1 /* 2 * schemas.c : implementation of the XML Schema handling and 3 * schema validity checking 4 * 5 * See Copyright for the status of this software. 6 * 7 * Daniel Veillard <veillard (at) redhat.com> 8 */ 9 10 /* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - if we don't intend to use the schema for schemas, we 16 * need to validate all schema attributes (ref, type, name) 17 * against their types. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 #define IN_LIBXML 48 #include "libxml.h" 49 50 #ifdef LIBXML_SCHEMAS_ENABLED 51 52 #include <string.h> 53 #include <libxml/xmlmemory.h> 54 #include <libxml/parser.h> 55 #include <libxml/parserInternals.h> 56 #include <libxml/hash.h> 57 #include <libxml/uri.h> 58 #include <libxml/xmlschemas.h> 59 #include <libxml/schemasInternals.h> 60 #include <libxml/xmlschemastypes.h> 61 #include <libxml/xmlautomata.h> 62 #include <libxml/xmlregexp.h> 63 #include <libxml/dict.h> 64 #include <libxml/encoding.h> 65 #include <libxml/xmlIO.h> 66 #ifdef LIBXML_PATTERN_ENABLED 67 #include <libxml/pattern.h> 68 #endif 69 #ifdef LIBXML_READER_ENABLED 70 #include <libxml/xmlreader.h> 71 #endif 72 73 /* #define DEBUG 1 */ 74 75 /* #define DEBUG_CONTENT 1 */ 76 77 /* #define DEBUG_TYPE 1 */ 78 79 /* #define DEBUG_CONTENT_REGEXP 1 */ 80 81 /* #define DEBUG_AUTOMATA 1 */ 82 83 /* #define DEBUG_IDC */ 84 85 /* #define DEBUG_IDC_NODE_TABLE */ 86 87 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 88 89 #ifdef DEBUG_IDC 90 #ifndef DEBUG_IDC_NODE_TABLE 91 #define DEBUG_IDC_NODE_TABLE 92 #endif 93 #endif 94 95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 96 97 #define ENABLE_REDEFINE 98 99 /* #define ENABLE_NAMED_LOCALS */ 100 101 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 102 103 #define DUMP_CONTENT_MODEL 104 105 #ifdef LIBXML_READER_ENABLED 106 /* #define XML_SCHEMA_READER_ENABLED */ 107 #endif 108 109 #define UNBOUNDED (1 << 30) 110 #define TODO \ 111 xmlGenericError(xmlGenericErrorContext, \ 112 "Unimplemented block at %s:%d\n", \ 113 __FILE__, __LINE__); 114 115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 116 117 /* 118 * The XML Schemas namespaces 119 */ 120 static const xmlChar *xmlSchemaNs = (const xmlChar *) 121 "http://www.w3.org/2001/XMLSchema"; 122 123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 124 "http://www.w3.org/2001/XMLSchema-instance"; 125 126 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 127 "http://www.w3.org/2000/xmlns/"; 128 129 /* 130 * Come casting macros. 131 */ 132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 137 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 138 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 139 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 146 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 148 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 149 150 /* 151 * Macros to query common properties of components. 152 */ 153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 154 155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 156 /* 157 * Macros for element declarations. 158 */ 159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 160 161 #define WXS_SUBST_HEAD(item) (item)->refDecl 162 /* 163 * Macros for attribute declarations. 164 */ 165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 166 /* 167 * Macros for attribute uses. 168 */ 169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 170 171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 172 173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 174 175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 176 /* 177 * Macros for attribute groups. 178 */ 179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 181 /* 182 * Macros for particles. 183 */ 184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 185 186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 187 188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 189 190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 191 /* 192 * Macros for model groups definitions. 193 */ 194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 195 /* 196 * Macros for model groups. 197 */ 198 #define WXS_IS_MODEL_GROUP(i) \ 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 202 203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 204 /* 205 * Macros for schema buckets. 206 */ 207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 209 210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 212 213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 214 215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 216 /* 217 * Macros for complex/simple types. 218 */ 219 #define WXS_IS_ANYTYPE(i) \ 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 222 223 #define WXS_IS_COMPLEX(i) \ 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 226 227 #define WXS_IS_SIMPLE(item) \ 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 231 232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 235 236 #define WXS_IS_RESTRICTION(t) \ 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 238 239 #define WXS_IS_EXTENSION(t) \ 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 241 242 #define WXS_IS_TYPE_NOT_FIXED(i) \ 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 245 246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 249 250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 251 252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 253 /* 254 * Macros for exclusively for complex types. 255 */ 256 #define WXS_HAS_COMPLEX_CONTENT(item) \ 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 260 261 #define WXS_HAS_SIMPLE_CONTENT(item) \ 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 264 265 #define WXS_HAS_MIXED_CONTENT(item) \ 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 267 268 #define WXS_EMPTIABLE(t) \ 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 270 271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 272 273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 274 275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 276 /* 277 * Macros for exclusively for simple types. 278 */ 279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 280 281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 282 283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 284 285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 286 /* 287 * Misc parser context macros. 288 */ 289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 290 291 #define WXS_HAS_BUCKETS(ctx) \ 292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 294 295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 296 297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 298 299 #define WXS_SCHEMA(ctx) (ctx)->schema 300 301 #define WXS_ADD_LOCAL(ctx, item) \ 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 303 304 #define WXS_ADD_GLOBAL(ctx, item) \ 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 306 307 #define WXS_ADD_PENDING(ctx, item) \ 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 309 /* 310 * xmlSchemaItemList macros. 311 */ 312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 313 /* 314 * Misc macros. 315 */ 316 #define IS_SCHEMA(node, type) \ 317 ((node != NULL) && (node->ns != NULL) && \ 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 320 321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 322 323 /* 324 * Since we put the default/fixed values into the dict, we can 325 * use pointer comparison for those values. 326 * REMOVED: (xmlStrEqual((v1), (v2))) 327 */ 328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 329 330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 331 332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 333 334 #define HFAILURE if (res == -1) goto exit_failure; 335 336 #define HERROR if (res != 0) goto exit_error; 337 338 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 339 /* 340 * Some flags used for various schema constraints. 341 */ 342 #define SUBSET_RESTRICTION 1<<0 343 #define SUBSET_EXTENSION 1<<1 344 #define SUBSET_SUBSTITUTION 1<<2 345 #define SUBSET_LIST 1<<3 346 #define SUBSET_UNION 1<<4 347 348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 350 351 typedef struct _xmlSchemaItemList xmlSchemaItemList; 352 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 353 struct _xmlSchemaItemList { 354 void **items; /* used for dynamic addition of schemata */ 355 int nbItems; /* used for dynamic addition of schemata */ 356 int sizeItems; /* used for dynamic addition of schemata */ 357 }; 358 359 #define XML_SCHEMA_CTXT_PARSER 1 360 #define XML_SCHEMA_CTXT_VALIDATOR 2 361 362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 364 struct _xmlSchemaAbstractCtxt { 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 366 }; 367 368 typedef struct _xmlSchemaBucket xmlSchemaBucket; 369 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 370 371 #define XML_SCHEMA_SCHEMA_MAIN 0 372 #define XML_SCHEMA_SCHEMA_IMPORT 1 373 #define XML_SCHEMA_SCHEMA_INCLUDE 2 374 #define XML_SCHEMA_SCHEMA_REDEFINE 3 375 376 /** 377 * xmlSchemaSchemaRelation: 378 * 379 * Used to create a graph of schema relationships. 380 */ 381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 383 struct _xmlSchemaSchemaRelation { 384 xmlSchemaSchemaRelationPtr next; 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 386 const xmlChar *importNamespace; 387 xmlSchemaBucketPtr bucket; 388 }; 389 390 #define XML_SCHEMA_BUCKET_MARKED 1<<0 391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 392 393 struct _xmlSchemaBucket { 394 int type; 395 int flags; 396 const xmlChar *schemaLocation; 397 const xmlChar *origTargetNamespace; 398 const xmlChar *targetNamespace; 399 xmlDocPtr doc; 400 xmlSchemaSchemaRelationPtr relations; 401 int located; 402 int parsed; 403 int imported; 404 int preserveDoc; 405 xmlSchemaItemListPtr globals; /* Global components. */ 406 xmlSchemaItemListPtr locals; /* Local components. */ 407 }; 408 409 /** 410 * xmlSchemaImport: 411 * (extends xmlSchemaBucket) 412 * 413 * Reflects a schema. Holds some information 414 * about the schema and its toplevel components. Duplicate 415 * toplevel components are not checked at this level. 416 */ 417 typedef struct _xmlSchemaImport xmlSchemaImport; 418 typedef xmlSchemaImport *xmlSchemaImportPtr; 419 struct _xmlSchemaImport { 420 int type; /* Main OR import OR include. */ 421 int flags; 422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 423 /* For chameleon includes, @origTargetNamespace will be NULL */ 424 const xmlChar *origTargetNamespace; 425 /* 426 * For chameleon includes, @targetNamespace will be the 427 * targetNamespace of the including schema. 428 */ 429 const xmlChar *targetNamespace; 430 xmlDocPtr doc; /* The schema node-tree. */ 431 /* @relations will hold any included/imported/redefined schemas. */ 432 xmlSchemaSchemaRelationPtr relations; 433 int located; 434 int parsed; 435 int imported; 436 int preserveDoc; 437 xmlSchemaItemListPtr globals; 438 xmlSchemaItemListPtr locals; 439 /* The imported schema. */ 440 xmlSchemaPtr schema; 441 }; 442 443 /* 444 * (extends xmlSchemaBucket) 445 */ 446 typedef struct _xmlSchemaInclude xmlSchemaInclude; 447 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 448 struct _xmlSchemaInclude { 449 int type; 450 int flags; 451 const xmlChar *schemaLocation; 452 const xmlChar *origTargetNamespace; 453 const xmlChar *targetNamespace; 454 xmlDocPtr doc; 455 xmlSchemaSchemaRelationPtr relations; 456 int located; 457 int parsed; 458 int imported; 459 int preserveDoc; 460 xmlSchemaItemListPtr globals; /* Global components. */ 461 xmlSchemaItemListPtr locals; /* Local components. */ 462 463 /* The owning main or import schema bucket. */ 464 xmlSchemaImportPtr ownerImport; 465 }; 466 467 /** 468 * xmlSchemaBasicItem: 469 * 470 * The abstract base type for schema components. 471 */ 472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 474 struct _xmlSchemaBasicItem { 475 xmlSchemaTypeType type; 476 }; 477 478 /** 479 * xmlSchemaAnnotItem: 480 * 481 * The abstract base type for annotated schema components. 482 * (Extends xmlSchemaBasicItem) 483 */ 484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 486 struct _xmlSchemaAnnotItem { 487 xmlSchemaTypeType type; 488 xmlSchemaAnnotPtr annot; 489 }; 490 491 /** 492 * xmlSchemaTreeItem: 493 * 494 * The abstract base type for tree-like structured schema components. 495 * (Extends xmlSchemaAnnotItem) 496 */ 497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 499 struct _xmlSchemaTreeItem { 500 xmlSchemaTypeType type; 501 xmlSchemaAnnotPtr annot; 502 xmlSchemaTreeItemPtr next; 503 xmlSchemaTreeItemPtr children; 504 }; 505 506 507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 508 /** 509 * xmlSchemaAttributeUsePtr: 510 * 511 * The abstract base type for tree-like structured schema components. 512 * (Extends xmlSchemaTreeItem) 513 */ 514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 516 struct _xmlSchemaAttributeUse { 517 xmlSchemaTypeType type; 518 xmlSchemaAnnotPtr annot; 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 520 /* 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 522 * a QName-ref. to an attribute group definition. 523 */ 524 xmlSchemaAttributePtr attrDecl; 525 526 int flags; 527 xmlNodePtr node; 528 int occurs; /* required, optional */ 529 const xmlChar * defValue; 530 xmlSchemaValPtr defVal; 531 }; 532 533 /** 534 * xmlSchemaAttributeUseProhibPtr: 535 * 536 * A helper component to reflect attribute prohibitions. 537 * (Extends xmlSchemaBasicItem) 538 */ 539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 541 struct _xmlSchemaAttributeUseProhib { 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 543 xmlNodePtr node; 544 const xmlChar *name; 545 const xmlChar *targetNamespace; 546 int isRef; 547 }; 548 549 /** 550 * xmlSchemaRedef: 551 */ 552 typedef struct _xmlSchemaRedef xmlSchemaRedef; 553 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 554 struct _xmlSchemaRedef { 555 xmlSchemaRedefPtr next; 556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 560 const xmlChar *refTargetNs; /* The target namespace of the 561 to-be-redefined comp. */ 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 563 }; 564 565 /** 566 * xmlSchemaConstructionCtxt: 567 */ 568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 570 struct _xmlSchemaConstructionCtxt { 571 xmlSchemaPtr mainSchema; /* The main schema. */ 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 573 xmlDictPtr dict; 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 578 need to be fixed. */ 579 xmlHashTablePtr substGroups; 580 xmlSchemaRedefPtr redefs; 581 xmlSchemaRedefPtr lastRedef; 582 }; 583 584 #define XML_SCHEMAS_PARSE_ERROR 1 585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 586 587 struct _xmlSchemaParserCtxt { 588 int type; 589 void *errCtxt; /* user specific error context */ 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 592 int err; 593 int nberrors; 594 xmlStructuredErrorFunc serror; 595 596 xmlSchemaConstructionCtxtPtr constructor; 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 598 599 /* xmlSchemaPtr topschema; */ 600 /* xmlHashTablePtr namespaces; */ 601 602 xmlSchemaPtr schema; /* The main schema in use */ 603 int counter; 604 605 const xmlChar *URL; 606 xmlDocPtr doc; 607 int preserve; /* Whether the doc should be freed */ 608 609 const char *buffer; 610 int size; 611 612 /* 613 * Used to build complex element content models 614 */ 615 xmlAutomataPtr am; 616 xmlAutomataStatePtr start; 617 xmlAutomataStatePtr end; 618 xmlAutomataStatePtr state; 619 620 xmlDictPtr dict; /* dictionnary for interned string names */ 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 622 int options; 623 xmlSchemaValidCtxtPtr vctxt; 624 int isS4S; 625 int isRedefine; 626 int xsiAssemble; 627 int stop; /* If the parser should stop; i.e. a critical error. */ 628 const xmlChar *targetNamespace; 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 630 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 632 int redefCounter; /* Used for redefinitions. */ 633 xmlSchemaItemListPtr attrProhibs; 634 }; 635 636 /** 637 * xmlSchemaQNameRef: 638 * 639 * A component reference item (not a schema component) 640 * (Extends xmlSchemaBasicItem) 641 */ 642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 644 struct _xmlSchemaQNameRef { 645 xmlSchemaTypeType type; 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 647 xmlSchemaTypeType itemType; 648 const xmlChar *name; 649 const xmlChar *targetNamespace; 650 xmlNodePtr node; 651 }; 652 653 /** 654 * xmlSchemaParticle: 655 * 656 * A particle component. 657 * (Extends xmlSchemaTreeItem) 658 */ 659 typedef struct _xmlSchemaParticle xmlSchemaParticle; 660 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 661 struct _xmlSchemaParticle { 662 xmlSchemaTypeType type; 663 xmlSchemaAnnotPtr annot; 664 xmlSchemaTreeItemPtr next; /* next particle */ 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 667 etc.) */ 668 int minOccurs; 669 int maxOccurs; 670 xmlNodePtr node; 671 }; 672 673 /** 674 * xmlSchemaModelGroup: 675 * 676 * A model group component. 677 * (Extends xmlSchemaTreeItem) 678 */ 679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 681 struct _xmlSchemaModelGroup { 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 683 xmlSchemaAnnotPtr annot; 684 xmlSchemaTreeItemPtr next; /* not used */ 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 686 xmlNodePtr node; 687 }; 688 689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 691 /** 692 * xmlSchemaModelGroupDef: 693 * 694 * A model group definition component. 695 * (Extends xmlSchemaTreeItem) 696 */ 697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 699 struct _xmlSchemaModelGroupDef { 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 701 xmlSchemaAnnotPtr annot; 702 xmlSchemaTreeItemPtr next; /* not used */ 703 xmlSchemaTreeItemPtr children; /* the "model group" */ 704 const xmlChar *name; 705 const xmlChar *targetNamespace; 706 xmlNodePtr node; 707 int flags; 708 }; 709 710 typedef struct _xmlSchemaIDC xmlSchemaIDC; 711 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 712 713 /** 714 * xmlSchemaIDCSelect: 715 * 716 * The identity-constraint "field" and "selector" item, holding the 717 * XPath expression. 718 */ 719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 721 struct _xmlSchemaIDCSelect { 722 xmlSchemaIDCSelectPtr next; 723 xmlSchemaIDCPtr idc; 724 int index; /* an index position if significant for IDC key-sequences */ 725 const xmlChar *xpath; /* the XPath expression */ 726 void *xpathComp; /* the compiled XPath expression */ 727 }; 728 729 /** 730 * xmlSchemaIDC: 731 * 732 * The identity-constraint definition component. 733 * (Extends xmlSchemaAnnotItem) 734 */ 735 736 struct _xmlSchemaIDC { 737 xmlSchemaTypeType type; 738 xmlSchemaAnnotPtr annot; 739 xmlSchemaIDCPtr next; 740 xmlNodePtr node; 741 const xmlChar *name; 742 const xmlChar *targetNamespace; 743 xmlSchemaIDCSelectPtr selector; 744 xmlSchemaIDCSelectPtr fields; 745 int nbFields; 746 xmlSchemaQNameRefPtr ref; 747 }; 748 749 /** 750 * xmlSchemaIDCAug: 751 * 752 * The augmented IDC information used for validation. 753 */ 754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 756 struct _xmlSchemaIDCAug { 757 xmlSchemaIDCAugPtr next; /* next in a list */ 758 xmlSchemaIDCPtr def; /* the IDC definition */ 759 int keyrefDepth; /* the lowest tree level to which IDC 760 tables need to be bubbled upwards */ 761 }; 762 763 /** 764 * xmlSchemaPSVIIDCKeySequence: 765 * 766 * The key sequence of a node table item. 767 */ 768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 770 struct _xmlSchemaPSVIIDCKey { 771 xmlSchemaTypePtr type; 772 xmlSchemaValPtr val; 773 }; 774 775 /** 776 * xmlSchemaPSVIIDCNode: 777 * 778 * The node table item of a node table. 779 */ 780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 782 struct _xmlSchemaPSVIIDCNode { 783 xmlNodePtr node; 784 xmlSchemaPSVIIDCKeyPtr *keys; 785 int nodeLine; 786 int nodeQNameID; 787 788 }; 789 790 /** 791 * xmlSchemaPSVIIDCBinding: 792 * 793 * The identity-constraint binding item of the [identity-constraint table]. 794 */ 795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 797 struct _xmlSchemaPSVIIDCBinding { 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 799 xmlSchemaIDCPtr definition; /* the IDC definition */ 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 801 int nbNodes; /* number of entries in the node table */ 802 int sizeNodes; /* size of the node table */ 803 xmlSchemaItemListPtr dupls; 804 }; 805 806 807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 809 810 #define XPATH_STATE_OBJ_MATCHES -2 811 #define XPATH_STATE_OBJ_BLOCKED -3 812 813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 815 816 /** 817 * xmlSchemaIDCStateObj: 818 * 819 * The state object used to evaluate XPath expressions. 820 */ 821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 823 struct _xmlSchemaIDCStateObj { 824 int type; 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 826 int depth; /* depth of creation */ 827 int *history; /* list of (depth, state-id) tuples */ 828 int nbHistory; 829 int sizeHistory; 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 831 matcher */ 832 xmlSchemaIDCSelectPtr sel; 833 void *xpathCtxt; 834 }; 835 836 #define IDC_MATCHER 0 837 838 /** 839 * xmlSchemaIDCMatcher: 840 * 841 * Used to evaluate IDC selectors (and fields). 842 */ 843 struct _xmlSchemaIDCMatcher { 844 int type; 845 int depth; /* the tree depth at creation time */ 846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 849 int idcType; 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 851 elements */ 852 int sizeKeySeqs; 853 xmlSchemaItemListPtr targets; /* list of target-node 854 (xmlSchemaPSVIIDCNodePtr) entries */ 855 }; 856 857 /* 858 * Element info flags. 859 */ 860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 864 865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 868 869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 873 874 /** 875 * xmlSchemaNodeInfo: 876 * 877 * Holds information of an element node. 878 */ 879 struct _xmlSchemaNodeInfo { 880 int nodeType; 881 xmlNodePtr node; 882 int nodeLine; 883 const xmlChar *localName; 884 const xmlChar *nsName; 885 const xmlChar *value; 886 xmlSchemaValPtr val; /* the pre-computed value if any */ 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 888 889 int flags; /* combination of node info flags */ 890 891 int valNeeded; 892 int normVal; 893 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 895 int depth; 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 897 for the scope element*/ 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 899 element */ 900 xmlRegExecCtxtPtr regexCtxt; 901 902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 903 int nbNsBindings; 904 int sizeNsBindings; 905 906 int hasKeyrefs; 907 int appliedXPath; /* Indicates that an XPath has been applied. */ 908 }; 909 910 #define XML_SCHEMAS_ATTR_UNKNOWN 1 911 #define XML_SCHEMAS_ATTR_ASSESSED 2 912 #define XML_SCHEMAS_ATTR_PROHIBITED 3 913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 917 #define XML_SCHEMAS_ATTR_DEFAULT 8 918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 926 #define XML_SCHEMAS_ATTR_META 17 927 /* 928 * @metaType values of xmlSchemaAttrInfo. 929 */ 930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 935 936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 938 struct _xmlSchemaAttrInfo { 939 int nodeType; 940 xmlNodePtr node; 941 int nodeLine; 942 const xmlChar *localName; 943 const xmlChar *nsName; 944 const xmlChar *value; 945 xmlSchemaValPtr val; /* the pre-computed value if any */ 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 947 int flags; /* combination of node info flags */ 948 949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 951 int state; 952 int metaType; 953 const xmlChar *vcValue; /* the value constraint value */ 954 xmlSchemaNodeInfoPtr parent; 955 }; 956 957 958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 959 /** 960 * xmlSchemaValidCtxt: 961 * 962 * A Schemas validation context 963 */ 964 struct _xmlSchemaValidCtxt { 965 int type; 966 void *errCtxt; /* user specific data block */ 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 969 xmlStructuredErrorFunc serror; 970 971 xmlSchemaPtr schema; /* The schema in use */ 972 xmlDocPtr doc; 973 xmlParserInputBufferPtr input; 974 xmlCharEncoding enc; 975 xmlSAXHandlerPtr sax; 976 xmlParserCtxtPtr parserCtxt; 977 void *user_data; /* TODO: What is this for? */ 978 979 int err; 980 int nberrors; 981 982 xmlNodePtr node; 983 xmlNodePtr cur; 984 /* xmlSchemaTypePtr type; */ 985 986 xmlRegExecCtxtPtr regexp; 987 xmlSchemaValPtr value; 988 989 int valueWS; 990 int options; 991 xmlNodePtr validationRoot; 992 xmlSchemaParserCtxtPtr pctxt; 993 int xsiAssemble; 994 995 int depth; 996 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 997 int sizeElemInfos; 998 xmlSchemaNodeInfoPtr inode; /* the current element information */ 999 1000 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1001 1002 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1003 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1004 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1005 1006 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1007 int nbIdcNodes; 1008 int sizeIdcNodes; 1009 1010 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1011 int nbIdcKeys; 1012 int sizeIdcKeys; 1013 1014 int flags; 1015 1016 xmlDictPtr dict; 1017 1018 #ifdef LIBXML_READER_ENABLED 1019 xmlTextReaderPtr reader; 1020 #endif 1021 1022 xmlSchemaAttrInfoPtr *attrInfos; 1023 int nbAttrInfos; 1024 int sizeAttrInfos; 1025 1026 int skipDepth; 1027 xmlSchemaItemListPtr nodeQNames; 1028 int hasKeyrefs; 1029 int createIDCNodeTables; 1030 int psviExposeIDCNodeTables; 1031 }; 1032 1033 /** 1034 * xmlSchemaSubstGroup: 1035 * 1036 * 1037 */ 1038 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1039 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1040 struct _xmlSchemaSubstGroup { 1041 xmlSchemaElementPtr head; 1042 xmlSchemaItemListPtr members; 1043 }; 1044 1045 /************************************************************************ 1046 * * 1047 * Some predeclarations * 1048 * * 1049 ************************************************************************/ 1050 1051 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1052 xmlSchemaPtr schema, 1053 xmlNodePtr node); 1054 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1055 xmlSchemaPtr schema, 1056 xmlNodePtr node); 1057 static int 1058 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1059 xmlSchemaAbstractCtxtPtr ctxt); 1060 static const xmlChar * 1061 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1062 static int 1063 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1064 xmlNodePtr node); 1065 static int 1066 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1067 xmlSchemaParserCtxtPtr ctxt); 1068 static void 1069 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1070 static xmlSchemaWhitespaceValueType 1071 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1072 static xmlSchemaTreeItemPtr 1073 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1074 xmlNodePtr node, xmlSchemaTypeType type, 1075 int withParticle); 1076 static const xmlChar * 1077 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1078 static xmlSchemaTypeLinkPtr 1079 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1080 static void 1081 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1082 const char *funcName, 1083 const char *message); 1084 static int 1085 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1086 xmlSchemaTypePtr type, 1087 xmlSchemaTypePtr baseType, 1088 int subset); 1089 static void 1090 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1091 xmlSchemaParserCtxtPtr ctxt); 1092 static void 1093 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1094 static xmlSchemaQNameRefPtr 1095 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1096 xmlSchemaPtr schema, 1097 xmlNodePtr node); 1098 1099 /************************************************************************ 1100 * * 1101 * Helper functions * 1102 * * 1103 ************************************************************************/ 1104 1105 /** 1106 * xmlSchemaItemTypeToStr: 1107 * @type: the type of the schema item 1108 * 1109 * Returns the component name of a schema item. 1110 */ 1111 static const xmlChar * 1112 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1113 { 1114 switch (type) { 1115 case XML_SCHEMA_TYPE_BASIC: 1116 return(BAD_CAST "simple type definition"); 1117 case XML_SCHEMA_TYPE_SIMPLE: 1118 return(BAD_CAST "simple type definition"); 1119 case XML_SCHEMA_TYPE_COMPLEX: 1120 return(BAD_CAST "complex type definition"); 1121 case XML_SCHEMA_TYPE_ELEMENT: 1122 return(BAD_CAST "element declaration"); 1123 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1124 return(BAD_CAST "attribute use"); 1125 case XML_SCHEMA_TYPE_ATTRIBUTE: 1126 return(BAD_CAST "attribute declaration"); 1127 case XML_SCHEMA_TYPE_GROUP: 1128 return(BAD_CAST "model group definition"); 1129 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1130 return(BAD_CAST "attribute group definition"); 1131 case XML_SCHEMA_TYPE_NOTATION: 1132 return(BAD_CAST "notation declaration"); 1133 case XML_SCHEMA_TYPE_SEQUENCE: 1134 return(BAD_CAST "model group (sequence)"); 1135 case XML_SCHEMA_TYPE_CHOICE: 1136 return(BAD_CAST "model group (choice)"); 1137 case XML_SCHEMA_TYPE_ALL: 1138 return(BAD_CAST "model group (all)"); 1139 case XML_SCHEMA_TYPE_PARTICLE: 1140 return(BAD_CAST "particle"); 1141 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1142 return(BAD_CAST "unique identity-constraint"); 1143 /* return(BAD_CAST "IDC (unique)"); */ 1144 case XML_SCHEMA_TYPE_IDC_KEY: 1145 return(BAD_CAST "key identity-constraint"); 1146 /* return(BAD_CAST "IDC (key)"); */ 1147 case XML_SCHEMA_TYPE_IDC_KEYREF: 1148 return(BAD_CAST "keyref identity-constraint"); 1149 /* return(BAD_CAST "IDC (keyref)"); */ 1150 case XML_SCHEMA_TYPE_ANY: 1151 return(BAD_CAST "wildcard (any)"); 1152 case XML_SCHEMA_EXTRA_QNAMEREF: 1153 return(BAD_CAST "[helper component] QName reference"); 1154 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1155 return(BAD_CAST "[helper component] attribute use prohibition"); 1156 default: 1157 return(BAD_CAST "Not a schema component"); 1158 } 1159 } 1160 1161 /** 1162 * xmlSchemaGetComponentTypeStr: 1163 * @type: the type of the schema item 1164 * 1165 * Returns the component name of a schema item. 1166 */ 1167 static const xmlChar * 1168 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1169 { 1170 switch (item->type) { 1171 case XML_SCHEMA_TYPE_BASIC: 1172 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1173 return(BAD_CAST "complex type definition"); 1174 else 1175 return(BAD_CAST "simple type definition"); 1176 default: 1177 return(xmlSchemaItemTypeToStr(item->type)); 1178 } 1179 } 1180 1181 /** 1182 * xmlSchemaGetComponentNode: 1183 * @item: a schema component 1184 * 1185 * Returns node associated with the schema component. 1186 * NOTE that such a node need not be available; plus, a component's 1187 * node need not to reflect the component directly, since there is no 1188 * one-to-one relationship between the XML Schema representation and 1189 * the component representation. 1190 */ 1191 static xmlNodePtr 1192 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1193 { 1194 switch (item->type) { 1195 case XML_SCHEMA_TYPE_ELEMENT: 1196 return (((xmlSchemaElementPtr) item)->node); 1197 case XML_SCHEMA_TYPE_ATTRIBUTE: 1198 return (((xmlSchemaAttributePtr) item)->node); 1199 case XML_SCHEMA_TYPE_COMPLEX: 1200 case XML_SCHEMA_TYPE_SIMPLE: 1201 return (((xmlSchemaTypePtr) item)->node); 1202 case XML_SCHEMA_TYPE_ANY: 1203 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1204 return (((xmlSchemaWildcardPtr) item)->node); 1205 case XML_SCHEMA_TYPE_PARTICLE: 1206 return (((xmlSchemaParticlePtr) item)->node); 1207 case XML_SCHEMA_TYPE_SEQUENCE: 1208 case XML_SCHEMA_TYPE_CHOICE: 1209 case XML_SCHEMA_TYPE_ALL: 1210 return (((xmlSchemaModelGroupPtr) item)->node); 1211 case XML_SCHEMA_TYPE_GROUP: 1212 return (((xmlSchemaModelGroupDefPtr) item)->node); 1213 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1214 return (((xmlSchemaAttributeGroupPtr) item)->node); 1215 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1216 case XML_SCHEMA_TYPE_IDC_KEY: 1217 case XML_SCHEMA_TYPE_IDC_KEYREF: 1218 return (((xmlSchemaIDCPtr) item)->node); 1219 case XML_SCHEMA_EXTRA_QNAMEREF: 1220 return(((xmlSchemaQNameRefPtr) item)->node); 1221 /* TODO: What to do with NOTATIONs? 1222 case XML_SCHEMA_TYPE_NOTATION: 1223 return (((xmlSchemaNotationPtr) item)->node); 1224 */ 1225 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1226 return (((xmlSchemaAttributeUsePtr) item)->node); 1227 default: 1228 return (NULL); 1229 } 1230 } 1231 1232 #if 0 1233 /** 1234 * xmlSchemaGetNextComponent: 1235 * @item: a schema component 1236 * 1237 * Returns the next sibling of the schema component. 1238 */ 1239 static xmlSchemaBasicItemPtr 1240 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1241 { 1242 switch (item->type) { 1243 case XML_SCHEMA_TYPE_ELEMENT: 1244 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1245 case XML_SCHEMA_TYPE_ATTRIBUTE: 1246 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1247 case XML_SCHEMA_TYPE_COMPLEX: 1248 case XML_SCHEMA_TYPE_SIMPLE: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1250 case XML_SCHEMA_TYPE_ANY: 1251 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1252 return (NULL); 1253 case XML_SCHEMA_TYPE_PARTICLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1255 case XML_SCHEMA_TYPE_SEQUENCE: 1256 case XML_SCHEMA_TYPE_CHOICE: 1257 case XML_SCHEMA_TYPE_ALL: 1258 return (NULL); 1259 case XML_SCHEMA_TYPE_GROUP: 1260 return (NULL); 1261 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1263 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1264 case XML_SCHEMA_TYPE_IDC_KEY: 1265 case XML_SCHEMA_TYPE_IDC_KEYREF: 1266 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1267 default: 1268 return (NULL); 1269 } 1270 } 1271 #endif 1272 1273 1274 /** 1275 * xmlSchemaFormatQName: 1276 * @buf: the string buffer 1277 * @namespaceName: the namespace name 1278 * @localName: the local name 1279 * 1280 * Returns the given QName in the format "{namespaceName}localName" or 1281 * just "localName" if @namespaceName is NULL. 1282 * 1283 * Returns the localName if @namespaceName is NULL, a formatted 1284 * string otherwise. 1285 */ 1286 static const xmlChar* 1287 xmlSchemaFormatQName(xmlChar **buf, 1288 const xmlChar *namespaceName, 1289 const xmlChar *localName) 1290 { 1291 FREE_AND_NULL(*buf) 1292 if (namespaceName != NULL) { 1293 *buf = xmlStrdup(BAD_CAST "{"); 1294 *buf = xmlStrcat(*buf, namespaceName); 1295 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1296 } 1297 if (localName != NULL) { 1298 if (namespaceName == NULL) 1299 return(localName); 1300 *buf = xmlStrcat(*buf, localName); 1301 } else { 1302 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1303 } 1304 return ((const xmlChar *) *buf); 1305 } 1306 1307 static const xmlChar* 1308 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1309 { 1310 if (ns != NULL) 1311 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1312 else 1313 return (xmlSchemaFormatQName(buf, NULL, localName)); 1314 } 1315 1316 static const xmlChar * 1317 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1318 { 1319 switch (item->type) { 1320 case XML_SCHEMA_TYPE_ELEMENT: 1321 return (((xmlSchemaElementPtr) item)->name); 1322 case XML_SCHEMA_TYPE_ATTRIBUTE: 1323 return (((xmlSchemaAttributePtr) item)->name); 1324 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1325 return (((xmlSchemaAttributeGroupPtr) item)->name); 1326 case XML_SCHEMA_TYPE_BASIC: 1327 case XML_SCHEMA_TYPE_SIMPLE: 1328 case XML_SCHEMA_TYPE_COMPLEX: 1329 return (((xmlSchemaTypePtr) item)->name); 1330 case XML_SCHEMA_TYPE_GROUP: 1331 return (((xmlSchemaModelGroupDefPtr) item)->name); 1332 case XML_SCHEMA_TYPE_IDC_KEY: 1333 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1334 case XML_SCHEMA_TYPE_IDC_KEYREF: 1335 return (((xmlSchemaIDCPtr) item)->name); 1336 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1337 if (WXS_ATTRUSE_DECL(item) != NULL) { 1338 return(xmlSchemaGetComponentName( 1339 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1340 } else 1341 return(NULL); 1342 case XML_SCHEMA_EXTRA_QNAMEREF: 1343 return (((xmlSchemaQNameRefPtr) item)->name); 1344 case XML_SCHEMA_TYPE_NOTATION: 1345 return (((xmlSchemaNotationPtr) item)->name); 1346 default: 1347 /* 1348 * Other components cannot have names. 1349 */ 1350 break; 1351 } 1352 return (NULL); 1353 } 1354 1355 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1356 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1357 /* 1358 static const xmlChar * 1359 xmlSchemaGetQNameRefName(void *ref) 1360 { 1361 return(((xmlSchemaQNameRefPtr) ref)->name); 1362 } 1363 1364 static const xmlChar * 1365 xmlSchemaGetQNameRefTargetNs(void *ref) 1366 { 1367 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1368 } 1369 */ 1370 1371 static const xmlChar * 1372 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1373 { 1374 switch (item->type) { 1375 case XML_SCHEMA_TYPE_ELEMENT: 1376 return (((xmlSchemaElementPtr) item)->targetNamespace); 1377 case XML_SCHEMA_TYPE_ATTRIBUTE: 1378 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1379 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1380 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1381 case XML_SCHEMA_TYPE_BASIC: 1382 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1383 case XML_SCHEMA_TYPE_SIMPLE: 1384 case XML_SCHEMA_TYPE_COMPLEX: 1385 return (((xmlSchemaTypePtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_GROUP: 1387 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1388 case XML_SCHEMA_TYPE_IDC_KEY: 1389 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1390 case XML_SCHEMA_TYPE_IDC_KEYREF: 1391 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1393 if (WXS_ATTRUSE_DECL(item) != NULL) { 1394 return(xmlSchemaGetComponentTargetNs( 1395 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1396 } 1397 /* TODO: Will returning NULL break something? */ 1398 break; 1399 case XML_SCHEMA_EXTRA_QNAMEREF: 1400 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_NOTATION: 1402 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1403 default: 1404 /* 1405 * Other components cannot have names. 1406 */ 1407 break; 1408 } 1409 return (NULL); 1410 } 1411 1412 static const xmlChar* 1413 xmlSchemaGetComponentQName(xmlChar **buf, 1414 void *item) 1415 { 1416 return (xmlSchemaFormatQName(buf, 1417 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1418 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1419 } 1420 1421 static const xmlChar* 1422 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1423 { 1424 xmlChar *str = NULL; 1425 1426 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1427 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1428 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1429 (xmlSchemaBasicItemPtr) item)); 1430 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1431 FREE_AND_NULL(str); 1432 return(*buf); 1433 } 1434 1435 static const xmlChar* 1436 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1437 { 1438 return(xmlSchemaGetComponentDesignation(buf, idc)); 1439 } 1440 1441 /** 1442 * xmlSchemaWildcardPCToString: 1443 * @pc: the type of processContents 1444 * 1445 * Returns a string representation of the type of 1446 * processContents. 1447 */ 1448 static const xmlChar * 1449 xmlSchemaWildcardPCToString(int pc) 1450 { 1451 switch (pc) { 1452 case XML_SCHEMAS_ANY_SKIP: 1453 return (BAD_CAST "skip"); 1454 case XML_SCHEMAS_ANY_LAX: 1455 return (BAD_CAST "lax"); 1456 case XML_SCHEMAS_ANY_STRICT: 1457 return (BAD_CAST "strict"); 1458 default: 1459 return (BAD_CAST "invalid process contents"); 1460 } 1461 } 1462 1463 /** 1464 * xmlSchemaGetCanonValueWhtspExt: 1465 * @val: the precomputed value 1466 * @retValue: the returned value 1467 * @ws: the whitespace type of the value 1468 * 1469 * Get a the cononical representation of the value. 1470 * The caller has to free the returned retValue. 1471 * 1472 * Returns 0 if the value could be built and -1 in case of 1473 * API errors or if the value type is not supported yet. 1474 */ 1475 static int 1476 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1477 xmlSchemaWhitespaceValueType ws, 1478 xmlChar **retValue) 1479 { 1480 int list; 1481 xmlSchemaValType valType; 1482 const xmlChar *value, *value2 = NULL; 1483 1484 1485 if ((retValue == NULL) || (val == NULL)) 1486 return (-1); 1487 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1488 *retValue = NULL; 1489 do { 1490 value = NULL; 1491 valType = xmlSchemaGetValType(val); 1492 switch (valType) { 1493 case XML_SCHEMAS_STRING: 1494 case XML_SCHEMAS_NORMSTRING: 1495 case XML_SCHEMAS_ANYSIMPLETYPE: 1496 value = xmlSchemaValueGetAsString(val); 1497 if (value != NULL) { 1498 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1499 value2 = xmlSchemaCollapseString(value); 1500 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1501 value2 = xmlSchemaWhiteSpaceReplace(value); 1502 if (value2 != NULL) 1503 value = value2; 1504 } 1505 break; 1506 default: 1507 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1508 if (value2 != NULL) 1509 xmlFree((xmlChar *) value2); 1510 goto internal_error; 1511 } 1512 value = value2; 1513 } 1514 if (*retValue == NULL) 1515 if (value == NULL) { 1516 if (! list) 1517 *retValue = xmlStrdup(BAD_CAST ""); 1518 } else 1519 *retValue = xmlStrdup(value); 1520 else if (value != NULL) { 1521 /* List. */ 1522 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1523 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1524 } 1525 FREE_AND_NULL(value2) 1526 val = xmlSchemaValueGetNext(val); 1527 } while (val != NULL); 1528 1529 return (0); 1530 internal_error: 1531 if (*retValue != NULL) 1532 xmlFree((xmlChar *) (*retValue)); 1533 if (value2 != NULL) 1534 xmlFree((xmlChar *) value2); 1535 return (-1); 1536 } 1537 1538 /** 1539 * xmlSchemaFormatItemForReport: 1540 * @buf: the string buffer 1541 * @itemDes: the designation of the item 1542 * @itemName: the name of the item 1543 * @item: the item as an object 1544 * @itemNode: the node of the item 1545 * @local: the local name 1546 * @parsing: if the function is used during the parse 1547 * 1548 * Returns a representation of the given item used 1549 * for error reports. 1550 * 1551 * The following order is used to build the resulting 1552 * designation if the arguments are not NULL: 1553 * 1a. If itemDes not NULL -> itemDes 1554 * 1b. If (itemDes not NULL) and (itemName not NULL) 1555 * -> itemDes + itemName 1556 * 2. If the preceding was NULL and (item not NULL) -> item 1557 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1558 * 1559 * If the itemNode is an attribute node, the name of the attribute 1560 * will be appended to the result. 1561 * 1562 * Returns the formatted string and sets @buf to the resulting value. 1563 */ 1564 static xmlChar* 1565 xmlSchemaFormatItemForReport(xmlChar **buf, 1566 const xmlChar *itemDes, 1567 xmlSchemaBasicItemPtr item, 1568 xmlNodePtr itemNode) 1569 { 1570 xmlChar *str = NULL; 1571 int named = 1; 1572 1573 if (*buf != NULL) { 1574 xmlFree(*buf); 1575 *buf = NULL; 1576 } 1577 1578 if (itemDes != NULL) { 1579 *buf = xmlStrdup(itemDes); 1580 } else if (item != NULL) { 1581 switch (item->type) { 1582 case XML_SCHEMA_TYPE_BASIC: { 1583 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1584 1585 if (WXS_IS_ATOMIC(type)) 1586 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1587 else if (WXS_IS_LIST(type)) 1588 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1589 else if (WXS_IS_UNION(type)) 1590 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1591 else 1592 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1593 *buf = xmlStrcat(*buf, type->name); 1594 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1595 } 1596 break; 1597 case XML_SCHEMA_TYPE_SIMPLE: { 1598 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1599 1600 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1601 *buf = xmlStrdup(BAD_CAST""); 1602 } else { 1603 *buf = xmlStrdup(BAD_CAST "local "); 1604 } 1605 if (WXS_IS_ATOMIC(type)) 1606 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1607 else if (WXS_IS_LIST(type)) 1608 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1609 else if (WXS_IS_UNION(type)) 1610 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1611 else 1612 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1615 *buf = xmlStrcat(*buf, type->name); 1616 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1617 } 1618 } 1619 break; 1620 case XML_SCHEMA_TYPE_COMPLEX: { 1621 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1622 1623 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1624 *buf = xmlStrdup(BAD_CAST ""); 1625 else 1626 *buf = xmlStrdup(BAD_CAST "local "); 1627 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1629 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1630 *buf = xmlStrcat(*buf, type->name); 1631 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1632 } 1633 } 1634 break; 1635 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1636 xmlSchemaAttributeUsePtr ause; 1637 1638 ause = WXS_ATTR_USE_CAST item; 1639 *buf = xmlStrdup(BAD_CAST "attribute use "); 1640 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1641 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1642 *buf = xmlStrcat(*buf, 1643 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1644 FREE_AND_NULL(str) 1645 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1646 } else { 1647 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1648 } 1649 } 1650 break; 1651 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1652 xmlSchemaAttributePtr attr; 1653 1654 attr = (xmlSchemaAttributePtr) item; 1655 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1656 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1657 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1658 attr->targetNamespace, attr->name)); 1659 FREE_AND_NULL(str) 1660 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1661 } 1662 break; 1663 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1664 xmlSchemaGetComponentDesignation(buf, item); 1665 break; 1666 case XML_SCHEMA_TYPE_ELEMENT: { 1667 xmlSchemaElementPtr elem; 1668 1669 elem = (xmlSchemaElementPtr) item; 1670 *buf = xmlStrdup(BAD_CAST "element decl."); 1671 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1672 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1673 elem->targetNamespace, elem->name)); 1674 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1675 } 1676 break; 1677 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1678 case XML_SCHEMA_TYPE_IDC_KEY: 1679 case XML_SCHEMA_TYPE_IDC_KEYREF: 1680 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1681 *buf = xmlStrdup(BAD_CAST "unique '"); 1682 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1683 *buf = xmlStrdup(BAD_CAST "key '"); 1684 else 1685 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1686 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 break; 1689 case XML_SCHEMA_TYPE_ANY: 1690 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1691 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1692 ((xmlSchemaWildcardPtr) item)->processContents)); 1693 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1694 break; 1695 case XML_SCHEMA_FACET_MININCLUSIVE: 1696 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1697 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1698 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1699 case XML_SCHEMA_FACET_TOTALDIGITS: 1700 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1701 case XML_SCHEMA_FACET_PATTERN: 1702 case XML_SCHEMA_FACET_ENUMERATION: 1703 case XML_SCHEMA_FACET_WHITESPACE: 1704 case XML_SCHEMA_FACET_LENGTH: 1705 case XML_SCHEMA_FACET_MAXLENGTH: 1706 case XML_SCHEMA_FACET_MINLENGTH: 1707 *buf = xmlStrdup(BAD_CAST "facet '"); 1708 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1709 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1710 break; 1711 case XML_SCHEMA_TYPE_GROUP: { 1712 *buf = xmlStrdup(BAD_CAST "model group def."); 1713 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1714 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1715 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1716 FREE_AND_NULL(str) 1717 } 1718 break; 1719 case XML_SCHEMA_TYPE_SEQUENCE: 1720 case XML_SCHEMA_TYPE_CHOICE: 1721 case XML_SCHEMA_TYPE_ALL: 1722 case XML_SCHEMA_TYPE_PARTICLE: 1723 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1724 break; 1725 case XML_SCHEMA_TYPE_NOTATION: { 1726 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1727 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1728 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1729 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1730 FREE_AND_NULL(str); 1731 } 1732 default: 1733 named = 0; 1734 } 1735 } else 1736 named = 0; 1737 1738 if ((named == 0) && (itemNode != NULL)) { 1739 xmlNodePtr elem; 1740 1741 if (itemNode->type == XML_ATTRIBUTE_NODE) 1742 elem = itemNode->parent; 1743 else 1744 elem = itemNode; 1745 *buf = xmlStrdup(BAD_CAST "Element '"); 1746 if (elem->ns != NULL) { 1747 *buf = xmlStrcat(*buf, 1748 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1749 FREE_AND_NULL(str) 1750 } else 1751 *buf = xmlStrcat(*buf, elem->name); 1752 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1753 1754 } 1755 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1756 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1757 if (itemNode->ns != NULL) { 1758 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1759 itemNode->ns->href, itemNode->name)); 1760 FREE_AND_NULL(str) 1761 } else 1762 *buf = xmlStrcat(*buf, itemNode->name); 1763 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1764 } 1765 FREE_AND_NULL(str) 1766 1767 return (*buf); 1768 } 1769 1770 /** 1771 * xmlSchemaFormatFacetEnumSet: 1772 * @buf: the string buffer 1773 * @type: the type holding the enumeration facets 1774 * 1775 * Builds a string consisting of all enumeration elements. 1776 * 1777 * Returns a string of all enumeration elements. 1778 */ 1779 static const xmlChar * 1780 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1781 xmlChar **buf, xmlSchemaTypePtr type) 1782 { 1783 xmlSchemaFacetPtr facet; 1784 xmlSchemaWhitespaceValueType ws; 1785 xmlChar *value = NULL; 1786 int res, found = 0; 1787 1788 if (*buf != NULL) 1789 xmlFree(*buf); 1790 *buf = NULL; 1791 1792 do { 1793 /* 1794 * Use the whitespace type of the base type. 1795 */ 1796 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1797 for (facet = type->facets; facet != NULL; facet = facet->next) { 1798 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1799 continue; 1800 found = 1; 1801 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1802 ws, &value); 1803 if (res == -1) { 1804 xmlSchemaInternalErr(actxt, 1805 "xmlSchemaFormatFacetEnumSet", 1806 "compute the canonical lexical representation"); 1807 if (*buf != NULL) 1808 xmlFree(*buf); 1809 *buf = NULL; 1810 return (NULL); 1811 } 1812 if (*buf == NULL) 1813 *buf = xmlStrdup(BAD_CAST "'"); 1814 else 1815 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1816 *buf = xmlStrcat(*buf, BAD_CAST value); 1817 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1818 if (value != NULL) { 1819 xmlFree((xmlChar *)value); 1820 value = NULL; 1821 } 1822 } 1823 /* 1824 * The enumeration facet of a type restricts the enumeration 1825 * facet of the ancestor type; i.e., such restricted enumerations 1826 * do not belong to the set of the given type. Thus we break 1827 * on the first found enumeration. 1828 */ 1829 if (found) 1830 break; 1831 type = type->baseType; 1832 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1833 1834 return ((const xmlChar *) *buf); 1835 } 1836 1837 /************************************************************************ 1838 * * 1839 * Error functions * 1840 * * 1841 ************************************************************************/ 1842 1843 #if 0 1844 static void 1845 xmlSchemaErrMemory(const char *msg) 1846 { 1847 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1848 msg); 1849 } 1850 #endif 1851 1852 static void 1853 xmlSchemaPSimpleErr(const char *msg) 1854 { 1855 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1856 msg); 1857 } 1858 1859 /** 1860 * xmlSchemaPErrMemory: 1861 * @node: a context node 1862 * @extra: extra informations 1863 * 1864 * Handle an out of memory condition 1865 */ 1866 static void 1867 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1868 const char *extra, xmlNodePtr node) 1869 { 1870 if (ctxt != NULL) 1871 ctxt->nberrors++; 1872 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1873 extra); 1874 } 1875 1876 /** 1877 * xmlSchemaPErr: 1878 * @ctxt: the parsing context 1879 * @node: the context node 1880 * @error: the error code 1881 * @msg: the error message 1882 * @str1: extra data 1883 * @str2: extra data 1884 * 1885 * Handle a parser error 1886 */ 1887 static void 1888 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1889 const char *msg, const xmlChar * str1, const xmlChar * str2) 1890 { 1891 xmlGenericErrorFunc channel = NULL; 1892 xmlStructuredErrorFunc schannel = NULL; 1893 void *data = NULL; 1894 1895 if (ctxt != NULL) { 1896 ctxt->nberrors++; 1897 ctxt->err = error; 1898 channel = ctxt->error; 1899 data = ctxt->errCtxt; 1900 schannel = ctxt->serror; 1901 } 1902 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1903 error, XML_ERR_ERROR, NULL, 0, 1904 (const char *) str1, (const char *) str2, NULL, 0, 0, 1905 msg, str1, str2); 1906 } 1907 1908 /** 1909 * xmlSchemaPErr2: 1910 * @ctxt: the parsing context 1911 * @node: the context node 1912 * @node: the current child 1913 * @error: the error code 1914 * @msg: the error message 1915 * @str1: extra data 1916 * @str2: extra data 1917 * 1918 * Handle a parser error 1919 */ 1920 static void 1921 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1922 xmlNodePtr child, int error, 1923 const char *msg, const xmlChar * str1, const xmlChar * str2) 1924 { 1925 if (child != NULL) 1926 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1927 else 1928 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1929 } 1930 1931 1932 /** 1933 * xmlSchemaPErrExt: 1934 * @ctxt: the parsing context 1935 * @node: the context node 1936 * @error: the error code 1937 * @strData1: extra data 1938 * @strData2: extra data 1939 * @strData3: extra data 1940 * @msg: the message 1941 * @str1: extra parameter for the message display 1942 * @str2: extra parameter for the message display 1943 * @str3: extra parameter for the message display 1944 * @str4: extra parameter for the message display 1945 * @str5: extra parameter for the message display 1946 * 1947 * Handle a parser error 1948 */ 1949 static void 1950 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1951 const xmlChar * strData1, const xmlChar * strData2, 1952 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1953 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1954 const xmlChar * str5) 1955 { 1956 1957 xmlGenericErrorFunc channel = NULL; 1958 xmlStructuredErrorFunc schannel = NULL; 1959 void *data = NULL; 1960 1961 if (ctxt != NULL) { 1962 ctxt->nberrors++; 1963 ctxt->err = error; 1964 channel = ctxt->error; 1965 data = ctxt->errCtxt; 1966 schannel = ctxt->serror; 1967 } 1968 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1969 error, XML_ERR_ERROR, NULL, 0, 1970 (const char *) strData1, (const char *) strData2, 1971 (const char *) strData3, 0, 0, msg, str1, str2, 1972 str3, str4, str5); 1973 } 1974 1975 /************************************************************************ 1976 * * 1977 * Allround error functions * 1978 * * 1979 ************************************************************************/ 1980 1981 /** 1982 * xmlSchemaVTypeErrMemory: 1983 * @node: a context node 1984 * @extra: extra informations 1985 * 1986 * Handle an out of memory condition 1987 */ 1988 static void 1989 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1990 const char *extra, xmlNodePtr node) 1991 { 1992 if (ctxt != NULL) { 1993 ctxt->nberrors++; 1994 ctxt->err = XML_SCHEMAV_INTERNAL; 1995 } 1996 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 1997 extra); 1998 } 1999 2000 static void 2001 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2002 const char *msg, const xmlChar *str) 2003 { 2004 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2005 msg, (const char *) str); 2006 } 2007 2008 #define WXS_ERROR_TYPE_ERROR 1 2009 #define WXS_ERROR_TYPE_WARNING 2 2010 /** 2011 * xmlSchemaErr3: 2012 * @ctxt: the validation context 2013 * @node: the context node 2014 * @error: the error code 2015 * @msg: the error message 2016 * @str1: extra data 2017 * @str2: extra data 2018 * @str3: extra data 2019 * 2020 * Handle a validation error 2021 */ 2022 static void 2023 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2024 xmlErrorLevel errorLevel, 2025 int error, xmlNodePtr node, int line, const char *msg, 2026 const xmlChar *str1, const xmlChar *str2, 2027 const xmlChar *str3, const xmlChar *str4) 2028 { 2029 xmlStructuredErrorFunc schannel = NULL; 2030 xmlGenericErrorFunc channel = NULL; 2031 void *data = NULL; 2032 2033 if (ctxt != NULL) { 2034 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2035 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2036 const char *file = NULL; 2037 if (errorLevel != XML_ERR_WARNING) { 2038 vctxt->nberrors++; 2039 vctxt->err = error; 2040 channel = vctxt->error; 2041 } else { 2042 channel = vctxt->warning; 2043 } 2044 schannel = vctxt->serror; 2045 data = vctxt->errCtxt; 2046 2047 /* 2048 * Error node. If we specify a line number, then 2049 * do not channel any node to the error function. 2050 */ 2051 if (line == 0) { 2052 if ((node == NULL) && 2053 (vctxt->depth >= 0) && 2054 (vctxt->inode != NULL)) { 2055 node = vctxt->inode->node; 2056 } 2057 /* 2058 * Get filename and line if no node-tree. 2059 */ 2060 if ((node == NULL) && 2061 (vctxt->parserCtxt != NULL) && 2062 (vctxt->parserCtxt->input != NULL)) { 2063 file = vctxt->parserCtxt->input->filename; 2064 line = vctxt->parserCtxt->input->line; 2065 } 2066 } else { 2067 /* 2068 * Override the given node's (if any) position 2069 * and channel only the given line number. 2070 */ 2071 node = NULL; 2072 /* 2073 * Get filename. 2074 */ 2075 if (vctxt->doc != NULL) 2076 file = (const char *) vctxt->doc->URL; 2077 else if ((vctxt->parserCtxt != NULL) && 2078 (vctxt->parserCtxt->input != NULL)) 2079 file = vctxt->parserCtxt->input->filename; 2080 } 2081 __xmlRaiseError(schannel, channel, data, ctxt, 2082 node, XML_FROM_SCHEMASV, 2083 error, errorLevel, file, line, 2084 (const char *) str1, (const char *) str2, 2085 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2086 2087 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2088 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2089 if (errorLevel != XML_ERR_WARNING) { 2090 pctxt->nberrors++; 2091 pctxt->err = error; 2092 channel = pctxt->error; 2093 } else { 2094 channel = pctxt->warning; 2095 } 2096 schannel = pctxt->serror; 2097 data = pctxt->errCtxt; 2098 __xmlRaiseError(schannel, channel, data, ctxt, 2099 node, XML_FROM_SCHEMASP, error, 2100 errorLevel, NULL, 0, 2101 (const char *) str1, (const char *) str2, 2102 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2103 } else { 2104 TODO 2105 } 2106 } 2107 } 2108 2109 /** 2110 * xmlSchemaErr3: 2111 * @ctxt: the validation context 2112 * @node: the context node 2113 * @error: the error code 2114 * @msg: the error message 2115 * @str1: extra data 2116 * @str2: extra data 2117 * @str3: extra data 2118 * 2119 * Handle a validation error 2120 */ 2121 static void 2122 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2123 int error, xmlNodePtr node, const char *msg, 2124 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2125 { 2126 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2127 msg, str1, str2, str3, NULL); 2128 } 2129 2130 static void 2131 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2132 int error, xmlNodePtr node, const char *msg, 2133 const xmlChar *str1, const xmlChar *str2, 2134 const xmlChar *str3, const xmlChar *str4) 2135 { 2136 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2137 msg, str1, str2, str3, str4); 2138 } 2139 2140 static void 2141 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2142 int error, xmlNodePtr node, const char *msg, 2143 const xmlChar *str1, const xmlChar *str2) 2144 { 2145 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2146 } 2147 2148 static xmlChar * 2149 xmlSchemaFormatNodeForError(xmlChar ** msg, 2150 xmlSchemaAbstractCtxtPtr actxt, 2151 xmlNodePtr node) 2152 { 2153 xmlChar *str = NULL; 2154 2155 *msg = NULL; 2156 if ((node != NULL) && 2157 (node->type != XML_ELEMENT_NODE) && 2158 (node->type != XML_ATTRIBUTE_NODE)) 2159 { 2160 /* 2161 * Don't try to format other nodes than element and 2162 * attribute nodes. 2163 * Play save and return an empty string. 2164 */ 2165 *msg = xmlStrdup(BAD_CAST ""); 2166 return(*msg); 2167 } 2168 if (node != NULL) { 2169 /* 2170 * Work on tree nodes. 2171 */ 2172 if (node->type == XML_ATTRIBUTE_NODE) { 2173 xmlNodePtr elem = node->parent; 2174 2175 *msg = xmlStrdup(BAD_CAST "Element '"); 2176 if (elem->ns != NULL) 2177 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2178 elem->ns->href, elem->name)); 2179 else 2180 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2181 NULL, elem->name)); 2182 FREE_AND_NULL(str); 2183 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2184 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2185 } else { 2186 *msg = xmlStrdup(BAD_CAST "Element '"); 2187 } 2188 if (node->ns != NULL) 2189 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2190 node->ns->href, node->name)); 2191 else 2192 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2193 NULL, node->name)); 2194 FREE_AND_NULL(str); 2195 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2196 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2197 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2198 /* 2199 * Work on node infos. 2200 */ 2201 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2202 xmlSchemaNodeInfoPtr ielem = 2203 vctxt->elemInfos[vctxt->depth]; 2204 2205 *msg = xmlStrdup(BAD_CAST "Element '"); 2206 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2207 ielem->nsName, ielem->localName)); 2208 FREE_AND_NULL(str); 2209 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2210 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2211 } else { 2212 *msg = xmlStrdup(BAD_CAST "Element '"); 2213 } 2214 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2215 vctxt->inode->nsName, vctxt->inode->localName)); 2216 FREE_AND_NULL(str); 2217 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2218 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2219 /* 2220 * Hmm, no node while parsing? 2221 * Return an empty string, in case NULL will break something. 2222 */ 2223 *msg = xmlStrdup(BAD_CAST ""); 2224 } else { 2225 TODO 2226 return (NULL); 2227 } 2228 /* 2229 * VAL TODO: The output of the given schema component is currently 2230 * disabled. 2231 */ 2232 #if 0 2233 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2234 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2235 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2236 NULL, type, NULL, 0)); 2237 FREE_AND_NULL(str) 2238 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2239 } 2240 #endif 2241 return (*msg); 2242 } 2243 2244 static void 2245 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2246 const char *funcName, 2247 const char *message, 2248 const xmlChar *str1, 2249 const xmlChar *str2) 2250 { 2251 xmlChar *msg = NULL; 2252 2253 if (actxt == NULL) 2254 return; 2255 msg = xmlStrdup(BAD_CAST "Internal error: "); 2256 msg = xmlStrcat(msg, BAD_CAST funcName); 2257 msg = xmlStrcat(msg, BAD_CAST ", "); 2258 msg = xmlStrcat(msg, BAD_CAST message); 2259 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2260 2261 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2262 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, 2263 (const char *) msg, str1, str2); 2264 2265 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2266 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, 2267 (const char *) msg, str1, str2); 2268 2269 FREE_AND_NULL(msg) 2270 } 2271 2272 static void 2273 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2274 const char *funcName, 2275 const char *message) 2276 { 2277 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2278 } 2279 2280 #if 0 2281 static void 2282 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2283 const char *funcName, 2284 const char *message, 2285 const xmlChar *str1, 2286 const xmlChar *str2) 2287 { 2288 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2289 str1, str2); 2290 } 2291 #endif 2292 2293 static void 2294 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2295 xmlParserErrors error, 2296 xmlNodePtr node, 2297 xmlSchemaBasicItemPtr item, 2298 const char *message, 2299 const xmlChar *str1, const xmlChar *str2, 2300 const xmlChar *str3, const xmlChar *str4) 2301 { 2302 xmlChar *msg = NULL; 2303 2304 if ((node == NULL) && (item != NULL) && 2305 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2306 node = WXS_ITEM_NODE(item); 2307 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2308 msg = xmlStrcat(msg, BAD_CAST ": "); 2309 } else 2310 xmlSchemaFormatNodeForError(&msg, actxt, node); 2311 msg = xmlStrcat(msg, (const xmlChar *) message); 2312 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2313 xmlSchemaErr4(actxt, error, node, 2314 (const char *) msg, str1, str2, str3, str4); 2315 FREE_AND_NULL(msg) 2316 } 2317 2318 static void 2319 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2320 xmlParserErrors error, 2321 xmlNodePtr node, 2322 xmlSchemaBasicItemPtr item, 2323 const char *message, 2324 const xmlChar *str1, 2325 const xmlChar *str2) 2326 { 2327 xmlSchemaCustomErr4(actxt, error, node, item, 2328 message, str1, str2, NULL, NULL); 2329 } 2330 2331 2332 2333 static void 2334 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2335 xmlParserErrors error, 2336 xmlNodePtr node, 2337 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2338 const char *message, 2339 const xmlChar *str1, 2340 const xmlChar *str2, 2341 const xmlChar *str3) 2342 { 2343 xmlChar *msg = NULL; 2344 2345 xmlSchemaFormatNodeForError(&msg, actxt, node); 2346 msg = xmlStrcat(msg, (const xmlChar *) message); 2347 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2348 2349 /* URGENT TODO: Set the error code to something sane. */ 2350 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2351 (const char *) msg, str1, str2, str3, NULL); 2352 2353 FREE_AND_NULL(msg) 2354 } 2355 2356 2357 2358 static void 2359 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2360 xmlParserErrors error, 2361 xmlSchemaPSVIIDCNodePtr idcNode, 2362 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2363 const char *message, 2364 const xmlChar *str1, 2365 const xmlChar *str2) 2366 { 2367 xmlChar *msg = NULL, *qname = NULL; 2368 2369 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2370 msg = xmlStrcat(msg, (const xmlChar *) message); 2371 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2372 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2373 error, NULL, idcNode->nodeLine, (const char *) msg, 2374 xmlSchemaFormatQName(&qname, 2375 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2376 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2377 str1, str2, NULL); 2378 FREE_AND_NULL(qname); 2379 FREE_AND_NULL(msg); 2380 } 2381 2382 static int 2383 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2384 xmlNodePtr node) 2385 { 2386 if (node != NULL) 2387 return (node->type); 2388 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2389 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2390 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2391 return (-1); 2392 } 2393 2394 static int 2395 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2396 { 2397 switch (item->type) { 2398 case XML_SCHEMA_TYPE_COMPLEX: 2399 case XML_SCHEMA_TYPE_SIMPLE: 2400 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2401 return(1); 2402 break; 2403 case XML_SCHEMA_TYPE_GROUP: 2404 return (1); 2405 case XML_SCHEMA_TYPE_ELEMENT: 2406 if ( ((xmlSchemaElementPtr) item)->flags & 2407 XML_SCHEMAS_ELEM_GLOBAL) 2408 return(1); 2409 break; 2410 case XML_SCHEMA_TYPE_ATTRIBUTE: 2411 if ( ((xmlSchemaAttributePtr) item)->flags & 2412 XML_SCHEMAS_ATTR_GLOBAL) 2413 return(1); 2414 break; 2415 /* Note that attribute groups are always global. */ 2416 default: 2417 return(1); 2418 } 2419 return (0); 2420 } 2421 2422 static void 2423 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2424 xmlParserErrors error, 2425 xmlNodePtr node, 2426 const xmlChar *value, 2427 xmlSchemaTypePtr type, 2428 int displayValue) 2429 { 2430 xmlChar *msg = NULL; 2431 2432 xmlSchemaFormatNodeForError(&msg, actxt, node); 2433 2434 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2435 XML_ATTRIBUTE_NODE)) 2436 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2437 else 2438 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2439 "value of "); 2440 2441 if (! xmlSchemaIsGlobalItem(type)) 2442 msg = xmlStrcat(msg, BAD_CAST "the local "); 2443 else 2444 msg = xmlStrcat(msg, BAD_CAST "the "); 2445 2446 if (WXS_IS_ATOMIC(type)) 2447 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2448 else if (WXS_IS_LIST(type)) 2449 msg = xmlStrcat(msg, BAD_CAST "list type"); 2450 else if (WXS_IS_UNION(type)) 2451 msg = xmlStrcat(msg, BAD_CAST "union type"); 2452 2453 if (xmlSchemaIsGlobalItem(type)) { 2454 xmlChar *str = NULL; 2455 msg = xmlStrcat(msg, BAD_CAST " '"); 2456 if (type->builtInType != 0) { 2457 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2458 msg = xmlStrcat(msg, type->name); 2459 } else 2460 msg = xmlStrcat(msg, 2461 xmlSchemaFormatQName(&str, 2462 type->targetNamespace, type->name)); 2463 msg = xmlStrcat(msg, BAD_CAST "'"); 2464 FREE_AND_NULL(str); 2465 } 2466 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2467 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2468 XML_ATTRIBUTE_NODE)) 2469 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2470 else 2471 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2472 FREE_AND_NULL(msg) 2473 } 2474 2475 static const xmlChar * 2476 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2477 xmlSchemaNodeInfoPtr ni, 2478 xmlNodePtr node) 2479 { 2480 if (node != NULL) { 2481 if (node->ns != NULL) 2482 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2483 else 2484 return (xmlSchemaFormatQName(str, NULL, node->name)); 2485 } else if (ni != NULL) 2486 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2487 return (NULL); 2488 } 2489 2490 static void 2491 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2492 xmlParserErrors error, 2493 xmlSchemaAttrInfoPtr ni, 2494 xmlNodePtr node) 2495 { 2496 xmlChar *msg = NULL, *str = NULL; 2497 2498 xmlSchemaFormatNodeForError(&msg, actxt, node); 2499 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2500 xmlSchemaErr(actxt, error, node, (const char *) msg, 2501 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2502 NULL); 2503 FREE_AND_NULL(str) 2504 FREE_AND_NULL(msg) 2505 } 2506 2507 static void 2508 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2509 xmlParserErrors error, 2510 xmlNodePtr node, 2511 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2512 const char *message, 2513 int nbval, 2514 int nbneg, 2515 xmlChar **values) 2516 { 2517 xmlChar *str = NULL, *msg = NULL; 2518 xmlChar *localName, *nsName; 2519 const xmlChar *cur, *end; 2520 int i; 2521 2522 xmlSchemaFormatNodeForError(&msg, actxt, node); 2523 msg = xmlStrcat(msg, (const xmlChar *) message); 2524 msg = xmlStrcat(msg, BAD_CAST "."); 2525 /* 2526 * Note that is does not make sense to report that we have a 2527 * wildcard here, since the wildcard might be unfolded into 2528 * multiple transitions. 2529 */ 2530 if (nbval + nbneg > 0) { 2531 if (nbval + nbneg > 1) { 2532 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2533 } else 2534 str = xmlStrdup(BAD_CAST " Expected is ( "); 2535 nsName = NULL; 2536 2537 for (i = 0; i < nbval + nbneg; i++) { 2538 cur = values[i]; 2539 if (cur == NULL) 2540 continue; 2541 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2542 (cur[3] == ' ')) { 2543 cur += 4; 2544 str = xmlStrcat(str, BAD_CAST "##other"); 2545 } 2546 /* 2547 * Get the local name. 2548 */ 2549 localName = NULL; 2550 2551 end = cur; 2552 if (*end == '*') { 2553 localName = xmlStrdup(BAD_CAST "*"); 2554 end++; 2555 } else { 2556 while ((*end != 0) && (*end != '|')) 2557 end++; 2558 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2559 } 2560 if (*end != 0) { 2561 end++; 2562 /* 2563 * Skip "*|*" if they come with negated expressions, since 2564 * they represent the same negated wildcard. 2565 */ 2566 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2567 /* 2568 * Get the namespace name. 2569 */ 2570 cur = end; 2571 if (*end == '*') { 2572 nsName = xmlStrdup(BAD_CAST "{*}"); 2573 } else { 2574 while (*end != 0) 2575 end++; 2576 2577 if (i >= nbval) 2578 nsName = xmlStrdup(BAD_CAST "{##other:"); 2579 else 2580 nsName = xmlStrdup(BAD_CAST "{"); 2581 2582 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2583 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2584 } 2585 str = xmlStrcat(str, BAD_CAST nsName); 2586 FREE_AND_NULL(nsName) 2587 } else { 2588 FREE_AND_NULL(localName); 2589 continue; 2590 } 2591 } 2592 str = xmlStrcat(str, BAD_CAST localName); 2593 FREE_AND_NULL(localName); 2594 2595 if (i < nbval + nbneg -1) 2596 str = xmlStrcat(str, BAD_CAST ", "); 2597 } 2598 str = xmlStrcat(str, BAD_CAST " ).\n"); 2599 msg = xmlStrcat(msg, BAD_CAST str); 2600 FREE_AND_NULL(str) 2601 } else 2602 msg = xmlStrcat(msg, BAD_CAST "\n"); 2603 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2604 xmlFree(msg); 2605 } 2606 2607 static void 2608 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2609 xmlParserErrors error, 2610 xmlNodePtr node, 2611 const xmlChar *value, 2612 unsigned long length, 2613 xmlSchemaTypePtr type, 2614 xmlSchemaFacetPtr facet, 2615 const char *message, 2616 const xmlChar *str1, 2617 const xmlChar *str2) 2618 { 2619 xmlChar *str = NULL, *msg = NULL; 2620 xmlSchemaTypeType facetType; 2621 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2622 2623 xmlSchemaFormatNodeForError(&msg, actxt, node); 2624 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2625 facetType = XML_SCHEMA_FACET_ENUMERATION; 2626 /* 2627 * If enumerations are validated, one must not expect the 2628 * facet to be given. 2629 */ 2630 } else 2631 facetType = facet->type; 2632 msg = xmlStrcat(msg, BAD_CAST "["); 2633 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2634 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2635 msg = xmlStrcat(msg, BAD_CAST "'] "); 2636 if (message == NULL) { 2637 /* 2638 * Use a default message. 2639 */ 2640 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2641 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2642 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2643 2644 char len[25], actLen[25]; 2645 2646 /* FIXME, TODO: What is the max expected string length of the 2647 * this value? 2648 */ 2649 if (nodeType == XML_ATTRIBUTE_NODE) 2650 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2651 else 2652 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2653 2654 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2655 snprintf(actLen, 24, "%lu", length); 2656 2657 if (facetType == XML_SCHEMA_FACET_LENGTH) 2658 msg = xmlStrcat(msg, 2659 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2660 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2661 msg = xmlStrcat(msg, 2662 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2663 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2664 msg = xmlStrcat(msg, 2665 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2666 2667 if (nodeType == XML_ATTRIBUTE_NODE) 2668 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2669 value, (const xmlChar *) actLen, (const xmlChar *) len); 2670 else 2671 xmlSchemaErr(actxt, error, node, (const char *) msg, 2672 (const xmlChar *) actLen, (const xmlChar *) len); 2673 2674 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2675 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2676 "of the set {%s}.\n"); 2677 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2678 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2679 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2681 "by the pattern '%s'.\n"); 2682 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2683 facet->value); 2684 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2685 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2686 "minimum value allowed ('%s').\n"); 2687 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2688 facet->value); 2689 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2690 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2691 "maximum value allowed ('%s').\n"); 2692 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2693 facet->value); 2694 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2695 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2696 "'%s'.\n"); 2697 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2698 facet->value); 2699 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2700 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2701 "'%s'.\n"); 2702 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2703 facet->value); 2704 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2706 "digits than are allowed ('%s').\n"); 2707 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2708 facet->value); 2709 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2711 "digits than are allowed ('%s').\n"); 2712 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2713 facet->value); 2714 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2717 } else { 2718 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2719 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2720 } 2721 } else { 2722 msg = xmlStrcat(msg, (const xmlChar *) message); 2723 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2724 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2725 } 2726 FREE_AND_NULL(str) 2727 xmlFree(msg); 2728 } 2729 2730 #define VERROR(err, type, msg) \ 2731 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2732 2733 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2734 2735 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2736 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2737 2738 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2739 2740 2741 /** 2742 * xmlSchemaPMissingAttrErr: 2743 * @ctxt: the schema validation context 2744 * @ownerDes: the designation of the owner 2745 * @ownerName: the name of the owner 2746 * @ownerItem: the owner as a schema object 2747 * @ownerElem: the owner as an element node 2748 * @node: the parent element node of the missing attribute node 2749 * @type: the corresponding type of the attribute node 2750 * 2751 * Reports an illegal attribute. 2752 */ 2753 static void 2754 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2755 xmlParserErrors error, 2756 xmlSchemaBasicItemPtr ownerItem, 2757 xmlNodePtr ownerElem, 2758 const char *name, 2759 const char *message) 2760 { 2761 xmlChar *des = NULL; 2762 2763 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2764 2765 if (message != NULL) 2766 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2767 else 2768 xmlSchemaPErr(ctxt, ownerElem, error, 2769 "%s: The attribute '%s' is required but missing.\n", 2770 BAD_CAST des, BAD_CAST name); 2771 FREE_AND_NULL(des); 2772 } 2773 2774 2775 /** 2776 * xmlSchemaPResCompAttrErr: 2777 * @ctxt: the schema validation context 2778 * @error: the error code 2779 * @ownerDes: the designation of the owner 2780 * @ownerItem: the owner as a schema object 2781 * @ownerElem: the owner as an element node 2782 * @name: the name of the attribute holding the QName 2783 * @refName: the referenced local name 2784 * @refURI: the referenced namespace URI 2785 * @message: optional message 2786 * 2787 * Used to report QName attribute values that failed to resolve 2788 * to schema components. 2789 */ 2790 static void 2791 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2792 xmlParserErrors error, 2793 xmlSchemaBasicItemPtr ownerItem, 2794 xmlNodePtr ownerElem, 2795 const char *name, 2796 const xmlChar *refName, 2797 const xmlChar *refURI, 2798 xmlSchemaTypeType refType, 2799 const char *refTypeStr) 2800 { 2801 xmlChar *des = NULL, *strA = NULL; 2802 2803 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2804 if (refTypeStr == NULL) 2805 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2806 xmlSchemaPErrExt(ctxt, ownerElem, error, 2807 NULL, NULL, NULL, 2808 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2809 "%s.\n", BAD_CAST des, BAD_CAST name, 2810 xmlSchemaFormatQName(&strA, refURI, refName), 2811 BAD_CAST refTypeStr, NULL); 2812 FREE_AND_NULL(des) 2813 FREE_AND_NULL(strA) 2814 } 2815 2816 /** 2817 * xmlSchemaPCustomAttrErr: 2818 * @ctxt: the schema parser context 2819 * @error: the error code 2820 * @ownerDes: the designation of the owner 2821 * @ownerItem: the owner as a schema object 2822 * @attr: the illegal attribute node 2823 * 2824 * Reports an illegal attribute during the parse. 2825 */ 2826 static void 2827 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2828 xmlParserErrors error, 2829 xmlChar **ownerDes, 2830 xmlSchemaBasicItemPtr ownerItem, 2831 xmlAttrPtr attr, 2832 const char *msg) 2833 { 2834 xmlChar *des = NULL; 2835 2836 if (ownerDes == NULL) 2837 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2838 else if (*ownerDes == NULL) { 2839 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2840 des = *ownerDes; 2841 } else 2842 des = *ownerDes; 2843 if (attr == NULL) { 2844 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2845 "%s, attribute '%s': %s.\n", 2846 BAD_CAST des, (const xmlChar *) "Unknown", 2847 (const xmlChar *) msg, NULL, NULL); 2848 } else { 2849 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2850 "%s, attribute '%s': %s.\n", 2851 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2852 } 2853 if (ownerDes == NULL) 2854 FREE_AND_NULL(des); 2855 } 2856 2857 /** 2858 * xmlSchemaPIllegalAttrErr: 2859 * @ctxt: the schema parser context 2860 * @error: the error code 2861 * @ownerDes: the designation of the attribute's owner 2862 * @ownerItem: the attribute's owner item 2863 * @attr: the illegal attribute node 2864 * 2865 * Reports an illegal attribute during the parse. 2866 */ 2867 static void 2868 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2869 xmlParserErrors error, 2870 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2871 xmlAttrPtr attr) 2872 { 2873 xmlChar *strA = NULL, *strB = NULL; 2874 2875 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2876 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2877 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2878 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2879 NULL, NULL); 2880 FREE_AND_NULL(strA); 2881 FREE_AND_NULL(strB); 2882 } 2883 2884 /** 2885 * xmlSchemaPCustomErr: 2886 * @ctxt: the schema parser context 2887 * @error: the error code 2888 * @itemDes: the designation of the schema item 2889 * @item: the schema item 2890 * @itemElem: the node of the schema item 2891 * @message: the error message 2892 * @str1: an optional param for the error message 2893 * @str2: an optional param for the error message 2894 * @str3: an optional param for the error message 2895 * 2896 * Reports an error during parsing. 2897 */ 2898 static void 2899 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2900 xmlParserErrors error, 2901 xmlSchemaBasicItemPtr item, 2902 xmlNodePtr itemElem, 2903 const char *message, 2904 const xmlChar *str1, 2905 const xmlChar *str2, 2906 const xmlChar *str3) 2907 { 2908 xmlChar *des = NULL, *msg = NULL; 2909 2910 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2911 msg = xmlStrdup(BAD_CAST "%s: "); 2912 msg = xmlStrcat(msg, (const xmlChar *) message); 2913 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2914 if ((itemElem == NULL) && (item != NULL)) 2915 itemElem = WXS_ITEM_NODE(item); 2916 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2917 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2918 FREE_AND_NULL(des); 2919 FREE_AND_NULL(msg); 2920 } 2921 2922 /** 2923 * xmlSchemaPCustomErr: 2924 * @ctxt: the schema parser context 2925 * @error: the error code 2926 * @itemDes: the designation of the schema item 2927 * @item: the schema item 2928 * @itemElem: the node of the schema item 2929 * @message: the error message 2930 * @str1: the optional param for the error message 2931 * 2932 * Reports an error during parsing. 2933 */ 2934 static void 2935 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2936 xmlParserErrors error, 2937 xmlSchemaBasicItemPtr item, 2938 xmlNodePtr itemElem, 2939 const char *message, 2940 const xmlChar *str1) 2941 { 2942 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2943 str1, NULL, NULL); 2944 } 2945 2946 /** 2947 * xmlSchemaPAttrUseErr: 2948 * @ctxt: the schema parser context 2949 * @error: the error code 2950 * @itemDes: the designation of the schema type 2951 * @item: the schema type 2952 * @itemElem: the node of the schema type 2953 * @attr: the invalid schema attribute 2954 * @message: the error message 2955 * @str1: the optional param for the error message 2956 * 2957 * Reports an attribute use error during parsing. 2958 */ 2959 static void 2960 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2961 xmlParserErrors error, 2962 xmlNodePtr node, 2963 xmlSchemaBasicItemPtr ownerItem, 2964 const xmlSchemaAttributeUsePtr attruse, 2965 const char *message, 2966 const xmlChar *str1, const xmlChar *str2, 2967 const xmlChar *str3,const xmlChar *str4) 2968 { 2969 xmlChar *str = NULL, *msg = NULL; 2970 2971 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 2972 msg = xmlStrcat(msg, BAD_CAST ", "); 2973 msg = xmlStrcat(msg, 2974 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 2975 WXS_BASIC_CAST attruse, NULL)); 2976 FREE_AND_NULL(str); 2977 msg = xmlStrcat(msg, BAD_CAST ": "); 2978 msg = xmlStrcat(msg, (const xmlChar *) message); 2979 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2980 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 2981 (const char *) msg, str1, str2, str3, str4); 2982 xmlFree(msg); 2983 } 2984 2985 /** 2986 * xmlSchemaPIllegalFacetAtomicErr: 2987 * @ctxt: the schema parser context 2988 * @error: the error code 2989 * @type: the schema type 2990 * @baseType: the base type of type 2991 * @facet: the illegal facet 2992 * 2993 * Reports an illegal facet for atomic simple types. 2994 */ 2995 static void 2996 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 2997 xmlParserErrors error, 2998 xmlSchemaTypePtr type, 2999 xmlSchemaTypePtr baseType, 3000 xmlSchemaFacetPtr facet) 3001 { 3002 xmlChar *des = NULL, *strT = NULL; 3003 3004 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3005 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3006 "%s: The facet '%s' is not allowed on types derived from the " 3007 "type %s.\n", 3008 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3009 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3010 NULL, NULL); 3011 FREE_AND_NULL(des); 3012 FREE_AND_NULL(strT); 3013 } 3014 3015 /** 3016 * xmlSchemaPIllegalFacetListUnionErr: 3017 * @ctxt: the schema parser context 3018 * @error: the error code 3019 * @itemDes: the designation of the schema item involved 3020 * @item: the schema item involved 3021 * @facet: the illegal facet 3022 * 3023 * Reports an illegal facet for <list> and <union>. 3024 */ 3025 static void 3026 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3027 xmlParserErrors error, 3028 xmlSchemaTypePtr type, 3029 xmlSchemaFacetPtr facet) 3030 { 3031 xmlChar *des = NULL; 3032 3033 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3034 type->node); 3035 xmlSchemaPErr(ctxt, type->node, error, 3036 "%s: The facet '%s' is not allowed.\n", 3037 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3038 FREE_AND_NULL(des); 3039 } 3040 3041 /** 3042 * xmlSchemaPMutualExclAttrErr: 3043 * @ctxt: the schema validation context 3044 * @error: the error code 3045 * @elemDes: the designation of the parent element node 3046 * @attr: the bad attribute node 3047 * @type: the corresponding type of the attribute node 3048 * 3049 * Reports an illegal attribute. 3050 */ 3051 static void 3052 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3053 xmlParserErrors error, 3054 xmlSchemaBasicItemPtr ownerItem, 3055 xmlAttrPtr attr, 3056 const char *name1, 3057 const char *name2) 3058 { 3059 xmlChar *des = NULL; 3060 3061 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3062 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3063 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3064 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3065 FREE_AND_NULL(des); 3066 } 3067 3068 /** 3069 * xmlSchemaPSimpleTypeErr: 3070 * @ctxt: the schema validation context 3071 * @error: the error code 3072 * @type: the type specifier 3073 * @ownerDes: the designation of the owner 3074 * @ownerItem: the schema object if existent 3075 * @node: the validated node 3076 * @value: the validated value 3077 * 3078 * Reports a simple type validation error. 3079 * TODO: Should this report the value of an element as well? 3080 */ 3081 static void 3082 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3083 xmlParserErrors error, 3084 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3085 xmlNodePtr node, 3086 xmlSchemaTypePtr type, 3087 const char *expected, 3088 const xmlChar *value, 3089 const char *message, 3090 const xmlChar *str1, 3091 const xmlChar *str2) 3092 { 3093 xmlChar *msg = NULL; 3094 3095 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3096 if (message == NULL) { 3097 /* 3098 * Use default messages. 3099 */ 3100 if (type != NULL) { 3101 if (node->type == XML_ATTRIBUTE_NODE) 3102 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3103 else 3104 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3105 "valid value of "); 3106 if (! xmlSchemaIsGlobalItem(type)) 3107 msg = xmlStrcat(msg, BAD_CAST "the local "); 3108 else 3109 msg = xmlStrcat(msg, BAD_CAST "the "); 3110 3111 if (WXS_IS_ATOMIC(type)) 3112 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3113 else if (WXS_IS_LIST(type)) 3114 msg = xmlStrcat(msg, BAD_CAST "list type"); 3115 else if (WXS_IS_UNION(type)) 3116 msg = xmlStrcat(msg, BAD_CAST "union type"); 3117 3118 if (xmlSchemaIsGlobalItem(type)) { 3119 xmlChar *str = NULL; 3120 msg = xmlStrcat(msg, BAD_CAST " '"); 3121 if (type->builtInType != 0) { 3122 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3123 msg = xmlStrcat(msg, type->name); 3124 } else 3125 msg = xmlStrcat(msg, 3126 xmlSchemaFormatQName(&str, 3127 type->targetNamespace, type->name)); 3128 msg = xmlStrcat(msg, BAD_CAST "'."); 3129 FREE_AND_NULL(str); 3130 } 3131 } else { 3132 if (node->type == XML_ATTRIBUTE_NODE) 3133 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3134 else 3135 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3136 "valid."); 3137 } 3138 if (expected) { 3139 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3140 msg = xmlStrcat(msg, BAD_CAST expected); 3141 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3142 } else 3143 msg = xmlStrcat(msg, BAD_CAST "\n"); 3144 if (node->type == XML_ATTRIBUTE_NODE) 3145 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3146 else 3147 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3148 } else { 3149 msg = xmlStrcat(msg, BAD_CAST message); 3150 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3151 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3152 (const char*) msg, str1, str2, NULL, NULL, NULL); 3153 } 3154 /* Cleanup. */ 3155 FREE_AND_NULL(msg) 3156 } 3157 3158 /** 3159 * xmlSchemaPContentErr: 3160 * @ctxt: the schema parser context 3161 * @error: the error code 3162 * @onwerDes: the designation of the holder of the content 3163 * @ownerItem: the owner item of the holder of the content 3164 * @ownerElem: the node of the holder of the content 3165 * @child: the invalid child node 3166 * @message: the optional error message 3167 * @content: the optional string describing the correct content 3168 * 3169 * Reports an error concerning the content of a schema element. 3170 */ 3171 static void 3172 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3173 xmlParserErrors error, 3174 xmlSchemaBasicItemPtr ownerItem, 3175 xmlNodePtr ownerElem, 3176 xmlNodePtr child, 3177 const char *message, 3178 const char *content) 3179 { 3180 xmlChar *des = NULL; 3181 3182 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3183 if (message != NULL) 3184 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3185 "%s: %s.\n", 3186 BAD_CAST des, BAD_CAST message); 3187 else { 3188 if (content != NULL) { 3189 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3190 "%s: The content is not valid. Expected is %s.\n", 3191 BAD_CAST des, BAD_CAST content); 3192 } else { 3193 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3194 "%s: The content is not valid.\n", 3195 BAD_CAST des, NULL); 3196 } 3197 } 3198 FREE_AND_NULL(des) 3199 } 3200 3201 /************************************************************************ 3202 * * 3203 * Streamable error functions * 3204 * * 3205 ************************************************************************/ 3206 3207 3208 3209 3210 /************************************************************************ 3211 * * 3212 * Validation helper functions * 3213 * * 3214 ************************************************************************/ 3215 3216 3217 /************************************************************************ 3218 * * 3219 * Allocation functions * 3220 * * 3221 ************************************************************************/ 3222 3223 /** 3224 * xmlSchemaNewSchemaForParserCtxt: 3225 * @ctxt: a schema validation context 3226 * 3227 * Allocate a new Schema structure. 3228 * 3229 * Returns the newly allocated structure or NULL in case or error 3230 */ 3231 static xmlSchemaPtr 3232 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3233 { 3234 xmlSchemaPtr ret; 3235 3236 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3237 if (ret == NULL) { 3238 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3239 return (NULL); 3240 } 3241 memset(ret, 0, sizeof(xmlSchema)); 3242 ret->dict = ctxt->dict; 3243 xmlDictReference(ret->dict); 3244 3245 return (ret); 3246 } 3247 3248 /** 3249 * xmlSchemaNewFacet: 3250 * 3251 * Allocate a new Facet structure. 3252 * 3253 * Returns the newly allocated structure or NULL in case or error 3254 */ 3255 xmlSchemaFacetPtr 3256 xmlSchemaNewFacet(void) 3257 { 3258 xmlSchemaFacetPtr ret; 3259 3260 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3261 if (ret == NULL) { 3262 return (NULL); 3263 } 3264 memset(ret, 0, sizeof(xmlSchemaFacet)); 3265 3266 return (ret); 3267 } 3268 3269 /** 3270 * xmlSchemaNewAnnot: 3271 * @ctxt: a schema validation context 3272 * @node: a node 3273 * 3274 * Allocate a new annotation structure. 3275 * 3276 * Returns the newly allocated structure or NULL in case or error 3277 */ 3278 static xmlSchemaAnnotPtr 3279 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3280 { 3281 xmlSchemaAnnotPtr ret; 3282 3283 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3284 if (ret == NULL) { 3285 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3286 return (NULL); 3287 } 3288 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3289 ret->content = node; 3290 return (ret); 3291 } 3292 3293 static xmlSchemaItemListPtr 3294 xmlSchemaItemListCreate(void) 3295 { 3296 xmlSchemaItemListPtr ret; 3297 3298 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3299 if (ret == NULL) { 3300 xmlSchemaPErrMemory(NULL, 3301 "allocating an item list structure", NULL); 3302 return (NULL); 3303 } 3304 memset(ret, 0, sizeof(xmlSchemaItemList)); 3305 return (ret); 3306 } 3307 3308 static void 3309 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3310 { 3311 if (list->items != NULL) { 3312 xmlFree(list->items); 3313 list->items = NULL; 3314 } 3315 list->nbItems = 0; 3316 list->sizeItems = 0; 3317 } 3318 3319 static int 3320 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3321 { 3322 if (list->items == NULL) { 3323 list->items = (void **) xmlMalloc( 3324 20 * sizeof(void *)); 3325 if (list->items == NULL) { 3326 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3327 return(-1); 3328 } 3329 list->sizeItems = 20; 3330 } else if (list->sizeItems <= list->nbItems) { 3331 list->sizeItems *= 2; 3332 list->items = (void **) xmlRealloc(list->items, 3333 list->sizeItems * sizeof(void *)); 3334 if (list->items == NULL) { 3335 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3336 list->sizeItems = 0; 3337 return(-1); 3338 } 3339 } 3340 list->items[list->nbItems++] = item; 3341 return(0); 3342 } 3343 3344 static int 3345 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3346 int initialSize, 3347 void *item) 3348 { 3349 if (list->items == NULL) { 3350 if (initialSize <= 0) 3351 initialSize = 1; 3352 list->items = (void **) xmlMalloc( 3353 initialSize * sizeof(void *)); 3354 if (list->items == NULL) { 3355 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3356 return(-1); 3357 } 3358 list->sizeItems = initialSize; 3359 } else if (list->sizeItems <= list->nbItems) { 3360 list->sizeItems *= 2; 3361 list->items = (void **) xmlRealloc(list->items, 3362 list->sizeItems * sizeof(void *)); 3363 if (list->items == NULL) { 3364 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3365 list->sizeItems = 0; 3366 return(-1); 3367 } 3368 } 3369 list->items[list->nbItems++] = item; 3370 return(0); 3371 } 3372 3373 static int 3374 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3375 { 3376 if (list->items == NULL) { 3377 list->items = (void **) xmlMalloc( 3378 20 * sizeof(void *)); 3379 if (list->items == NULL) { 3380 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3381 return(-1); 3382 } 3383 list->sizeItems = 20; 3384 } else if (list->sizeItems <= list->nbItems) { 3385 list->sizeItems *= 2; 3386 list->items = (void **) xmlRealloc(list->items, 3387 list->sizeItems * sizeof(void *)); 3388 if (list->items == NULL) { 3389 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3390 list->sizeItems = 0; 3391 return(-1); 3392 } 3393 } 3394 /* 3395 * Just append if the index is greater/equal than the item count. 3396 */ 3397 if (idx >= list->nbItems) { 3398 list->items[list->nbItems++] = item; 3399 } else { 3400 int i; 3401 for (i = list->nbItems; i > idx; i--) 3402 list->items[i] = list->items[i-1]; 3403 list->items[idx] = item; 3404 list->nbItems++; 3405 } 3406 return(0); 3407 } 3408 3409 #if 0 /* enable if ever needed */ 3410 static int 3411 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3412 int initialSize, 3413 void *item, 3414 int idx) 3415 { 3416 if (list->items == NULL) { 3417 if (initialSize <= 0) 3418 initialSize = 1; 3419 list->items = (void **) xmlMalloc( 3420 initialSize * sizeof(void *)); 3421 if (list->items == NULL) { 3422 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3423 return(-1); 3424 } 3425 list->sizeItems = initialSize; 3426 } else if (list->sizeItems <= list->nbItems) { 3427 list->sizeItems *= 2; 3428 list->items = (void **) xmlRealloc(list->items, 3429 list->sizeItems * sizeof(void *)); 3430 if (list->items == NULL) { 3431 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3432 list->sizeItems = 0; 3433 return(-1); 3434 } 3435 } 3436 /* 3437 * Just append if the index is greater/equal than the item count. 3438 */ 3439 if (idx >= list->nbItems) { 3440 list->items[list->nbItems++] = item; 3441 } else { 3442 int i; 3443 for (i = list->nbItems; i > idx; i--) 3444 list->items[i] = list->items[i-1]; 3445 list->items[idx] = item; 3446 list->nbItems++; 3447 } 3448 return(0); 3449 } 3450 #endif 3451 3452 static int 3453 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3454 { 3455 int i; 3456 if ((list->items == NULL) || (idx >= list->nbItems)) { 3457 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3458 "index error.\n"); 3459 return(-1); 3460 } 3461 3462 if (list->nbItems == 1) { 3463 /* TODO: Really free the list? */ 3464 xmlFree(list->items); 3465 list->items = NULL; 3466 list->nbItems = 0; 3467 list->sizeItems = 0; 3468 } else if (list->nbItems -1 == idx) { 3469 list->nbItems--; 3470 } else { 3471 for (i = idx; i < list->nbItems -1; i++) 3472 list->items[i] = list->items[i+1]; 3473 list->nbItems--; 3474 } 3475 return(0); 3476 } 3477 3478 /** 3479 * xmlSchemaItemListFree: 3480 * @annot: a schema type structure 3481 * 3482 * Deallocate a annotation structure 3483 */ 3484 static void 3485 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3486 { 3487 if (list == NULL) 3488 return; 3489 if (list->items != NULL) 3490 xmlFree(list->items); 3491 xmlFree(list); 3492 } 3493 3494 static void 3495 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3496 { 3497 if (bucket == NULL) 3498 return; 3499 if (bucket->globals != NULL) { 3500 xmlSchemaComponentListFree(bucket->globals); 3501 xmlSchemaItemListFree(bucket->globals); 3502 } 3503 if (bucket->locals != NULL) { 3504 xmlSchemaComponentListFree(bucket->locals); 3505 xmlSchemaItemListFree(bucket->locals); 3506 } 3507 if (bucket->relations != NULL) { 3508 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3509 do { 3510 prev = cur; 3511 cur = cur->next; 3512 xmlFree(prev); 3513 } while (cur != NULL); 3514 } 3515 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3516 xmlFreeDoc(bucket->doc); 3517 } 3518 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3519 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3520 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3521 } 3522 xmlFree(bucket); 3523 } 3524 3525 static xmlSchemaBucketPtr 3526 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3527 int type, const xmlChar *targetNamespace) 3528 { 3529 xmlSchemaBucketPtr ret; 3530 int size; 3531 xmlSchemaPtr mainSchema; 3532 3533 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3534 PERROR_INT("xmlSchemaBucketCreate", 3535 "no main schema on constructor"); 3536 return(NULL); 3537 } 3538 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3539 /* Create the schema bucket. */ 3540 if (WXS_IS_BUCKET_INCREDEF(type)) 3541 size = sizeof(xmlSchemaInclude); 3542 else 3543 size = sizeof(xmlSchemaImport); 3544 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3545 if (ret == NULL) { 3546 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3547 return(NULL); 3548 } 3549 memset(ret, 0, size); 3550 ret->targetNamespace = targetNamespace; 3551 ret->type = type; 3552 ret->globals = xmlSchemaItemListCreate(); 3553 if (ret->globals == NULL) { 3554 xmlFree(ret); 3555 return(NULL); 3556 } 3557 ret->locals = xmlSchemaItemListCreate(); 3558 if (ret->locals == NULL) { 3559 xmlFree(ret); 3560 return(NULL); 3561 } 3562 /* 3563 * The following will assure that only the first bucket is marked as 3564 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3565 * For each following import buckets an xmlSchema will be created. 3566 * An xmlSchema will be created for every distinct targetNamespace. 3567 * We assign the targetNamespace to the schemata here. 3568 */ 3569 if (! WXS_HAS_BUCKETS(pctxt)) { 3570 if (WXS_IS_BUCKET_INCREDEF(type)) { 3571 PERROR_INT("xmlSchemaBucketCreate", 3572 "first bucket but it's an include or redefine"); 3573 xmlSchemaBucketFree(ret); 3574 return(NULL); 3575 } 3576 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3577 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3578 /* Point to the *main* schema. */ 3579 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3580 WXS_IMPBUCKET(ret)->schema = mainSchema; 3581 /* 3582 * Ensure that the main schema gets a targetNamespace. 3583 */ 3584 mainSchema->targetNamespace = targetNamespace; 3585 } else { 3586 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3587 PERROR_INT("xmlSchemaBucketCreate", 3588 "main bucket but it's not the first one"); 3589 xmlSchemaBucketFree(ret); 3590 return(NULL); 3591 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3592 /* 3593 * Create a schema for imports and assign the 3594 * targetNamespace. 3595 */ 3596 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3597 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3598 xmlSchemaBucketFree(ret); 3599 return(NULL); 3600 } 3601 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3602 } 3603 } 3604 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3605 int res; 3606 /* 3607 * Imports go into the "schemasImports" slot of the main *schema*. 3608 * Note that we create an import entry for the main schema as well; i.e., 3609 * even if there's only one schema, we'll get an import. 3610 */ 3611 if (mainSchema->schemasImports == NULL) { 3612 mainSchema->schemasImports = xmlHashCreateDict(5, 3613 WXS_CONSTRUCTOR(pctxt)->dict); 3614 if (mainSchema->schemasImports == NULL) { 3615 xmlSchemaBucketFree(ret); 3616 return(NULL); 3617 } 3618 } 3619 if (targetNamespace == NULL) 3620 res = xmlHashAddEntry(mainSchema->schemasImports, 3621 XML_SCHEMAS_NO_NAMESPACE, ret); 3622 else 3623 res = xmlHashAddEntry(mainSchema->schemasImports, 3624 targetNamespace, ret); 3625 if (res != 0) { 3626 PERROR_INT("xmlSchemaBucketCreate", 3627 "failed to add the schema bucket to the hash"); 3628 xmlSchemaBucketFree(ret); 3629 return(NULL); 3630 } 3631 } else { 3632 /* Set the @ownerImport of an include bucket. */ 3633 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3634 WXS_INCBUCKET(ret)->ownerImport = 3635 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3636 else 3637 WXS_INCBUCKET(ret)->ownerImport = 3638 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3639 3640 /* Includes got into the "includes" slot of the *main* schema. */ 3641 if (mainSchema->includes == NULL) { 3642 mainSchema->includes = xmlSchemaItemListCreate(); 3643 if (mainSchema->includes == NULL) { 3644 xmlSchemaBucketFree(ret); 3645 return(NULL); 3646 } 3647 } 3648 xmlSchemaItemListAdd(mainSchema->includes, ret); 3649 } 3650 /* 3651 * Add to list of all buckets; this is used for lookup 3652 * during schema construction time only. 3653 */ 3654 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3655 return(NULL); 3656 return(ret); 3657 } 3658 3659 static int 3660 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3661 { 3662 if (*list == NULL) { 3663 *list = xmlSchemaItemListCreate(); 3664 if (*list == NULL) 3665 return(-1); 3666 } 3667 xmlSchemaItemListAddSize(*list, initialSize, item); 3668 return(0); 3669 } 3670 3671 /** 3672 * xmlSchemaFreeAnnot: 3673 * @annot: a schema type structure 3674 * 3675 * Deallocate a annotation structure 3676 */ 3677 static void 3678 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3679 { 3680 if (annot == NULL) 3681 return; 3682 if (annot->next == NULL) { 3683 xmlFree(annot); 3684 } else { 3685 xmlSchemaAnnotPtr prev; 3686 3687 do { 3688 prev = annot; 3689 annot = annot->next; 3690 xmlFree(prev); 3691 } while (annot != NULL); 3692 } 3693 } 3694 3695 /** 3696 * xmlSchemaFreeNotation: 3697 * @schema: a schema notation structure 3698 * 3699 * Deallocate a Schema Notation structure. 3700 */ 3701 static void 3702 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3703 { 3704 if (nota == NULL) 3705 return; 3706 xmlFree(nota); 3707 } 3708 3709 /** 3710 * xmlSchemaFreeAttribute: 3711 * @attr: an attribute declaration 3712 * 3713 * Deallocates an attribute declaration structure. 3714 */ 3715 static void 3716 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3717 { 3718 if (attr == NULL) 3719 return; 3720 if (attr->annot != NULL) 3721 xmlSchemaFreeAnnot(attr->annot); 3722 if (attr->defVal != NULL) 3723 xmlSchemaFreeValue(attr->defVal); 3724 xmlFree(attr); 3725 } 3726 3727 /** 3728 * xmlSchemaFreeAttributeUse: 3729 * @use: an attribute use 3730 * 3731 * Deallocates an attribute use structure. 3732 */ 3733 static void 3734 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3735 { 3736 if (use == NULL) 3737 return; 3738 if (use->annot != NULL) 3739 xmlSchemaFreeAnnot(use->annot); 3740 if (use->defVal != NULL) 3741 xmlSchemaFreeValue(use->defVal); 3742 xmlFree(use); 3743 } 3744 3745 /** 3746 * xmlSchemaFreeAttributeUseProhib: 3747 * @prohib: an attribute use prohibition 3748 * 3749 * Deallocates an attribute use structure. 3750 */ 3751 static void 3752 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3753 { 3754 if (prohib == NULL) 3755 return; 3756 xmlFree(prohib); 3757 } 3758 3759 /** 3760 * xmlSchemaFreeWildcardNsSet: 3761 * set: a schema wildcard namespace 3762 * 3763 * Deallocates a list of wildcard constraint structures. 3764 */ 3765 static void 3766 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3767 { 3768 xmlSchemaWildcardNsPtr next; 3769 3770 while (set != NULL) { 3771 next = set->next; 3772 xmlFree(set); 3773 set = next; 3774 } 3775 } 3776 3777 /** 3778 * xmlSchemaFreeWildcard: 3779 * @wildcard: a wildcard structure 3780 * 3781 * Deallocates a wildcard structure. 3782 */ 3783 void 3784 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3785 { 3786 if (wildcard == NULL) 3787 return; 3788 if (wildcard->annot != NULL) 3789 xmlSchemaFreeAnnot(wildcard->annot); 3790 if (wildcard->nsSet != NULL) 3791 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3792 if (wildcard->negNsSet != NULL) 3793 xmlFree(wildcard->negNsSet); 3794 xmlFree(wildcard); 3795 } 3796 3797 /** 3798 * xmlSchemaFreeAttributeGroup: 3799 * @schema: a schema attribute group structure 3800 * 3801 * Deallocate a Schema Attribute Group structure. 3802 */ 3803 static void 3804 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3805 { 3806 if (attrGr == NULL) 3807 return; 3808 if (attrGr->annot != NULL) 3809 xmlSchemaFreeAnnot(attrGr->annot); 3810 if (attrGr->attrUses != NULL) 3811 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3812 xmlFree(attrGr); 3813 } 3814 3815 /** 3816 * xmlSchemaFreeQNameRef: 3817 * @item: a QName reference structure 3818 * 3819 * Deallocatea a QName reference structure. 3820 */ 3821 static void 3822 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3823 { 3824 xmlFree(item); 3825 } 3826 3827 /** 3828 * xmlSchemaFreeTypeLinkList: 3829 * @alink: a type link 3830 * 3831 * Deallocate a list of types. 3832 */ 3833 static void 3834 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3835 { 3836 xmlSchemaTypeLinkPtr next; 3837 3838 while (link != NULL) { 3839 next = link->next; 3840 xmlFree(link); 3841 link = next; 3842 } 3843 } 3844 3845 static void 3846 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3847 { 3848 xmlSchemaIDCStateObjPtr next; 3849 while (sto != NULL) { 3850 next = sto->next; 3851 if (sto->history != NULL) 3852 xmlFree(sto->history); 3853 if (sto->xpathCtxt != NULL) 3854 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3855 xmlFree(sto); 3856 sto = next; 3857 } 3858 } 3859 3860 /** 3861 * xmlSchemaFreeIDC: 3862 * @idc: a identity-constraint definition 3863 * 3864 * Deallocates an identity-constraint definition. 3865 */ 3866 static void 3867 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3868 { 3869 xmlSchemaIDCSelectPtr cur, prev; 3870 3871 if (idcDef == NULL) 3872 return; 3873 if (idcDef->annot != NULL) 3874 xmlSchemaFreeAnnot(idcDef->annot); 3875 /* Selector */ 3876 if (idcDef->selector != NULL) { 3877 if (idcDef->selector->xpathComp != NULL) 3878 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3879 xmlFree(idcDef->selector); 3880 } 3881 /* Fields */ 3882 if (idcDef->fields != NULL) { 3883 cur = idcDef->fields; 3884 do { 3885 prev = cur; 3886 cur = cur->next; 3887 if (prev->xpathComp != NULL) 3888 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3889 xmlFree(prev); 3890 } while (cur != NULL); 3891 } 3892 xmlFree(idcDef); 3893 } 3894 3895 /** 3896 * xmlSchemaFreeElement: 3897 * @schema: a schema element structure 3898 * 3899 * Deallocate a Schema Element structure. 3900 */ 3901 static void 3902 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3903 { 3904 if (elem == NULL) 3905 return; 3906 if (elem->annot != NULL) 3907 xmlSchemaFreeAnnot(elem->annot); 3908 if (elem->contModel != NULL) 3909 xmlRegFreeRegexp(elem->contModel); 3910 if (elem->defVal != NULL) 3911 xmlSchemaFreeValue(elem->defVal); 3912 xmlFree(elem); 3913 } 3914 3915 /** 3916 * xmlSchemaFreeFacet: 3917 * @facet: a schema facet structure 3918 * 3919 * Deallocate a Schema Facet structure. 3920 */ 3921 void 3922 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3923 { 3924 if (facet == NULL) 3925 return; 3926 if (facet->val != NULL) 3927 xmlSchemaFreeValue(facet->val); 3928 if (facet->regexp != NULL) 3929 xmlRegFreeRegexp(facet->regexp); 3930 if (facet->annot != NULL) 3931 xmlSchemaFreeAnnot(facet->annot); 3932 xmlFree(facet); 3933 } 3934 3935 /** 3936 * xmlSchemaFreeType: 3937 * @type: a schema type structure 3938 * 3939 * Deallocate a Schema Type structure. 3940 */ 3941 void 3942 xmlSchemaFreeType(xmlSchemaTypePtr type) 3943 { 3944 if (type == NULL) 3945 return; 3946 if (type->annot != NULL) 3947 xmlSchemaFreeAnnot(type->annot); 3948 if (type->facets != NULL) { 3949 xmlSchemaFacetPtr facet, next; 3950 3951 facet = type->facets; 3952 while (facet != NULL) { 3953 next = facet->next; 3954 xmlSchemaFreeFacet(facet); 3955 facet = next; 3956 } 3957 } 3958 if (type->attrUses != NULL) 3959 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3960 if (type->memberTypes != NULL) 3961 xmlSchemaFreeTypeLinkList(type->memberTypes); 3962 if (type->facetSet != NULL) { 3963 xmlSchemaFacetLinkPtr next, link; 3964 3965 link = type->facetSet; 3966 do { 3967 next = link->next; 3968 xmlFree(link); 3969 link = next; 3970 } while (link != NULL); 3971 } 3972 if (type->contModel != NULL) 3973 xmlRegFreeRegexp(type->contModel); 3974 xmlFree(type); 3975 } 3976 3977 /** 3978 * xmlSchemaFreeModelGroupDef: 3979 * @item: a schema model group definition 3980 * 3981 * Deallocates a schema model group definition. 3982 */ 3983 static void 3984 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 3985 { 3986 if (item->annot != NULL) 3987 xmlSchemaFreeAnnot(item->annot); 3988 xmlFree(item); 3989 } 3990 3991 /** 3992 * xmlSchemaFreeModelGroup: 3993 * @item: a schema model group 3994 * 3995 * Deallocates a schema model group structure. 3996 */ 3997 static void 3998 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 3999 { 4000 if (item->annot != NULL) 4001 xmlSchemaFreeAnnot(item->annot); 4002 xmlFree(item); 4003 } 4004 4005 static void 4006 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4007 { 4008 if ((list == NULL) || (list->nbItems == 0)) 4009 return; 4010 { 4011 xmlSchemaTreeItemPtr item; 4012 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4013 int i; 4014 4015 for (i = 0; i < list->nbItems; i++) { 4016 item = items[i]; 4017 if (item == NULL) 4018 continue; 4019 switch (item->type) { 4020 case XML_SCHEMA_TYPE_SIMPLE: 4021 case XML_SCHEMA_TYPE_COMPLEX: 4022 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4023 break; 4024 case XML_SCHEMA_TYPE_ATTRIBUTE: 4025 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4026 break; 4027 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4028 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4029 break; 4030 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4031 xmlSchemaFreeAttributeUseProhib( 4032 (xmlSchemaAttributeUseProhibPtr) item); 4033 break; 4034 case XML_SCHEMA_TYPE_ELEMENT: 4035 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4036 break; 4037 case XML_SCHEMA_TYPE_PARTICLE: 4038 if (item->annot != NULL) 4039 xmlSchemaFreeAnnot(item->annot); 4040 xmlFree(item); 4041 break; 4042 case XML_SCHEMA_TYPE_SEQUENCE: 4043 case XML_SCHEMA_TYPE_CHOICE: 4044 case XML_SCHEMA_TYPE_ALL: 4045 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4046 break; 4047 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4048 xmlSchemaFreeAttributeGroup( 4049 (xmlSchemaAttributeGroupPtr) item); 4050 break; 4051 case XML_SCHEMA_TYPE_GROUP: 4052 xmlSchemaFreeModelGroupDef( 4053 (xmlSchemaModelGroupDefPtr) item); 4054 break; 4055 case XML_SCHEMA_TYPE_ANY: 4056 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4057 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4058 break; 4059 case XML_SCHEMA_TYPE_IDC_KEY: 4060 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4061 case XML_SCHEMA_TYPE_IDC_KEYREF: 4062 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4063 break; 4064 case XML_SCHEMA_TYPE_NOTATION: 4065 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4066 break; 4067 case XML_SCHEMA_EXTRA_QNAMEREF: 4068 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4069 break; 4070 default: { 4071 /* TODO: This should never be hit. */ 4072 xmlSchemaPSimpleInternalErr(NULL, 4073 "Internal error: xmlSchemaComponentListFree, " 4074 "unexpected component type '%s'\n", 4075 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4076 } 4077 break; 4078 } 4079 } 4080 list->nbItems = 0; 4081 } 4082 } 4083 4084 /** 4085 * xmlSchemaFree: 4086 * @schema: a schema structure 4087 * 4088 * Deallocate a Schema structure. 4089 */ 4090 void 4091 xmlSchemaFree(xmlSchemaPtr schema) 4092 { 4093 if (schema == NULL) 4094 return; 4095 /* @volatiles is not used anymore :-/ */ 4096 if (schema->volatiles != NULL) 4097 TODO 4098 /* 4099 * Note that those slots are not responsible for freeing 4100 * schema components anymore; this will now be done by 4101 * the schema buckets. 4102 */ 4103 if (schema->notaDecl != NULL) 4104 xmlHashFree(schema->notaDecl, NULL); 4105 if (schema->attrDecl != NULL) 4106 xmlHashFree(schema->attrDecl, NULL); 4107 if (schema->attrgrpDecl != NULL) 4108 xmlHashFree(schema->attrgrpDecl, NULL); 4109 if (schema->elemDecl != NULL) 4110 xmlHashFree(schema->elemDecl, NULL); 4111 if (schema->typeDecl != NULL) 4112 xmlHashFree(schema->typeDecl, NULL); 4113 if (schema->groupDecl != NULL) 4114 xmlHashFree(schema->groupDecl, NULL); 4115 if (schema->idcDef != NULL) 4116 xmlHashFree(schema->idcDef, NULL); 4117 4118 if (schema->schemasImports != NULL) 4119 xmlHashFree(schema->schemasImports, 4120 (xmlHashDeallocator) xmlSchemaBucketFree); 4121 if (schema->includes != NULL) { 4122 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4123 int i; 4124 for (i = 0; i < list->nbItems; i++) { 4125 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4126 } 4127 xmlSchemaItemListFree(list); 4128 } 4129 if (schema->annot != NULL) 4130 xmlSchemaFreeAnnot(schema->annot); 4131 /* Never free the doc here, since this will be done by the buckets. */ 4132 4133 xmlDictFree(schema->dict); 4134 xmlFree(schema); 4135 } 4136 4137 /************************************************************************ 4138 * * 4139 * Debug functions * 4140 * * 4141 ************************************************************************/ 4142 4143 #ifdef LIBXML_OUTPUT_ENABLED 4144 4145 static void 4146 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4147 4148 /** 4149 * xmlSchemaElementDump: 4150 * @elem: an element 4151 * @output: the file output 4152 * 4153 * Dump the element 4154 */ 4155 static void 4156 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4157 const xmlChar * name ATTRIBUTE_UNUSED, 4158 const xmlChar * namespace ATTRIBUTE_UNUSED, 4159 const xmlChar * context ATTRIBUTE_UNUSED) 4160 { 4161 if (elem == NULL) 4162 return; 4163 4164 4165 fprintf(output, "Element"); 4166 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4167 fprintf(output, " (global)"); 4168 fprintf(output, ": '%s' ", elem->name); 4169 if (namespace != NULL) 4170 fprintf(output, "ns '%s'", namespace); 4171 fprintf(output, "\n"); 4172 #if 0 4173 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4174 fprintf(output, " min %d ", elem->minOccurs); 4175 if (elem->maxOccurs >= UNBOUNDED) 4176 fprintf(output, "max: unbounded\n"); 4177 else if (elem->maxOccurs != 1) 4178 fprintf(output, "max: %d\n", elem->maxOccurs); 4179 else 4180 fprintf(output, "\n"); 4181 } 4182 #endif 4183 /* 4184 * Misc other properties. 4185 */ 4186 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4187 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4188 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4189 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4190 fprintf(output, " props: "); 4191 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4192 fprintf(output, "[fixed] "); 4193 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4194 fprintf(output, "[default] "); 4195 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4196 fprintf(output, "[abstract] "); 4197 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4198 fprintf(output, "[nillable] "); 4199 fprintf(output, "\n"); 4200 } 4201 /* 4202 * Default/fixed value. 4203 */ 4204 if (elem->value != NULL) 4205 fprintf(output, " value: '%s'\n", elem->value); 4206 /* 4207 * Type. 4208 */ 4209 if (elem->namedType != NULL) { 4210 fprintf(output, " type: '%s' ", elem->namedType); 4211 if (elem->namedTypeNs != NULL) 4212 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4213 else 4214 fprintf(output, "\n"); 4215 } else if (elem->subtypes != NULL) { 4216 /* 4217 * Dump local types. 4218 */ 4219 xmlSchemaTypeDump(elem->subtypes, output); 4220 } 4221 /* 4222 * Substitution group. 4223 */ 4224 if (elem->substGroup != NULL) { 4225 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4226 if (elem->substGroupNs != NULL) 4227 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4228 else 4229 fprintf(output, "\n"); 4230 } 4231 } 4232 4233 /** 4234 * xmlSchemaAnnotDump: 4235 * @output: the file output 4236 * @annot: a annotation 4237 * 4238 * Dump the annotation 4239 */ 4240 static void 4241 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4242 { 4243 xmlChar *content; 4244 4245 if (annot == NULL) 4246 return; 4247 4248 content = xmlNodeGetContent(annot->content); 4249 if (content != NULL) { 4250 fprintf(output, " Annot: %s\n", content); 4251 xmlFree(content); 4252 } else 4253 fprintf(output, " Annot: empty\n"); 4254 } 4255 4256 /** 4257 * xmlSchemaContentModelDump: 4258 * @particle: the schema particle 4259 * @output: the file output 4260 * @depth: the depth used for intentation 4261 * 4262 * Dump a SchemaType structure 4263 */ 4264 static void 4265 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4266 { 4267 xmlChar *str = NULL; 4268 xmlSchemaTreeItemPtr term; 4269 char shift[100]; 4270 int i; 4271 4272 if (particle == NULL) 4273 return; 4274 for (i = 0;((i < depth) && (i < 25));i++) 4275 shift[2 * i] = shift[2 * i + 1] = ' '; 4276 shift[2 * i] = shift[2 * i + 1] = 0; 4277 fprintf(output, "%s", shift); 4278 if (particle->children == NULL) { 4279 fprintf(output, "MISSING particle term\n"); 4280 return; 4281 } 4282 term = particle->children; 4283 if (term == NULL) { 4284 fprintf(output, "(NULL)"); 4285 } else { 4286 switch (term->type) { 4287 case XML_SCHEMA_TYPE_ELEMENT: 4288 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4289 ((xmlSchemaElementPtr)term)->targetNamespace, 4290 ((xmlSchemaElementPtr)term)->name)); 4291 FREE_AND_NULL(str); 4292 break; 4293 case XML_SCHEMA_TYPE_SEQUENCE: 4294 fprintf(output, "SEQUENCE"); 4295 break; 4296 case XML_SCHEMA_TYPE_CHOICE: 4297 fprintf(output, "CHOICE"); 4298 break; 4299 case XML_SCHEMA_TYPE_ALL: 4300 fprintf(output, "ALL"); 4301 break; 4302 case XML_SCHEMA_TYPE_ANY: 4303 fprintf(output, "ANY"); 4304 break; 4305 default: 4306 fprintf(output, "UNKNOWN\n"); 4307 return; 4308 } 4309 } 4310 if (particle->minOccurs != 1) 4311 fprintf(output, " min: %d", particle->minOccurs); 4312 if (particle->maxOccurs >= UNBOUNDED) 4313 fprintf(output, " max: unbounded"); 4314 else if (particle->maxOccurs != 1) 4315 fprintf(output, " max: %d", particle->maxOccurs); 4316 fprintf(output, "\n"); 4317 if (term && 4318 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4319 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4320 (term->type == XML_SCHEMA_TYPE_ALL)) && 4321 (term->children != NULL)) { 4322 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4323 output, depth +1); 4324 } 4325 if (particle->next != NULL) 4326 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4327 output, depth); 4328 } 4329 4330 /** 4331 * xmlSchemaAttrUsesDump: 4332 * @uses: attribute uses list 4333 * @output: the file output 4334 * 4335 * Dumps a list of attribute use components. 4336 */ 4337 static void 4338 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4339 { 4340 xmlSchemaAttributeUsePtr use; 4341 xmlSchemaAttributeUseProhibPtr prohib; 4342 xmlSchemaQNameRefPtr ref; 4343 const xmlChar *name, *tns; 4344 xmlChar *str = NULL; 4345 int i; 4346 4347 if ((uses == NULL) || (uses->nbItems == 0)) 4348 return; 4349 4350 fprintf(output, " attributes:\n"); 4351 for (i = 0; i < uses->nbItems; i++) { 4352 use = uses->items[i]; 4353 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4354 fprintf(output, " [prohibition] "); 4355 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4356 name = prohib->name; 4357 tns = prohib->targetNamespace; 4358 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4359 fprintf(output, " [reference] "); 4360 ref = (xmlSchemaQNameRefPtr) use; 4361 name = ref->name; 4362 tns = ref->targetNamespace; 4363 } else { 4364 fprintf(output, " [use] "); 4365 name = WXS_ATTRUSE_DECL_NAME(use); 4366 tns = WXS_ATTRUSE_DECL_TNS(use); 4367 } 4368 fprintf(output, "'%s'\n", 4369 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4370 FREE_AND_NULL(str); 4371 } 4372 } 4373 4374 /** 4375 * xmlSchemaTypeDump: 4376 * @output: the file output 4377 * @type: a type structure 4378 * 4379 * Dump a SchemaType structure 4380 */ 4381 static void 4382 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4383 { 4384 if (type == NULL) { 4385 fprintf(output, "Type: NULL\n"); 4386 return; 4387 } 4388 fprintf(output, "Type: "); 4389 if (type->name != NULL) 4390 fprintf(output, "'%s' ", type->name); 4391 else 4392 fprintf(output, "(no name) "); 4393 if (type->targetNamespace != NULL) 4394 fprintf(output, "ns '%s' ", type->targetNamespace); 4395 switch (type->type) { 4396 case XML_SCHEMA_TYPE_BASIC: 4397 fprintf(output, "[basic] "); 4398 break; 4399 case XML_SCHEMA_TYPE_SIMPLE: 4400 fprintf(output, "[simple] "); 4401 break; 4402 case XML_SCHEMA_TYPE_COMPLEX: 4403 fprintf(output, "[complex] "); 4404 break; 4405 case XML_SCHEMA_TYPE_SEQUENCE: 4406 fprintf(output, "[sequence] "); 4407 break; 4408 case XML_SCHEMA_TYPE_CHOICE: 4409 fprintf(output, "[choice] "); 4410 break; 4411 case XML_SCHEMA_TYPE_ALL: 4412 fprintf(output, "[all] "); 4413 break; 4414 case XML_SCHEMA_TYPE_UR: 4415 fprintf(output, "[ur] "); 4416 break; 4417 case XML_SCHEMA_TYPE_RESTRICTION: 4418 fprintf(output, "[restriction] "); 4419 break; 4420 case XML_SCHEMA_TYPE_EXTENSION: 4421 fprintf(output, "[extension] "); 4422 break; 4423 default: 4424 fprintf(output, "[unknown type %d] ", type->type); 4425 break; 4426 } 4427 fprintf(output, "content: "); 4428 switch (type->contentType) { 4429 case XML_SCHEMA_CONTENT_UNKNOWN: 4430 fprintf(output, "[unknown] "); 4431 break; 4432 case XML_SCHEMA_CONTENT_EMPTY: 4433 fprintf(output, "[empty] "); 4434 break; 4435 case XML_SCHEMA_CONTENT_ELEMENTS: 4436 fprintf(output, "[element] "); 4437 break; 4438 case XML_SCHEMA_CONTENT_MIXED: 4439 fprintf(output, "[mixed] "); 4440 break; 4441 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4442 /* not used. */ 4443 break; 4444 case XML_SCHEMA_CONTENT_BASIC: 4445 fprintf(output, "[basic] "); 4446 break; 4447 case XML_SCHEMA_CONTENT_SIMPLE: 4448 fprintf(output, "[simple] "); 4449 break; 4450 case XML_SCHEMA_CONTENT_ANY: 4451 fprintf(output, "[any] "); 4452 break; 4453 } 4454 fprintf(output, "\n"); 4455 if (type->base != NULL) { 4456 fprintf(output, " base type: '%s'", type->base); 4457 if (type->baseNs != NULL) 4458 fprintf(output, " ns '%s'\n", type->baseNs); 4459 else 4460 fprintf(output, "\n"); 4461 } 4462 if (type->attrUses != NULL) 4463 xmlSchemaAttrUsesDump(type->attrUses, output); 4464 if (type->annot != NULL) 4465 xmlSchemaAnnotDump(output, type->annot); 4466 #ifdef DUMP_CONTENT_MODEL 4467 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4468 (type->subtypes != NULL)) { 4469 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4470 output, 1); 4471 } 4472 #endif 4473 } 4474 4475 /** 4476 * xmlSchemaDump: 4477 * @output: the file output 4478 * @schema: a schema structure 4479 * 4480 * Dump a Schema structure. 4481 */ 4482 void 4483 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4484 { 4485 if (output == NULL) 4486 return; 4487 if (schema == NULL) { 4488 fprintf(output, "Schemas: NULL\n"); 4489 return; 4490 } 4491 fprintf(output, "Schemas: "); 4492 if (schema->name != NULL) 4493 fprintf(output, "%s, ", schema->name); 4494 else 4495 fprintf(output, "no name, "); 4496 if (schema->targetNamespace != NULL) 4497 fprintf(output, "%s", (const char *) schema->targetNamespace); 4498 else 4499 fprintf(output, "no target namespace"); 4500 fprintf(output, "\n"); 4501 if (schema->annot != NULL) 4502 xmlSchemaAnnotDump(output, schema->annot); 4503 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4504 output); 4505 xmlHashScanFull(schema->elemDecl, 4506 (xmlHashScannerFull) xmlSchemaElementDump, output); 4507 } 4508 4509 #ifdef DEBUG_IDC_NODE_TABLE 4510 /** 4511 * xmlSchemaDebugDumpIDCTable: 4512 * @vctxt: the WXS validation context 4513 * 4514 * Displays the current IDC table for debug purposes. 4515 */ 4516 static void 4517 xmlSchemaDebugDumpIDCTable(FILE * output, 4518 const xmlChar *namespaceName, 4519 const xmlChar *localName, 4520 xmlSchemaPSVIIDCBindingPtr bind) 4521 { 4522 xmlChar *str = NULL; 4523 const xmlChar *value; 4524 xmlSchemaPSVIIDCNodePtr tab; 4525 xmlSchemaPSVIIDCKeyPtr key; 4526 int i, j, res; 4527 4528 fprintf(output, "IDC: TABLES on '%s'\n", 4529 xmlSchemaFormatQName(&str, namespaceName, localName)); 4530 FREE_AND_NULL(str) 4531 4532 if (bind == NULL) 4533 return; 4534 do { 4535 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4536 xmlSchemaGetComponentQName(&str, 4537 bind->definition), bind->nbNodes); 4538 FREE_AND_NULL(str) 4539 for (i = 0; i < bind->nbNodes; i++) { 4540 tab = bind->nodeTable[i]; 4541 fprintf(output, " ( "); 4542 for (j = 0; j < bind->definition->nbFields; j++) { 4543 key = tab->keys[j]; 4544 if ((key != NULL) && (key->val != NULL)) { 4545 res = xmlSchemaGetCanonValue(key->val, &value); 4546 if (res >= 0) 4547 fprintf(output, "'%s' ", value); 4548 else 4549 fprintf(output, "CANON-VALUE-FAILED "); 4550 if (res == 0) 4551 FREE_AND_NULL(value) 4552 } else if (key != NULL) 4553 fprintf(output, "(no val), "); 4554 else 4555 fprintf(output, "(key missing), "); 4556 } 4557 fprintf(output, ")\n"); 4558 } 4559 if (bind->dupls && bind->dupls->nbItems) { 4560 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4561 for (i = 0; i < bind->dupls->nbItems; i++) { 4562 tab = bind->dupls->items[i]; 4563 fprintf(output, " ( "); 4564 for (j = 0; j < bind->definition->nbFields; j++) { 4565 key = tab->keys[j]; 4566 if ((key != NULL) && (key->val != NULL)) { 4567 res = xmlSchemaGetCanonValue(key->val, &value); 4568 if (res >= 0) 4569 fprintf(output, "'%s' ", value); 4570 else 4571 fprintf(output, "CANON-VALUE-FAILED "); 4572 if (res == 0) 4573 FREE_AND_NULL(value) 4574 } else if (key != NULL) 4575 fprintf(output, "(no val), "); 4576 else 4577 fprintf(output, "(key missing), "); 4578 } 4579 fprintf(output, ")\n"); 4580 } 4581 } 4582 bind = bind->next; 4583 } while (bind != NULL); 4584 } 4585 #endif /* DEBUG_IDC */ 4586 #endif /* LIBXML_OUTPUT_ENABLED */ 4587 4588 /************************************************************************ 4589 * * 4590 * Utilities * 4591 * * 4592 ************************************************************************/ 4593 4594 /** 4595 * xmlSchemaGetPropNode: 4596 * @node: the element node 4597 * @name: the name of the attribute 4598 * 4599 * Seeks an attribute with a name of @name in 4600 * no namespace. 4601 * 4602 * Returns the attribute or NULL if not present. 4603 */ 4604 static xmlAttrPtr 4605 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4606 { 4607 xmlAttrPtr prop; 4608 4609 if ((node == NULL) || (name == NULL)) 4610 return(NULL); 4611 prop = node->properties; 4612 while (prop != NULL) { 4613 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4614 return(prop); 4615 prop = prop->next; 4616 } 4617 return (NULL); 4618 } 4619 4620 /** 4621 * xmlSchemaGetPropNodeNs: 4622 * @node: the element node 4623 * @uri: the uri 4624 * @name: the name of the attribute 4625 * 4626 * Seeks an attribute with a local name of @name and 4627 * a namespace URI of @uri. 4628 * 4629 * Returns the attribute or NULL if not present. 4630 */ 4631 static xmlAttrPtr 4632 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4633 { 4634 xmlAttrPtr prop; 4635 4636 if ((node == NULL) || (name == NULL)) 4637 return(NULL); 4638 prop = node->properties; 4639 while (prop != NULL) { 4640 if ((prop->ns != NULL) && 4641 xmlStrEqual(prop->name, BAD_CAST name) && 4642 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4643 return(prop); 4644 prop = prop->next; 4645 } 4646 return (NULL); 4647 } 4648 4649 static const xmlChar * 4650 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4651 { 4652 xmlChar *val; 4653 const xmlChar *ret; 4654 4655 val = xmlNodeGetContent(node); 4656 if (val == NULL) 4657 val = xmlStrdup((xmlChar *)""); 4658 ret = xmlDictLookup(ctxt->dict, val, -1); 4659 xmlFree(val); 4660 return(ret); 4661 } 4662 4663 static const xmlChar * 4664 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4665 { 4666 return((const xmlChar*) xmlNodeGetContent(node)); 4667 } 4668 4669 /** 4670 * xmlSchemaGetProp: 4671 * @ctxt: the parser context 4672 * @node: the node 4673 * @name: the property name 4674 * 4675 * Read a attribute value and internalize the string 4676 * 4677 * Returns the string or NULL if not present. 4678 */ 4679 static const xmlChar * 4680 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4681 const char *name) 4682 { 4683 xmlChar *val; 4684 const xmlChar *ret; 4685 4686 val = xmlGetNoNsProp(node, BAD_CAST name); 4687 if (val == NULL) 4688 return(NULL); 4689 ret = xmlDictLookup(ctxt->dict, val, -1); 4690 xmlFree(val); 4691 return(ret); 4692 } 4693 4694 /************************************************************************ 4695 * * 4696 * Parsing functions * 4697 * * 4698 ************************************************************************/ 4699 4700 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4701 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4702 ret = xmlHashLookup(schema->slot, name); \ 4703 if (ret != NULL) goto exit; \ 4704 } \ 4705 if (xmlHashSize(schema->schemasImports) > 1) { \ 4706 xmlSchemaImportPtr import; \ 4707 if (nsName == NULL) \ 4708 import = xmlHashLookup(schema->schemasImports, \ 4709 XML_SCHEMAS_NO_NAMESPACE); \ 4710 else \ 4711 import = xmlHashLookup(schema->schemasImports, nsName); \ 4712 if (import == NULL) \ 4713 goto exit; \ 4714 ret = xmlHashLookup(import->schema->slot, name); \ 4715 } 4716 4717 /** 4718 * xmlSchemaGetElem: 4719 * @schema: the schema context 4720 * @name: the element name 4721 * @ns: the element namespace 4722 * 4723 * Lookup a global element declaration in the schema. 4724 * 4725 * Returns the element declaration or NULL if not found. 4726 */ 4727 static xmlSchemaElementPtr 4728 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4729 const xmlChar * nsName) 4730 { 4731 xmlSchemaElementPtr ret = NULL; 4732 4733 if ((name == NULL) || (schema == NULL)) 4734 return(NULL); 4735 if (schema != NULL) { 4736 WXS_FIND_GLOBAL_ITEM(elemDecl) 4737 } 4738 exit: 4739 #ifdef DEBUG 4740 if (ret == NULL) { 4741 if (nsName == NULL) 4742 fprintf(stderr, "Unable to lookup element decl. %s", name); 4743 else 4744 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4745 nsName); 4746 } 4747 #endif 4748 return (ret); 4749 } 4750 4751 /** 4752 * xmlSchemaGetType: 4753 * @schema: the main schema 4754 * @name: the type's name 4755 * nsName: the type's namespace 4756 * 4757 * Lookup a type in the schemas or the predefined types 4758 * 4759 * Returns the group definition or NULL if not found. 4760 */ 4761 static xmlSchemaTypePtr 4762 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4763 const xmlChar * nsName) 4764 { 4765 xmlSchemaTypePtr ret = NULL; 4766 4767 if (name == NULL) 4768 return (NULL); 4769 /* First try the built-in types. */ 4770 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4771 ret = xmlSchemaGetPredefinedType(name, nsName); 4772 if (ret != NULL) 4773 goto exit; 4774 /* 4775 * Note that we try the parsed schemas as well here 4776 * since one might have parsed the S4S, which contain more 4777 * than the built-in types. 4778 * TODO: Can we optimize this? 4779 */ 4780 } 4781 if (schema != NULL) { 4782 WXS_FIND_GLOBAL_ITEM(typeDecl) 4783 } 4784 exit: 4785 4786 #ifdef DEBUG 4787 if (ret == NULL) { 4788 if (nsName == NULL) 4789 fprintf(stderr, "Unable to lookup type %s", name); 4790 else 4791 fprintf(stderr, "Unable to lookup type %s:%s", name, 4792 nsName); 4793 } 4794 #endif 4795 return (ret); 4796 } 4797 4798 /** 4799 * xmlSchemaGetAttributeDecl: 4800 * @schema: the context of the schema 4801 * @name: the name of the attribute 4802 * @ns: the target namespace of the attribute 4803 * 4804 * Lookup a an attribute in the schema or imported schemas 4805 * 4806 * Returns the attribute declaration or NULL if not found. 4807 */ 4808 static xmlSchemaAttributePtr 4809 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4810 const xmlChar * nsName) 4811 { 4812 xmlSchemaAttributePtr ret = NULL; 4813 4814 if ((name == NULL) || (schema == NULL)) 4815 return (NULL); 4816 if (schema != NULL) { 4817 WXS_FIND_GLOBAL_ITEM(attrDecl) 4818 } 4819 exit: 4820 #ifdef DEBUG 4821 if (ret == NULL) { 4822 if (nsName == NULL) 4823 fprintf(stderr, "Unable to lookup attribute %s", name); 4824 else 4825 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4826 nsName); 4827 } 4828 #endif 4829 return (ret); 4830 } 4831 4832 /** 4833 * xmlSchemaGetAttributeGroup: 4834 * @schema: the context of the schema 4835 * @name: the name of the attribute group 4836 * @ns: the target namespace of the attribute group 4837 * 4838 * Lookup a an attribute group in the schema or imported schemas 4839 * 4840 * Returns the attribute group definition or NULL if not found. 4841 */ 4842 static xmlSchemaAttributeGroupPtr 4843 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4844 const xmlChar * nsName) 4845 { 4846 xmlSchemaAttributeGroupPtr ret = NULL; 4847 4848 if ((name == NULL) || (schema == NULL)) 4849 return (NULL); 4850 if (schema != NULL) { 4851 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4852 } 4853 exit: 4854 /* TODO: 4855 if ((ret != NULL) && (ret->redef != NULL)) { 4856 * Return the last redefinition. * 4857 ret = ret->redef; 4858 } 4859 */ 4860 #ifdef DEBUG 4861 if (ret == NULL) { 4862 if (nsName == NULL) 4863 fprintf(stderr, "Unable to lookup attribute group %s", name); 4864 else 4865 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4866 nsName); 4867 } 4868 #endif 4869 return (ret); 4870 } 4871 4872 /** 4873 * xmlSchemaGetGroup: 4874 * @schema: the context of the schema 4875 * @name: the name of the group 4876 * @ns: the target namespace of the group 4877 * 4878 * Lookup a group in the schema or imported schemas 4879 * 4880 * Returns the group definition or NULL if not found. 4881 */ 4882 static xmlSchemaModelGroupDefPtr 4883 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4884 const xmlChar * nsName) 4885 { 4886 xmlSchemaModelGroupDefPtr ret = NULL; 4887 4888 if ((name == NULL) || (schema == NULL)) 4889 return (NULL); 4890 if (schema != NULL) { 4891 WXS_FIND_GLOBAL_ITEM(groupDecl) 4892 } 4893 exit: 4894 4895 #ifdef DEBUG 4896 if (ret == NULL) { 4897 if (nsName == NULL) 4898 fprintf(stderr, "Unable to lookup group %s", name); 4899 else 4900 fprintf(stderr, "Unable to lookup group %s:%s", name, 4901 nsName); 4902 } 4903 #endif 4904 return (ret); 4905 } 4906 4907 static xmlSchemaNotationPtr 4908 xmlSchemaGetNotation(xmlSchemaPtr schema, 4909 const xmlChar *name, 4910 const xmlChar *nsName) 4911 { 4912 xmlSchemaNotationPtr ret = NULL; 4913 4914 if ((name == NULL) || (schema == NULL)) 4915 return (NULL); 4916 if (schema != NULL) { 4917 WXS_FIND_GLOBAL_ITEM(notaDecl) 4918 } 4919 exit: 4920 return (ret); 4921 } 4922 4923 static xmlSchemaIDCPtr 4924 xmlSchemaGetIDC(xmlSchemaPtr schema, 4925 const xmlChar *name, 4926 const xmlChar *nsName) 4927 { 4928 xmlSchemaIDCPtr ret = NULL; 4929 4930 if ((name == NULL) || (schema == NULL)) 4931 return (NULL); 4932 if (schema != NULL) { 4933 WXS_FIND_GLOBAL_ITEM(idcDef) 4934 } 4935 exit: 4936 return (ret); 4937 } 4938 4939 /** 4940 * xmlSchemaGetNamedComponent: 4941 * @schema: the schema 4942 * @name: the name of the group 4943 * @ns: the target namespace of the group 4944 * 4945 * Lookup a group in the schema or imported schemas 4946 * 4947 * Returns the group definition or NULL if not found. 4948 */ 4949 static xmlSchemaBasicItemPtr 4950 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4951 xmlSchemaTypeType itemType, 4952 const xmlChar *name, 4953 const xmlChar *targetNs) 4954 { 4955 switch (itemType) { 4956 case XML_SCHEMA_TYPE_GROUP: 4957 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4958 name, targetNs)); 4959 case XML_SCHEMA_TYPE_ELEMENT: 4960 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4961 name, targetNs)); 4962 default: 4963 TODO 4964 return (NULL); 4965 } 4966 } 4967 4968 /************************************************************************ 4969 * * 4970 * Parsing functions * 4971 * * 4972 ************************************************************************/ 4973 4974 #define IS_BLANK_NODE(n) \ 4975 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 4976 4977 /** 4978 * xmlSchemaIsBlank: 4979 * @str: a string 4980 * @len: the length of the string or -1 4981 * 4982 * Check if a string is ignorable 4983 * 4984 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 4985 */ 4986 static int 4987 xmlSchemaIsBlank(xmlChar * str, int len) 4988 { 4989 if (str == NULL) 4990 return (1); 4991 if (len < 0) { 4992 while (*str != 0) { 4993 if (!(IS_BLANK_CH(*str))) 4994 return (0); 4995 str++; 4996 } 4997 } else while ((*str != 0) && (len != 0)) { 4998 if (!(IS_BLANK_CH(*str))) 4999 return (0); 5000 str++; 5001 len--; 5002 } 5003 5004 return (1); 5005 } 5006 5007 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5009 /* 5010 * xmlSchemaFindRedefCompInGraph: 5011 * ATTENTION TODO: This uses pointer comp. for strings. 5012 */ 5013 static xmlSchemaBasicItemPtr 5014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5015 xmlSchemaTypeType type, 5016 const xmlChar *name, 5017 const xmlChar *nsName) 5018 { 5019 xmlSchemaBasicItemPtr ret; 5020 int i; 5021 5022 if ((bucket == NULL) || (name == NULL)) 5023 return(NULL); 5024 if ((bucket->globals == NULL) || 5025 (bucket->globals->nbItems == 0)) 5026 goto subschemas; 5027 /* 5028 * Search in global components. 5029 */ 5030 for (i = 0; i < bucket->globals->nbItems; i++) { 5031 ret = bucket->globals->items[i]; 5032 if (ret->type == type) { 5033 switch (type) { 5034 case XML_SCHEMA_TYPE_COMPLEX: 5035 case XML_SCHEMA_TYPE_SIMPLE: 5036 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5037 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5038 nsName)) 5039 { 5040 return(ret); 5041 } 5042 break; 5043 case XML_SCHEMA_TYPE_GROUP: 5044 if ((WXS_COMP_NAME(ret, 5045 xmlSchemaModelGroupDefPtr) == name) && 5046 (WXS_COMP_TNS(ret, 5047 xmlSchemaModelGroupDefPtr) == nsName)) 5048 { 5049 return(ret); 5050 } 5051 break; 5052 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5053 if ((WXS_COMP_NAME(ret, 5054 xmlSchemaAttributeGroupPtr) == name) && 5055 (WXS_COMP_TNS(ret, 5056 xmlSchemaAttributeGroupPtr) == nsName)) 5057 { 5058 return(ret); 5059 } 5060 break; 5061 default: 5062 /* Should not be hit. */ 5063 return(NULL); 5064 } 5065 } 5066 } 5067 subschemas: 5068 /* 5069 * Process imported/included schemas. 5070 */ 5071 if (bucket->relations != NULL) { 5072 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5073 5074 /* 5075 * TODO: Marking the bucket will not avoid multiple searches 5076 * in the same schema, but avoids at least circularity. 5077 */ 5078 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5079 do { 5080 if ((rel->bucket != NULL) && 5081 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5082 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5083 type, name, nsName); 5084 if (ret != NULL) 5085 return(ret); 5086 } 5087 rel = rel->next; 5088 } while (rel != NULL); 5089 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5090 } 5091 return(NULL); 5092 } 5093 5094 /** 5095 * xmlSchemaAddNotation: 5096 * @ctxt: a schema parser context 5097 * @schema: the schema being built 5098 * @name: the item name 5099 * 5100 * Add an XML schema annotation declaration 5101 * *WARNING* this interface is highly subject to change 5102 * 5103 * Returns the new struture or NULL in case of error 5104 */ 5105 static xmlSchemaNotationPtr 5106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5107 const xmlChar *name, const xmlChar *nsName, 5108 xmlNodePtr node ATTRIBUTE_UNUSED) 5109 { 5110 xmlSchemaNotationPtr ret = NULL; 5111 5112 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5113 return (NULL); 5114 5115 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5116 if (ret == NULL) { 5117 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5118 return (NULL); 5119 } 5120 memset(ret, 0, sizeof(xmlSchemaNotation)); 5121 ret->type = XML_SCHEMA_TYPE_NOTATION; 5122 ret->name = name; 5123 ret->targetNamespace = nsName; 5124 /* TODO: do we need the node to be set? 5125 * ret->node = node;*/ 5126 WXS_ADD_GLOBAL(ctxt, ret); 5127 return (ret); 5128 } 5129 5130 /** 5131 * xmlSchemaAddAttribute: 5132 * @ctxt: a schema parser context 5133 * @schema: the schema being built 5134 * @name: the item name 5135 * @namespace: the namespace 5136 * 5137 * Add an XML schema Attrribute declaration 5138 * *WARNING* this interface is highly subject to change 5139 * 5140 * Returns the new struture or NULL in case of error 5141 */ 5142 static xmlSchemaAttributePtr 5143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5144 const xmlChar * name, const xmlChar * nsName, 5145 xmlNodePtr node, int topLevel) 5146 { 5147 xmlSchemaAttributePtr ret = NULL; 5148 5149 if ((ctxt == NULL) || (schema == NULL)) 5150 return (NULL); 5151 5152 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5153 if (ret == NULL) { 5154 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5155 return (NULL); 5156 } 5157 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5158 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5159 ret->node = node; 5160 ret->name = name; 5161 ret->targetNamespace = nsName; 5162 5163 if (topLevel) 5164 WXS_ADD_GLOBAL(ctxt, ret); 5165 else 5166 WXS_ADD_LOCAL(ctxt, ret); 5167 WXS_ADD_PENDING(ctxt, ret); 5168 return (ret); 5169 } 5170 5171 /** 5172 * xmlSchemaAddAttributeUse: 5173 * @ctxt: a schema parser context 5174 * @schema: the schema being built 5175 * @name: the item name 5176 * @namespace: the namespace 5177 * 5178 * Add an XML schema Attrribute declaration 5179 * *WARNING* this interface is highly subject to change 5180 * 5181 * Returns the new struture or NULL in case of error 5182 */ 5183 static xmlSchemaAttributeUsePtr 5184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5185 xmlNodePtr node) 5186 { 5187 xmlSchemaAttributeUsePtr ret = NULL; 5188 5189 if (pctxt == NULL) 5190 return (NULL); 5191 5192 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5193 if (ret == NULL) { 5194 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5195 return (NULL); 5196 } 5197 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5198 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5199 ret->node = node; 5200 5201 WXS_ADD_LOCAL(pctxt, ret); 5202 return (ret); 5203 } 5204 5205 /* 5206 * xmlSchemaAddRedef: 5207 * 5208 * Adds a redefinition information. This is used at a later stage to: 5209 * resolve references to the redefined components and to check constraints. 5210 */ 5211 static xmlSchemaRedefPtr 5212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5213 xmlSchemaBucketPtr targetBucket, 5214 void *item, 5215 const xmlChar *refName, 5216 const xmlChar *refTargetNs) 5217 { 5218 xmlSchemaRedefPtr ret; 5219 5220 ret = (xmlSchemaRedefPtr) 5221 xmlMalloc(sizeof(xmlSchemaRedef)); 5222 if (ret == NULL) { 5223 xmlSchemaPErrMemory(pctxt, 5224 "allocating redefinition info", NULL); 5225 return (NULL); 5226 } 5227 memset(ret, 0, sizeof(xmlSchemaRedef)); 5228 ret->item = item; 5229 ret->targetBucket = targetBucket; 5230 ret->refName = refName; 5231 ret->refTargetNs = refTargetNs; 5232 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5233 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5234 else 5235 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5236 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5237 5238 return (ret); 5239 } 5240 5241 /** 5242 * xmlSchemaAddAttributeGroupDefinition: 5243 * @ctxt: a schema parser context 5244 * @schema: the schema being built 5245 * @name: the item name 5246 * @nsName: the target namespace 5247 * @node: the corresponding node 5248 * 5249 * Add an XML schema Attrribute Group definition. 5250 * 5251 * Returns the new struture or NULL in case of error 5252 */ 5253 static xmlSchemaAttributeGroupPtr 5254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5255 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5256 const xmlChar *name, 5257 const xmlChar *nsName, 5258 xmlNodePtr node) 5259 { 5260 xmlSchemaAttributeGroupPtr ret = NULL; 5261 5262 if ((pctxt == NULL) || (name == NULL)) 5263 return (NULL); 5264 5265 ret = (xmlSchemaAttributeGroupPtr) 5266 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5267 if (ret == NULL) { 5268 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5269 return (NULL); 5270 } 5271 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5272 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5273 ret->name = name; 5274 ret->targetNamespace = nsName; 5275 ret->node = node; 5276 5277 /* TODO: Remove the flag. */ 5278 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5279 if (pctxt->isRedefine) { 5280 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5281 ret, name, nsName); 5282 if (pctxt->redef == NULL) { 5283 xmlFree(ret); 5284 return(NULL); 5285 } 5286 pctxt->redefCounter = 0; 5287 } 5288 WXS_ADD_GLOBAL(pctxt, ret); 5289 WXS_ADD_PENDING(pctxt, ret); 5290 return (ret); 5291 } 5292 5293 /** 5294 * xmlSchemaAddElement: 5295 * @ctxt: a schema parser context 5296 * @schema: the schema being built 5297 * @name: the type name 5298 * @namespace: the type namespace 5299 * 5300 * Add an XML schema Element declaration 5301 * *WARNING* this interface is highly subject to change 5302 * 5303 * Returns the new struture or NULL in case of error 5304 */ 5305 static xmlSchemaElementPtr 5306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5307 const xmlChar * name, const xmlChar * nsName, 5308 xmlNodePtr node, int topLevel) 5309 { 5310 xmlSchemaElementPtr ret = NULL; 5311 5312 if ((ctxt == NULL) || (name == NULL)) 5313 return (NULL); 5314 5315 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5316 if (ret == NULL) { 5317 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5318 return (NULL); 5319 } 5320 memset(ret, 0, sizeof(xmlSchemaElement)); 5321 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5322 ret->name = name; 5323 ret->targetNamespace = nsName; 5324 ret->node = node; 5325 5326 if (topLevel) 5327 WXS_ADD_GLOBAL(ctxt, ret); 5328 else 5329 WXS_ADD_LOCAL(ctxt, ret); 5330 WXS_ADD_PENDING(ctxt, ret); 5331 return (ret); 5332 } 5333 5334 /** 5335 * xmlSchemaAddType: 5336 * @ctxt: a schema parser context 5337 * @schema: the schema being built 5338 * @name: the item name 5339 * @namespace: the namespace 5340 * 5341 * Add an XML schema item 5342 * *WARNING* this interface is highly subject to change 5343 * 5344 * Returns the new struture or NULL in case of error 5345 */ 5346 static xmlSchemaTypePtr 5347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5348 xmlSchemaTypeType type, 5349 const xmlChar * name, const xmlChar * nsName, 5350 xmlNodePtr node, int topLevel) 5351 { 5352 xmlSchemaTypePtr ret = NULL; 5353 5354 if ((ctxt == NULL) || (schema == NULL)) 5355 return (NULL); 5356 5357 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5358 if (ret == NULL) { 5359 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5360 return (NULL); 5361 } 5362 memset(ret, 0, sizeof(xmlSchemaType)); 5363 ret->type = type; 5364 ret->name = name; 5365 ret->targetNamespace = nsName; 5366 ret->node = node; 5367 if (topLevel) { 5368 if (ctxt->isRedefine) { 5369 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5370 ret, name, nsName); 5371 if (ctxt->redef == NULL) { 5372 xmlFree(ret); 5373 return(NULL); 5374 } 5375 ctxt->redefCounter = 0; 5376 } 5377 WXS_ADD_GLOBAL(ctxt, ret); 5378 } else 5379 WXS_ADD_LOCAL(ctxt, ret); 5380 WXS_ADD_PENDING(ctxt, ret); 5381 return (ret); 5382 } 5383 5384 static xmlSchemaQNameRefPtr 5385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5386 xmlSchemaTypeType refType, 5387 const xmlChar *refName, 5388 const xmlChar *refNs) 5389 { 5390 xmlSchemaQNameRefPtr ret; 5391 5392 ret = (xmlSchemaQNameRefPtr) 5393 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5394 if (ret == NULL) { 5395 xmlSchemaPErrMemory(pctxt, 5396 "allocating QName reference item", NULL); 5397 return (NULL); 5398 } 5399 ret->node = NULL; 5400 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5401 ret->name = refName; 5402 ret->targetNamespace = refNs; 5403 ret->item = NULL; 5404 ret->itemType = refType; 5405 /* 5406 * Store the reference item in the schema. 5407 */ 5408 WXS_ADD_LOCAL(pctxt, ret); 5409 return (ret); 5410 } 5411 5412 static xmlSchemaAttributeUseProhibPtr 5413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5414 { 5415 xmlSchemaAttributeUseProhibPtr ret; 5416 5417 ret = (xmlSchemaAttributeUseProhibPtr) 5418 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5419 if (ret == NULL) { 5420 xmlSchemaPErrMemory(pctxt, 5421 "allocating attribute use prohibition", NULL); 5422 return (NULL); 5423 } 5424 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5425 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5426 WXS_ADD_LOCAL(pctxt, ret); 5427 return (ret); 5428 } 5429 5430 5431 /** 5432 * xmlSchemaAddModelGroup: 5433 * @ctxt: a schema parser context 5434 * @schema: the schema being built 5435 * @type: the "compositor" type of the model group 5436 * @node: the node in the schema doc 5437 * 5438 * Adds a schema model group 5439 * *WARNING* this interface is highly subject to change 5440 * 5441 * Returns the new struture or NULL in case of error 5442 */ 5443 static xmlSchemaModelGroupPtr 5444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5445 xmlSchemaPtr schema, 5446 xmlSchemaTypeType type, 5447 xmlNodePtr node) 5448 { 5449 xmlSchemaModelGroupPtr ret = NULL; 5450 5451 if ((ctxt == NULL) || (schema == NULL)) 5452 return (NULL); 5453 5454 ret = (xmlSchemaModelGroupPtr) 5455 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5456 if (ret == NULL) { 5457 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5458 NULL); 5459 return (NULL); 5460 } 5461 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5462 ret->type = type; 5463 ret->node = node; 5464 WXS_ADD_LOCAL(ctxt, ret); 5465 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5466 (type == XML_SCHEMA_TYPE_CHOICE)) 5467 WXS_ADD_PENDING(ctxt, ret); 5468 return (ret); 5469 } 5470 5471 5472 /** 5473 * xmlSchemaAddParticle: 5474 * @ctxt: a schema parser context 5475 * @schema: the schema being built 5476 * @node: the corresponding node in the schema doc 5477 * @min: the minOccurs 5478 * @max: the maxOccurs 5479 * 5480 * Adds an XML schema particle component. 5481 * *WARNING* this interface is highly subject to change 5482 * 5483 * Returns the new struture or NULL in case of error 5484 */ 5485 static xmlSchemaParticlePtr 5486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5487 xmlNodePtr node, int min, int max) 5488 { 5489 xmlSchemaParticlePtr ret = NULL; 5490 if (ctxt == NULL) 5491 return (NULL); 5492 5493 #ifdef DEBUG 5494 fprintf(stderr, "Adding particle component\n"); 5495 #endif 5496 ret = (xmlSchemaParticlePtr) 5497 xmlMalloc(sizeof(xmlSchemaParticle)); 5498 if (ret == NULL) { 5499 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5500 NULL); 5501 return (NULL); 5502 } 5503 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5504 ret->annot = NULL; 5505 ret->node = node; 5506 ret->minOccurs = min; 5507 ret->maxOccurs = max; 5508 ret->next = NULL; 5509 ret->children = NULL; 5510 5511 WXS_ADD_LOCAL(ctxt, ret); 5512 /* 5513 * Note that addition to pending components will be done locally 5514 * to the specific parsing function, since the most particles 5515 * need not to be fixed up (i.e. the reference to be resolved). 5516 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5517 */ 5518 return (ret); 5519 } 5520 5521 /** 5522 * xmlSchemaAddModelGroupDefinition: 5523 * @ctxt: a schema validation context 5524 * @schema: the schema being built 5525 * @name: the group name 5526 * 5527 * Add an XML schema Group definition 5528 * 5529 * Returns the new struture or NULL in case of error 5530 */ 5531 static xmlSchemaModelGroupDefPtr 5532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5533 xmlSchemaPtr schema, 5534 const xmlChar *name, 5535 const xmlChar *nsName, 5536 xmlNodePtr node) 5537 { 5538 xmlSchemaModelGroupDefPtr ret = NULL; 5539 5540 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5541 return (NULL); 5542 5543 ret = (xmlSchemaModelGroupDefPtr) 5544 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5545 if (ret == NULL) { 5546 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5547 return (NULL); 5548 } 5549 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5550 ret->name = name; 5551 ret->type = XML_SCHEMA_TYPE_GROUP; 5552 ret->node = node; 5553 ret->targetNamespace = nsName; 5554 5555 if (ctxt->isRedefine) { 5556 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5557 ret, name, nsName); 5558 if (ctxt->redef == NULL) { 5559 xmlFree(ret); 5560 return(NULL); 5561 } 5562 ctxt->redefCounter = 0; 5563 } 5564 WXS_ADD_GLOBAL(ctxt, ret); 5565 WXS_ADD_PENDING(ctxt, ret); 5566 return (ret); 5567 } 5568 5569 /** 5570 * xmlSchemaNewWildcardNs: 5571 * @ctxt: a schema validation context 5572 * 5573 * Creates a new wildcard namespace constraint. 5574 * 5575 * Returns the new struture or NULL in case of error 5576 */ 5577 static xmlSchemaWildcardNsPtr 5578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5579 { 5580 xmlSchemaWildcardNsPtr ret; 5581 5582 ret = (xmlSchemaWildcardNsPtr) 5583 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5584 if (ret == NULL) { 5585 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5586 return (NULL); 5587 } 5588 ret->value = NULL; 5589 ret->next = NULL; 5590 return (ret); 5591 } 5592 5593 static xmlSchemaIDCPtr 5594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5595 const xmlChar *name, const xmlChar *nsName, 5596 int category, xmlNodePtr node) 5597 { 5598 xmlSchemaIDCPtr ret = NULL; 5599 5600 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5601 return (NULL); 5602 5603 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5604 if (ret == NULL) { 5605 xmlSchemaPErrMemory(ctxt, 5606 "allocating an identity-constraint definition", NULL); 5607 return (NULL); 5608 } 5609 memset(ret, 0, sizeof(xmlSchemaIDC)); 5610 /* The target namespace of the parent element declaration. */ 5611 ret->targetNamespace = nsName; 5612 ret->name = name; 5613 ret->type = category; 5614 ret->node = node; 5615 5616 WXS_ADD_GLOBAL(ctxt, ret); 5617 /* 5618 * Only keyrefs need to be fixup up. 5619 */ 5620 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5621 WXS_ADD_PENDING(ctxt, ret); 5622 return (ret); 5623 } 5624 5625 /** 5626 * xmlSchemaAddWildcard: 5627 * @ctxt: a schema validation context 5628 * @schema: a schema 5629 * 5630 * Adds a wildcard. 5631 * It corresponds to a xsd:anyAttribute and xsd:any. 5632 * 5633 * Returns the new struture or NULL in case of error 5634 */ 5635 static xmlSchemaWildcardPtr 5636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5637 xmlSchemaTypeType type, xmlNodePtr node) 5638 { 5639 xmlSchemaWildcardPtr ret = NULL; 5640 5641 if ((ctxt == NULL) || (schema == NULL)) 5642 return (NULL); 5643 5644 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5645 if (ret == NULL) { 5646 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5647 return (NULL); 5648 } 5649 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5650 ret->type = type; 5651 ret->node = node; 5652 WXS_ADD_LOCAL(ctxt, ret); 5653 return (ret); 5654 } 5655 5656 static void 5657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5658 { 5659 if (group == NULL) 5660 return; 5661 if (group->members != NULL) 5662 xmlSchemaItemListFree(group->members); 5663 xmlFree(group); 5664 } 5665 5666 static xmlSchemaSubstGroupPtr 5667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5668 xmlSchemaElementPtr head) 5669 { 5670 xmlSchemaSubstGroupPtr ret; 5671 5672 /* Init subst group hash. */ 5673 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5674 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5675 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5676 return(NULL); 5677 } 5678 /* Create a new substitution group. */ 5679 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5680 if (ret == NULL) { 5681 xmlSchemaPErrMemory(NULL, 5682 "allocating a substitution group container", NULL); 5683 return(NULL); 5684 } 5685 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5686 ret->head = head; 5687 /* Create list of members. */ 5688 ret->members = xmlSchemaItemListCreate(); 5689 if (ret->members == NULL) { 5690 xmlSchemaSubstGroupFree(ret); 5691 return(NULL); 5692 } 5693 /* Add subst group to hash. */ 5694 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5695 head->name, head->targetNamespace, ret) != 0) { 5696 PERROR_INT("xmlSchemaSubstGroupAdd", 5697 "failed to add a new substitution container"); 5698 xmlSchemaSubstGroupFree(ret); 5699 return(NULL); 5700 } 5701 return(ret); 5702 } 5703 5704 static xmlSchemaSubstGroupPtr 5705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5706 xmlSchemaElementPtr head) 5707 { 5708 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5709 return(NULL); 5710 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5711 head->name, head->targetNamespace)); 5712 5713 } 5714 5715 /** 5716 * xmlSchemaAddElementSubstitutionMember: 5717 * @pctxt: a schema parser context 5718 * @head: the head of the substitution group 5719 * @member: the new member of the substitution group 5720 * 5721 * Allocate a new annotation structure. 5722 * 5723 * Returns the newly allocated structure or NULL in case or error 5724 */ 5725 static int 5726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5727 xmlSchemaElementPtr head, 5728 xmlSchemaElementPtr member) 5729 { 5730 xmlSchemaSubstGroupPtr substGroup = NULL; 5731 5732 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5733 return (-1); 5734 5735 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5736 if (substGroup == NULL) 5737 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5738 if (substGroup == NULL) 5739 return(-1); 5740 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5741 return(-1); 5742 return(0); 5743 } 5744 5745 /************************************************************************ 5746 * * 5747 * Utilities for parsing * 5748 * * 5749 ************************************************************************/ 5750 5751 /** 5752 * xmlSchemaPValAttrNodeQNameValue: 5753 * @ctxt: a schema parser context 5754 * @schema: the schema context 5755 * @ownerDes: the designation of the parent element 5756 * @ownerItem: the parent as a schema object 5757 * @value: the QName value 5758 * @local: the resulting local part if found, the attribute value otherwise 5759 * @uri: the resulting namespace URI if found 5760 * 5761 * Extracts the local name and the URI of a QName value and validates it. 5762 * This one is intended to be used on attribute values that 5763 * should resolve to schema components. 5764 * 5765 * Returns 0, in case the QName is valid, a positive error code 5766 * if not valid and -1 if an internal error occurs. 5767 */ 5768 static int 5769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5770 xmlSchemaPtr schema, 5771 xmlSchemaBasicItemPtr ownerItem, 5772 xmlAttrPtr attr, 5773 const xmlChar *value, 5774 const xmlChar **uri, 5775 const xmlChar **local) 5776 { 5777 const xmlChar *pref; 5778 xmlNsPtr ns; 5779 int len, ret; 5780 5781 *uri = NULL; 5782 *local = NULL; 5783 ret = xmlValidateQName(value, 1); 5784 if (ret > 0) { 5785 xmlSchemaPSimpleTypeErr(ctxt, 5786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5787 ownerItem, (xmlNodePtr) attr, 5788 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5789 NULL, value, NULL, NULL, NULL); 5790 *local = value; 5791 return (ctxt->err); 5792 } else if (ret < 0) 5793 return (-1); 5794 5795 if (!strchr((char *) value, ':')) { 5796 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5797 if (ns) 5798 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5799 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5800 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5801 * parser context. */ 5802 /* 5803 * This one takes care of included schemas with no 5804 * target namespace. 5805 */ 5806 *uri = ctxt->targetNamespace; 5807 } 5808 *local = xmlDictLookup(ctxt->dict, value, -1); 5809 return (0); 5810 } 5811 /* 5812 * At this point xmlSplitQName3 has to return a local name. 5813 */ 5814 *local = xmlSplitQName3(value, &len); 5815 *local = xmlDictLookup(ctxt->dict, *local, -1); 5816 pref = xmlDictLookup(ctxt->dict, value, len); 5817 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5818 if (ns == NULL) { 5819 xmlSchemaPSimpleTypeErr(ctxt, 5820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5821 ownerItem, (xmlNodePtr) attr, 5822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5823 "The value '%s' of simple type 'xs:QName' has no " 5824 "corresponding namespace declaration in scope", value, NULL); 5825 return (ctxt->err); 5826 } else { 5827 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5828 } 5829 return (0); 5830 } 5831 5832 /** 5833 * xmlSchemaPValAttrNodeQName: 5834 * @ctxt: a schema parser context 5835 * @schema: the schema context 5836 * @ownerDes: the designation of the owner element 5837 * @ownerItem: the owner as a schema object 5838 * @attr: the attribute node 5839 * @local: the resulting local part if found, the attribute value otherwise 5840 * @uri: the resulting namespace URI if found 5841 * 5842 * Extracts and validates the QName of an attribute value. 5843 * This one is intended to be used on attribute values that 5844 * should resolve to schema components. 5845 * 5846 * Returns 0, in case the QName is valid, a positive error code 5847 * if not valid and -1 if an internal error occurs. 5848 */ 5849 static int 5850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5851 xmlSchemaPtr schema, 5852 xmlSchemaBasicItemPtr ownerItem, 5853 xmlAttrPtr attr, 5854 const xmlChar **uri, 5855 const xmlChar **local) 5856 { 5857 const xmlChar *value; 5858 5859 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5860 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5861 ownerItem, attr, value, uri, local)); 5862 } 5863 5864 /** 5865 * xmlSchemaPValAttrQName: 5866 * @ctxt: a schema parser context 5867 * @schema: the schema context 5868 * @ownerDes: the designation of the parent element 5869 * @ownerItem: the owner as a schema object 5870 * @ownerElem: the parent node of the attribute 5871 * @name: the name of the attribute 5872 * @local: the resulting local part if found, the attribute value otherwise 5873 * @uri: the resulting namespace URI if found 5874 * 5875 * Extracts and validates the QName of an attribute value. 5876 * 5877 * Returns 0, in case the QName is valid, a positive error code 5878 * if not valid and -1 if an internal error occurs. 5879 */ 5880 static int 5881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5882 xmlSchemaPtr schema, 5883 xmlSchemaBasicItemPtr ownerItem, 5884 xmlNodePtr ownerElem, 5885 const char *name, 5886 const xmlChar **uri, 5887 const xmlChar **local) 5888 { 5889 xmlAttrPtr attr; 5890 5891 attr = xmlSchemaGetPropNode(ownerElem, name); 5892 if (attr == NULL) { 5893 *local = NULL; 5894 *uri = NULL; 5895 return (0); 5896 } 5897 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5898 ownerItem, attr, uri, local)); 5899 } 5900 5901 /** 5902 * xmlSchemaPValAttrID: 5903 * @ctxt: a schema parser context 5904 * @schema: the schema context 5905 * @ownerDes: the designation of the parent element 5906 * @ownerItem: the owner as a schema object 5907 * @ownerElem: the parent node of the attribute 5908 * @name: the name of the attribute 5909 * 5910 * Extracts and validates the ID of an attribute value. 5911 * 5912 * Returns 0, in case the ID is valid, a positive error code 5913 * if not valid and -1 if an internal error occurs. 5914 */ 5915 static int 5916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5917 { 5918 int ret; 5919 const xmlChar *value; 5920 5921 if (attr == NULL) 5922 return(0); 5923 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5924 ret = xmlValidateNCName(value, 1); 5925 if (ret == 0) { 5926 /* 5927 * NOTE: the IDness might have already be declared in the DTD 5928 */ 5929 if (attr->atype != XML_ATTRIBUTE_ID) { 5930 xmlIDPtr res; 5931 xmlChar *strip; 5932 5933 /* 5934 * TODO: Use xmlSchemaStrip here; it's not exported at this 5935 * moment. 5936 */ 5937 strip = xmlSchemaCollapseString(value); 5938 if (strip != NULL) { 5939 xmlFree((xmlChar *) value); 5940 value = strip; 5941 } 5942 res = xmlAddID(NULL, attr->doc, value, attr); 5943 if (res == NULL) { 5944 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5945 xmlSchemaPSimpleTypeErr(ctxt, 5946 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5947 NULL, (xmlNodePtr) attr, 5948 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5949 NULL, NULL, "Duplicate value '%s' of simple " 5950 "type 'xs:ID'", value, NULL); 5951 } else 5952 attr->atype = XML_ATTRIBUTE_ID; 5953 } 5954 } else if (ret > 0) { 5955 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5956 xmlSchemaPSimpleTypeErr(ctxt, 5957 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5958 NULL, (xmlNodePtr) attr, 5959 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5960 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5961 "not a valid 'xs:NCName'", 5962 value, NULL); 5963 } 5964 if (value != NULL) 5965 xmlFree((xmlChar *)value); 5966 5967 return (ret); 5968 } 5969 5970 static int 5971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 5972 xmlNodePtr ownerElem, 5973 const xmlChar *name) 5974 { 5975 xmlAttrPtr attr; 5976 5977 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 5978 if (attr == NULL) 5979 return(0); 5980 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 5981 5982 } 5983 5984 /** 5985 * xmlGetMaxOccurs: 5986 * @ctxt: a schema validation context 5987 * @node: a subtree containing XML Schema informations 5988 * 5989 * Get the maxOccurs property 5990 * 5991 * Returns the default if not found, or the value 5992 */ 5993 static int 5994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 5995 int min, int max, int def, const char *expected) 5996 { 5997 const xmlChar *val, *cur; 5998 int ret = 0; 5999 xmlAttrPtr attr; 6000 6001 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6002 if (attr == NULL) 6003 return (def); 6004 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6005 6006 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6007 if (max != UNBOUNDED) { 6008 xmlSchemaPSimpleTypeErr(ctxt, 6009 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6010 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6011 NULL, (xmlNodePtr) attr, NULL, expected, 6012 val, NULL, NULL, NULL); 6013 return (def); 6014 } else 6015 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6016 } 6017 6018 cur = val; 6019 while (IS_BLANK_CH(*cur)) 6020 cur++; 6021 if (*cur == 0) { 6022 xmlSchemaPSimpleTypeErr(ctxt, 6023 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6024 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6025 NULL, (xmlNodePtr) attr, NULL, expected, 6026 val, NULL, NULL, NULL); 6027 return (def); 6028 } 6029 while ((*cur >= '0') && (*cur <= '9')) { 6030 ret = ret * 10 + (*cur - '0'); 6031 cur++; 6032 } 6033 while (IS_BLANK_CH(*cur)) 6034 cur++; 6035 /* 6036 * TODO: Restrict the maximal value to Integer. 6037 */ 6038 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6039 xmlSchemaPSimpleTypeErr(ctxt, 6040 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6041 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6042 NULL, (xmlNodePtr) attr, NULL, expected, 6043 val, NULL, NULL, NULL); 6044 return (def); 6045 } 6046 return (ret); 6047 } 6048 6049 /** 6050 * xmlGetMinOccurs: 6051 * @ctxt: a schema validation context 6052 * @node: a subtree containing XML Schema informations 6053 * 6054 * Get the minOccurs property 6055 * 6056 * Returns the default if not found, or the value 6057 */ 6058 static int 6059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6060 int min, int max, int def, const char *expected) 6061 { 6062 const xmlChar *val, *cur; 6063 int ret = 0; 6064 xmlAttrPtr attr; 6065 6066 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6067 if (attr == NULL) 6068 return (def); 6069 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6070 cur = val; 6071 while (IS_BLANK_CH(*cur)) 6072 cur++; 6073 if (*cur == 0) { 6074 xmlSchemaPSimpleTypeErr(ctxt, 6075 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6076 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6077 NULL, (xmlNodePtr) attr, NULL, expected, 6078 val, NULL, NULL, NULL); 6079 return (def); 6080 } 6081 while ((*cur >= '0') && (*cur <= '9')) { 6082 ret = ret * 10 + (*cur - '0'); 6083 cur++; 6084 } 6085 while (IS_BLANK_CH(*cur)) 6086 cur++; 6087 /* 6088 * TODO: Restrict the maximal value to Integer. 6089 */ 6090 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6091 xmlSchemaPSimpleTypeErr(ctxt, 6092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6093 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6094 NULL, (xmlNodePtr) attr, NULL, expected, 6095 val, NULL, NULL, NULL); 6096 return (def); 6097 } 6098 return (ret); 6099 } 6100 6101 /** 6102 * xmlSchemaPGetBoolNodeValue: 6103 * @ctxt: a schema validation context 6104 * @ownerDes: owner designation 6105 * @ownerItem: the owner as a schema item 6106 * @node: the node holding the value 6107 * 6108 * Converts a boolean string value into 1 or 0. 6109 * 6110 * Returns 0 or 1. 6111 */ 6112 static int 6113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6114 xmlSchemaBasicItemPtr ownerItem, 6115 xmlNodePtr node) 6116 { 6117 xmlChar *value = NULL; 6118 int res = 0; 6119 6120 value = xmlNodeGetContent(node); 6121 /* 6122 * 3.2.2.1 Lexical representation 6123 * An instance of a datatype that is defined as boolean 6124 * can have the following legal literals {true, false, 1, 0}. 6125 */ 6126 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6127 res = 1; 6128 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6129 res = 0; 6130 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6131 res = 1; 6132 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6133 res = 0; 6134 else { 6135 xmlSchemaPSimpleTypeErr(ctxt, 6136 XML_SCHEMAP_INVALID_BOOLEAN, 6137 ownerItem, node, 6138 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6139 NULL, BAD_CAST value, 6140 NULL, NULL, NULL); 6141 } 6142 if (value != NULL) 6143 xmlFree(value); 6144 return (res); 6145 } 6146 6147 /** 6148 * xmlGetBooleanProp: 6149 * @ctxt: a schema validation context 6150 * @node: a subtree containing XML Schema informations 6151 * @name: the attribute name 6152 * @def: the default value 6153 * 6154 * Evaluate if a boolean property is set 6155 * 6156 * Returns the default if not found, 0 if found to be false, 6157 * 1 if found to be true 6158 */ 6159 static int 6160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6161 xmlNodePtr node, 6162 const char *name, int def) 6163 { 6164 const xmlChar *val; 6165 6166 val = xmlSchemaGetProp(ctxt, node, name); 6167 if (val == NULL) 6168 return (def); 6169 /* 6170 * 3.2.2.1 Lexical representation 6171 * An instance of a datatype that is defined as boolean 6172 * can have the following legal literals {true, false, 1, 0}. 6173 */ 6174 if (xmlStrEqual(val, BAD_CAST "true")) 6175 def = 1; 6176 else if (xmlStrEqual(val, BAD_CAST "false")) 6177 def = 0; 6178 else if (xmlStrEqual(val, BAD_CAST "1")) 6179 def = 1; 6180 else if (xmlStrEqual(val, BAD_CAST "0")) 6181 def = 0; 6182 else { 6183 xmlSchemaPSimpleTypeErr(ctxt, 6184 XML_SCHEMAP_INVALID_BOOLEAN, 6185 NULL, 6186 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6187 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6188 NULL, val, NULL, NULL, NULL); 6189 } 6190 return (def); 6191 } 6192 6193 /************************************************************************ 6194 * * 6195 * Shema extraction from an Infoset * 6196 * * 6197 ************************************************************************/ 6198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6199 ctxt, xmlSchemaPtr schema, 6200 xmlNodePtr node, 6201 int topLevel); 6202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6203 ctxt, 6204 xmlSchemaPtr schema, 6205 xmlNodePtr node, 6206 int topLevel); 6207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6208 ctxt, 6209 xmlSchemaPtr schema, 6210 xmlNodePtr node, 6211 xmlSchemaTypeType parentType); 6212 static xmlSchemaBasicItemPtr 6213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6214 xmlSchemaPtr schema, 6215 xmlNodePtr node, 6216 xmlSchemaItemListPtr uses, 6217 int parentType); 6218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6219 xmlSchemaPtr schema, 6220 xmlNodePtr node); 6221 static xmlSchemaWildcardPtr 6222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6223 xmlSchemaPtr schema, xmlNodePtr node); 6224 6225 /** 6226 * xmlSchemaPValAttrNodeValue: 6227 * 6228 * @ctxt: a schema parser context 6229 * @ownerDes: the designation of the parent element 6230 * @ownerItem: the schema object owner if existent 6231 * @attr: the schema attribute node being validated 6232 * @value: the value 6233 * @type: the built-in type to be validated against 6234 * 6235 * Validates a value against the given built-in type. 6236 * This one is intended to be used internally for validation 6237 * of schema attribute values during parsing of the schema. 6238 * 6239 * Returns 0 if the value is valid, a positive error code 6240 * number otherwise and -1 in case of an internal or API error. 6241 */ 6242 static int 6243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6244 xmlSchemaBasicItemPtr ownerItem, 6245 xmlAttrPtr attr, 6246 const xmlChar *value, 6247 xmlSchemaTypePtr type) 6248 { 6249 6250 int ret = 0; 6251 6252 /* 6253 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6254 * one is really meant to be used internally, so better not. 6255 */ 6256 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6257 return (-1); 6258 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6259 PERROR_INT("xmlSchemaPValAttrNodeValue", 6260 "the given type is not a built-in type"); 6261 return (-1); 6262 } 6263 switch (type->builtInType) { 6264 case XML_SCHEMAS_NCNAME: 6265 case XML_SCHEMAS_QNAME: 6266 case XML_SCHEMAS_ANYURI: 6267 case XML_SCHEMAS_TOKEN: 6268 case XML_SCHEMAS_LANGUAGE: 6269 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6270 (xmlNodePtr) attr); 6271 break; 6272 default: { 6273 PERROR_INT("xmlSchemaPValAttrNodeValue", 6274 "validation using the given type is not supported while " 6275 "parsing a schema"); 6276 return (-1); 6277 } 6278 } 6279 /* 6280 * TODO: Should we use the S4S error codes instead? 6281 */ 6282 if (ret < 0) { 6283 PERROR_INT("xmlSchemaPValAttrNodeValue", 6284 "failed to validate a schema attribute value"); 6285 return (-1); 6286 } else if (ret > 0) { 6287 if (WXS_IS_LIST(type)) 6288 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6289 else 6290 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6291 xmlSchemaPSimpleTypeErr(pctxt, 6292 ret, ownerItem, (xmlNodePtr) attr, 6293 type, NULL, value, NULL, NULL, NULL); 6294 } 6295 return (ret); 6296 } 6297 6298 /** 6299 * xmlSchemaPValAttrNode: 6300 * 6301 * @ctxt: a schema parser context 6302 * @ownerDes: the designation of the parent element 6303 * @ownerItem: the schema object owner if existent 6304 * @attr: the schema attribute node being validated 6305 * @type: the built-in type to be validated against 6306 * @value: the resulting value if any 6307 * 6308 * Extracts and validates a value against the given built-in type. 6309 * This one is intended to be used internally for validation 6310 * of schema attribute values during parsing of the schema. 6311 * 6312 * Returns 0 if the value is valid, a positive error code 6313 * number otherwise and -1 in case of an internal or API error. 6314 */ 6315 static int 6316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6317 xmlSchemaBasicItemPtr ownerItem, 6318 xmlAttrPtr attr, 6319 xmlSchemaTypePtr type, 6320 const xmlChar **value) 6321 { 6322 const xmlChar *val; 6323 6324 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6325 return (-1); 6326 6327 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6328 if (value != NULL) 6329 *value = val; 6330 6331 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6332 val, type)); 6333 } 6334 6335 /** 6336 * xmlSchemaPValAttr: 6337 * 6338 * @ctxt: a schema parser context 6339 * @node: the element node of the attribute 6340 * @ownerDes: the designation of the parent element 6341 * @ownerItem: the schema object owner if existent 6342 * @ownerElem: the owner element node 6343 * @name: the name of the schema attribute node 6344 * @type: the built-in type to be validated against 6345 * @value: the resulting value if any 6346 * 6347 * Extracts and validates a value against the given built-in type. 6348 * This one is intended to be used internally for validation 6349 * of schema attribute values during parsing of the schema. 6350 * 6351 * Returns 0 if the value is valid, a positive error code 6352 * number otherwise and -1 in case of an internal or API error. 6353 */ 6354 static int 6355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6356 xmlSchemaBasicItemPtr ownerItem, 6357 xmlNodePtr ownerElem, 6358 const char *name, 6359 xmlSchemaTypePtr type, 6360 const xmlChar **value) 6361 { 6362 xmlAttrPtr attr; 6363 6364 if ((ctxt == NULL) || (type == NULL)) { 6365 if (value != NULL) 6366 *value = NULL; 6367 return (-1); 6368 } 6369 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6370 if (value != NULL) 6371 *value = NULL; 6372 xmlSchemaPErr(ctxt, ownerElem, 6373 XML_SCHEMAP_INTERNAL, 6374 "Internal error: xmlSchemaPValAttr, the given " 6375 "type '%s' is not a built-in type.\n", 6376 type->name, NULL); 6377 return (-1); 6378 } 6379 attr = xmlSchemaGetPropNode(ownerElem, name); 6380 if (attr == NULL) { 6381 if (value != NULL) 6382 *value = NULL; 6383 return (0); 6384 } 6385 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6386 type, value)); 6387 } 6388 6389 static int 6390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6391 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6392 xmlNodePtr node, 6393 xmlAttrPtr attr, 6394 const xmlChar *namespaceName) 6395 { 6396 /* TODO: Pointer comparison instead? */ 6397 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6398 return (0); 6399 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6400 return (0); 6401 /* 6402 * Check if the referenced namespace was <import>ed. 6403 */ 6404 if (WXS_BUCKET(pctxt)->relations != NULL) { 6405 xmlSchemaSchemaRelationPtr rel; 6406 6407 rel = WXS_BUCKET(pctxt)->relations; 6408 do { 6409 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6410 xmlStrEqual(namespaceName, rel->importNamespace)) 6411 return (0); 6412 rel = rel->next; 6413 } while (rel != NULL); 6414 } 6415 /* 6416 * No matching <import>ed namespace found. 6417 */ 6418 { 6419 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6420 6421 if (namespaceName == NULL) 6422 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6423 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6424 "References from this schema to components in no " 6425 "namespace are not allowed, since not indicated by an " 6426 "import statement", NULL, NULL); 6427 else 6428 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6429 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6430 "References from this schema to components in the " 6431 "namespace '%s' are not allowed, since not indicated by an " 6432 "import statement", namespaceName, NULL); 6433 } 6434 return (XML_SCHEMAP_SRC_RESOLVE); 6435 } 6436 6437 /** 6438 * xmlSchemaParseLocalAttributes: 6439 * @ctxt: a schema validation context 6440 * @schema: the schema being built 6441 * @node: a subtree containing XML Schema informations 6442 * @type: the hosting type where the attributes will be anchored 6443 * 6444 * Parses attribute uses and attribute declarations and 6445 * attribute group references. 6446 */ 6447 static int 6448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6449 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6450 int parentType, int *hasRefs) 6451 { 6452 void *item; 6453 6454 while ((IS_SCHEMA((*child), "attribute")) || 6455 (IS_SCHEMA((*child), "attributeGroup"))) { 6456 if (IS_SCHEMA((*child), "attribute")) { 6457 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6458 *list, parentType); 6459 } else { 6460 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6461 if ((item != NULL) && (hasRefs != NULL)) 6462 *hasRefs = 1; 6463 } 6464 if (item != NULL) { 6465 if (*list == NULL) { 6466 /* TODO: Customize grow factor. */ 6467 *list = xmlSchemaItemListCreate(); 6468 if (*list == NULL) 6469 return(-1); 6470 } 6471 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6472 return(-1); 6473 } 6474 *child = (*child)->next; 6475 } 6476 return (0); 6477 } 6478 6479 /** 6480 * xmlSchemaParseAnnotation: 6481 * @ctxt: a schema validation context 6482 * @schema: the schema being built 6483 * @node: a subtree containing XML Schema informations 6484 * 6485 * parse a XML schema Attrribute declaration 6486 * *WARNING* this interface is highly subject to change 6487 * 6488 * Returns -1 in case of error, 0 if the declaration is improper and 6489 * 1 in case of success. 6490 */ 6491 static xmlSchemaAnnotPtr 6492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6493 { 6494 xmlSchemaAnnotPtr ret; 6495 xmlNodePtr child = NULL; 6496 xmlAttrPtr attr; 6497 int barked = 0; 6498 6499 /* 6500 * INFO: S4S completed. 6501 */ 6502 /* 6503 * id = ID 6504 * {any attributes with non-schema namespace . . .}> 6505 * Content: (appinfo | documentation)* 6506 */ 6507 if ((ctxt == NULL) || (node == NULL)) 6508 return (NULL); 6509 if (needed) 6510 ret = xmlSchemaNewAnnot(ctxt, node); 6511 else 6512 ret = NULL; 6513 attr = node->properties; 6514 while (attr != NULL) { 6515 if (((attr->ns == NULL) && 6516 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6517 ((attr->ns != NULL) && 6518 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6519 6520 xmlSchemaPIllegalAttrErr(ctxt, 6521 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6522 } 6523 attr = attr->next; 6524 } 6525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6526 /* 6527 * And now for the children... 6528 */ 6529 child = node->children; 6530 while (child != NULL) { 6531 if (IS_SCHEMA(child, "appinfo")) { 6532 /* TODO: make available the content of "appinfo". */ 6533 /* 6534 * source = anyURI 6535 * {any attributes with non-schema namespace . . .}> 6536 * Content: ({any})* 6537 */ 6538 attr = child->properties; 6539 while (attr != NULL) { 6540 if (((attr->ns == NULL) && 6541 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6542 ((attr->ns != NULL) && 6543 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6544 6545 xmlSchemaPIllegalAttrErr(ctxt, 6546 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6547 } 6548 attr = attr->next; 6549 } 6550 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6551 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6552 child = child->next; 6553 } else if (IS_SCHEMA(child, "documentation")) { 6554 /* TODO: make available the content of "documentation". */ 6555 /* 6556 * source = anyURI 6557 * {any attributes with non-schema namespace . . .}> 6558 * Content: ({any})* 6559 */ 6560 attr = child->properties; 6561 while (attr != NULL) { 6562 if (attr->ns == NULL) { 6563 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6564 xmlSchemaPIllegalAttrErr(ctxt, 6565 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6566 } 6567 } else { 6568 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6569 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6570 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6571 6572 xmlSchemaPIllegalAttrErr(ctxt, 6573 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6574 } 6575 } 6576 attr = attr->next; 6577 } 6578 /* 6579 * Attribute "xml:lang". 6580 */ 6581 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6582 if (attr != NULL) 6583 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6584 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6585 child = child->next; 6586 } else { 6587 if (!barked) 6588 xmlSchemaPContentErr(ctxt, 6589 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6590 NULL, node, child, NULL, "(appinfo | documentation)*"); 6591 barked = 1; 6592 child = child->next; 6593 } 6594 } 6595 6596 return (ret); 6597 } 6598 6599 /** 6600 * xmlSchemaParseFacet: 6601 * @ctxt: a schema validation context 6602 * @schema: the schema being built 6603 * @node: a subtree containing XML Schema informations 6604 * 6605 * parse a XML schema Facet declaration 6606 * *WARNING* this interface is highly subject to change 6607 * 6608 * Returns the new type structure or NULL in case of error 6609 */ 6610 static xmlSchemaFacetPtr 6611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6612 xmlNodePtr node) 6613 { 6614 xmlSchemaFacetPtr facet; 6615 xmlNodePtr child = NULL; 6616 const xmlChar *value; 6617 6618 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6619 return (NULL); 6620 6621 facet = xmlSchemaNewFacet(); 6622 if (facet == NULL) { 6623 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6624 return (NULL); 6625 } 6626 facet->node = node; 6627 value = xmlSchemaGetProp(ctxt, node, "value"); 6628 if (value == NULL) { 6629 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6630 "Facet %s has no value\n", node->name, NULL); 6631 xmlSchemaFreeFacet(facet); 6632 return (NULL); 6633 } 6634 if (IS_SCHEMA(node, "minInclusive")) { 6635 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6636 } else if (IS_SCHEMA(node, "minExclusive")) { 6637 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6638 } else if (IS_SCHEMA(node, "maxInclusive")) { 6639 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6640 } else if (IS_SCHEMA(node, "maxExclusive")) { 6641 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6642 } else if (IS_SCHEMA(node, "totalDigits")) { 6643 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6644 } else if (IS_SCHEMA(node, "fractionDigits")) { 6645 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6646 } else if (IS_SCHEMA(node, "pattern")) { 6647 facet->type = XML_SCHEMA_FACET_PATTERN; 6648 } else if (IS_SCHEMA(node, "enumeration")) { 6649 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6650 } else if (IS_SCHEMA(node, "whiteSpace")) { 6651 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6652 } else if (IS_SCHEMA(node, "length")) { 6653 facet->type = XML_SCHEMA_FACET_LENGTH; 6654 } else if (IS_SCHEMA(node, "maxLength")) { 6655 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6656 } else if (IS_SCHEMA(node, "minLength")) { 6657 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6658 } else { 6659 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6660 "Unknown facet type %s\n", node->name, NULL); 6661 xmlSchemaFreeFacet(facet); 6662 return (NULL); 6663 } 6664 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6665 facet->value = value; 6666 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6667 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6668 const xmlChar *fixed; 6669 6670 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6671 if (fixed != NULL) { 6672 if (xmlStrEqual(fixed, BAD_CAST "true")) 6673 facet->fixed = 1; 6674 } 6675 } 6676 child = node->children; 6677 6678 if (IS_SCHEMA(child, "annotation")) { 6679 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6680 child = child->next; 6681 } 6682 if (child != NULL) { 6683 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6684 "Facet %s has unexpected child content\n", 6685 node->name, NULL); 6686 } 6687 return (facet); 6688 } 6689 6690 /** 6691 * xmlSchemaParseWildcardNs: 6692 * @ctxt: a schema parser context 6693 * @wildc: the wildcard, already created 6694 * @node: a subtree containing XML Schema informations 6695 * 6696 * Parses the attribute "processContents" and "namespace" 6697 * of a xsd:anyAttribute and xsd:any. 6698 * *WARNING* this interface is highly subject to change 6699 * 6700 * Returns 0 if everything goes fine, a positive error code 6701 * if something is not valid and -1 if an internal error occurs. 6702 */ 6703 static int 6704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6705 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6706 xmlSchemaWildcardPtr wildc, 6707 xmlNodePtr node) 6708 { 6709 const xmlChar *pc, *ns, *dictnsItem; 6710 int ret = 0; 6711 xmlChar *nsItem; 6712 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6713 xmlAttrPtr attr; 6714 6715 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6716 if ((pc == NULL) 6717 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6718 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6719 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6720 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6721 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6722 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6723 } else { 6724 xmlSchemaPSimpleTypeErr(ctxt, 6725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6726 NULL, node, 6727 NULL, "(strict | skip | lax)", pc, 6728 NULL, NULL, NULL); 6729 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6730 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6731 } 6732 /* 6733 * Build the namespace constraints. 6734 */ 6735 attr = xmlSchemaGetPropNode(node, "namespace"); 6736 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6737 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6738 wildc->any = 1; 6739 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6740 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6741 if (wildc->negNsSet == NULL) { 6742 return (-1); 6743 } 6744 wildc->negNsSet->value = ctxt->targetNamespace; 6745 } else { 6746 const xmlChar *end, *cur; 6747 6748 cur = ns; 6749 do { 6750 while (IS_BLANK_CH(*cur)) 6751 cur++; 6752 end = cur; 6753 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6754 end++; 6755 if (end == cur) 6756 break; 6757 nsItem = xmlStrndup(cur, end - cur); 6758 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6759 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6760 xmlSchemaPSimpleTypeErr(ctxt, 6761 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6762 NULL, (xmlNodePtr) attr, 6763 NULL, 6764 "((##any | ##other) | List of (xs:anyURI | " 6765 "(##targetNamespace | ##local)))", 6766 nsItem, NULL, NULL, NULL); 6767 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6768 } else { 6769 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6770 dictnsItem = ctxt->targetNamespace; 6771 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6772 dictnsItem = NULL; 6773 } else { 6774 /* 6775 * Validate the item (anyURI). 6776 */ 6777 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6778 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6779 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6780 } 6781 /* 6782 * Avoid dublicate namespaces. 6783 */ 6784 tmp = wildc->nsSet; 6785 while (tmp != NULL) { 6786 if (dictnsItem == tmp->value) 6787 break; 6788 tmp = tmp->next; 6789 } 6790 if (tmp == NULL) { 6791 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6792 if (tmp == NULL) { 6793 xmlFree(nsItem); 6794 return (-1); 6795 } 6796 tmp->value = dictnsItem; 6797 tmp->next = NULL; 6798 if (wildc->nsSet == NULL) 6799 wildc->nsSet = tmp; 6800 else if (lastNs != NULL) 6801 lastNs->next = tmp; 6802 lastNs = tmp; 6803 } 6804 6805 } 6806 xmlFree(nsItem); 6807 cur = end; 6808 } while (*cur != 0); 6809 } 6810 return (ret); 6811 } 6812 6813 static int 6814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6815 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6816 xmlNodePtr node, 6817 int minOccurs, 6818 int maxOccurs) { 6819 6820 if ((maxOccurs == 0) && ( minOccurs == 0)) 6821 return (0); 6822 if (maxOccurs != UNBOUNDED) { 6823 /* 6824 * TODO: Maybe we should better not create the particle, 6825 * if min/max is invalid, since it could confuse the build of the 6826 * content model. 6827 */ 6828 /* 6829 * 3.9.6 Schema Component Constraint: Particle Correct 6830 * 6831 */ 6832 if (maxOccurs < 1) { 6833 /* 6834 * 2.2 {max occurs} must be greater than or equal to 1. 6835 */ 6836 xmlSchemaPCustomAttrErr(ctxt, 6837 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6838 NULL, NULL, 6839 xmlSchemaGetPropNode(node, "maxOccurs"), 6840 "The value must be greater than or equal to 1"); 6841 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6842 } else if (minOccurs > maxOccurs) { 6843 /* 6844 * 2.1 {min occurs} must not be greater than {max occurs}. 6845 */ 6846 xmlSchemaPCustomAttrErr(ctxt, 6847 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6848 NULL, NULL, 6849 xmlSchemaGetPropNode(node, "minOccurs"), 6850 "The value must not be greater than the value of 'maxOccurs'"); 6851 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6852 } 6853 } 6854 return (0); 6855 } 6856 6857 /** 6858 * xmlSchemaParseAny: 6859 * @ctxt: a schema validation context 6860 * @schema: the schema being built 6861 * @node: a subtree containing XML Schema informations 6862 * 6863 * Parsea a XML schema <any> element. A particle and wildcard 6864 * will be created (except if minOccurs==maxOccurs==0, in this case 6865 * nothing will be created). 6866 * *WARNING* this interface is highly subject to change 6867 * 6868 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6869 */ 6870 static xmlSchemaParticlePtr 6871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6872 xmlNodePtr node) 6873 { 6874 xmlSchemaParticlePtr particle; 6875 xmlNodePtr child = NULL; 6876 xmlSchemaWildcardPtr wild; 6877 int min, max; 6878 xmlAttrPtr attr; 6879 xmlSchemaAnnotPtr annot = NULL; 6880 6881 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6882 return (NULL); 6883 /* 6884 * Check for illegal attributes. 6885 */ 6886 attr = node->properties; 6887 while (attr != NULL) { 6888 if (attr->ns == NULL) { 6889 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6890 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6891 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6892 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6893 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6894 xmlSchemaPIllegalAttrErr(ctxt, 6895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6896 } 6897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6898 xmlSchemaPIllegalAttrErr(ctxt, 6899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6900 } 6901 attr = attr->next; 6902 } 6903 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6904 /* 6905 * minOccurs/maxOccurs. 6906 */ 6907 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6908 "(xs:nonNegativeInteger | unbounded)"); 6909 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6910 "xs:nonNegativeInteger"); 6911 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6912 /* 6913 * Create & parse the wildcard. 6914 */ 6915 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6916 if (wild == NULL) 6917 return (NULL); 6918 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6919 /* 6920 * And now for the children... 6921 */ 6922 child = node->children; 6923 if (IS_SCHEMA(child, "annotation")) { 6924 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6925 child = child->next; 6926 } 6927 if (child != NULL) { 6928 xmlSchemaPContentErr(ctxt, 6929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6930 NULL, node, child, 6931 NULL, "(annotation?)"); 6932 } 6933 /* 6934 * No component if minOccurs==maxOccurs==0. 6935 */ 6936 if ((min == 0) && (max == 0)) { 6937 /* Don't free the wildcard, since it's already on the list. */ 6938 return (NULL); 6939 } 6940 /* 6941 * Create the particle. 6942 */ 6943 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6944 if (particle == NULL) 6945 return (NULL); 6946 particle->annot = annot; 6947 particle->children = (xmlSchemaTreeItemPtr) wild; 6948 6949 return (particle); 6950 } 6951 6952 /** 6953 * xmlSchemaParseNotation: 6954 * @ctxt: a schema validation context 6955 * @schema: the schema being built 6956 * @node: a subtree containing XML Schema informations 6957 * 6958 * parse a XML schema Notation declaration 6959 * 6960 * Returns the new structure or NULL in case of error 6961 */ 6962 static xmlSchemaNotationPtr 6963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6964 xmlNodePtr node) 6965 { 6966 const xmlChar *name; 6967 xmlSchemaNotationPtr ret; 6968 xmlNodePtr child = NULL; 6969 6970 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6971 return (NULL); 6972 name = xmlSchemaGetProp(ctxt, node, "name"); 6973 if (name == NULL) { 6974 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 6975 "Notation has no name\n", NULL, NULL); 6976 return (NULL); 6977 } 6978 ret = xmlSchemaAddNotation(ctxt, schema, name, 6979 ctxt->targetNamespace, node); 6980 if (ret == NULL) 6981 return (NULL); 6982 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6983 6984 child = node->children; 6985 if (IS_SCHEMA(child, "annotation")) { 6986 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6987 child = child->next; 6988 } 6989 if (child != NULL) { 6990 xmlSchemaPContentErr(ctxt, 6991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6992 NULL, node, child, 6993 NULL, "(annotation?)"); 6994 } 6995 6996 return (ret); 6997 } 6998 6999 /** 7000 * xmlSchemaParseAnyAttribute: 7001 * @ctxt: a schema validation context 7002 * @schema: the schema being built 7003 * @node: a subtree containing XML Schema informations 7004 * 7005 * parse a XML schema AnyAttrribute declaration 7006 * *WARNING* this interface is highly subject to change 7007 * 7008 * Returns a wildcard or NULL. 7009 */ 7010 static xmlSchemaWildcardPtr 7011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7012 xmlSchemaPtr schema, xmlNodePtr node) 7013 { 7014 xmlSchemaWildcardPtr ret; 7015 xmlNodePtr child = NULL; 7016 xmlAttrPtr attr; 7017 7018 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7019 return (NULL); 7020 7021 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7022 node); 7023 if (ret == NULL) { 7024 return (NULL); 7025 } 7026 /* 7027 * Check for illegal attributes. 7028 */ 7029 attr = node->properties; 7030 while (attr != NULL) { 7031 if (attr->ns == NULL) { 7032 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7033 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7034 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7035 xmlSchemaPIllegalAttrErr(ctxt, 7036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7037 } 7038 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7039 xmlSchemaPIllegalAttrErr(ctxt, 7040 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7041 } 7042 attr = attr->next; 7043 } 7044 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7045 /* 7046 * Parse the namespace list. 7047 */ 7048 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7049 return (NULL); 7050 /* 7051 * And now for the children... 7052 */ 7053 child = node->children; 7054 if (IS_SCHEMA(child, "annotation")) { 7055 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7056 child = child->next; 7057 } 7058 if (child != NULL) { 7059 xmlSchemaPContentErr(ctxt, 7060 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7061 NULL, node, child, 7062 NULL, "(annotation?)"); 7063 } 7064 7065 return (ret); 7066 } 7067 7068 7069 /** 7070 * xmlSchemaParseAttribute: 7071 * @ctxt: a schema validation context 7072 * @schema: the schema being built 7073 * @node: a subtree containing XML Schema informations 7074 * 7075 * parse a XML schema Attrribute declaration 7076 * *WARNING* this interface is highly subject to change 7077 * 7078 * Returns the attribute declaration. 7079 */ 7080 static xmlSchemaBasicItemPtr 7081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7082 xmlSchemaPtr schema, 7083 xmlNodePtr node, 7084 xmlSchemaItemListPtr uses, 7085 int parentType) 7086 { 7087 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7088 xmlSchemaAttributeUsePtr use = NULL; 7089 xmlNodePtr child = NULL; 7090 xmlAttrPtr attr; 7091 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7092 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7093 int nberrors, hasForm = 0, defValueType = 0; 7094 7095 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7096 #define WXS_ATTR_DEF_VAL_FIXED 2 7097 7098 /* 7099 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7100 */ 7101 7102 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7103 return (NULL); 7104 attr = xmlSchemaGetPropNode(node, "ref"); 7105 if (attr != NULL) { 7106 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7107 NULL, attr, &tmpNs, &tmpName) != 0) { 7108 return (NULL); 7109 } 7110 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7111 return(NULL); 7112 isRef = 1; 7113 } 7114 nberrors = pctxt->nberrors; 7115 /* 7116 * Check for illegal attributes. 7117 */ 7118 attr = node->properties; 7119 while (attr != NULL) { 7120 if (attr->ns == NULL) { 7121 if (isRef) { 7122 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7123 xmlSchemaPValAttrNodeID(pctxt, attr); 7124 goto attr_next; 7125 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7126 goto attr_next; 7127 } 7128 } else { 7129 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7130 goto attr_next; 7131 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7132 xmlSchemaPValAttrNodeID(pctxt, attr); 7133 goto attr_next; 7134 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7135 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7136 attr, &tmpNs, &tmpName); 7137 goto attr_next; 7138 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7139 /* 7140 * Evaluate the target namespace 7141 */ 7142 hasForm = 1; 7143 attrValue = xmlSchemaGetNodeContent(pctxt, 7144 (xmlNodePtr) attr); 7145 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7146 ns = pctxt->targetNamespace; 7147 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7148 { 7149 xmlSchemaPSimpleTypeErr(pctxt, 7150 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7151 NULL, (xmlNodePtr) attr, 7152 NULL, "(qualified | unqualified)", 7153 attrValue, NULL, NULL, NULL); 7154 } 7155 goto attr_next; 7156 } 7157 } 7158 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7159 7160 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7161 /* TODO: Maybe we need to normalize the value beforehand. */ 7162 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7163 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7164 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7165 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7166 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7167 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7168 else { 7169 xmlSchemaPSimpleTypeErr(pctxt, 7170 XML_SCHEMAP_INVALID_ATTR_USE, 7171 NULL, (xmlNodePtr) attr, 7172 NULL, "(optional | prohibited | required)", 7173 attrValue, NULL, NULL, NULL); 7174 } 7175 goto attr_next; 7176 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7177 /* 7178 * 3.2.3 : 1 7179 * default and fixed must not both be present. 7180 */ 7181 if (defValue) { 7182 xmlSchemaPMutualExclAttrErr(pctxt, 7183 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7184 NULL, attr, "default", "fixed"); 7185 } else { 7186 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7187 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7188 } 7189 goto attr_next; 7190 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7191 /* 7192 * 3.2.3 : 1 7193 * default and fixed must not both be present. 7194 */ 7195 if (defValue) { 7196 xmlSchemaPMutualExclAttrErr(pctxt, 7197 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7198 NULL, attr, "default", "fixed"); 7199 } else { 7200 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7201 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7202 } 7203 goto attr_next; 7204 } 7205 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7206 goto attr_next; 7207 7208 xmlSchemaPIllegalAttrErr(pctxt, 7209 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7210 7211 attr_next: 7212 attr = attr->next; 7213 } 7214 /* 7215 * 3.2.3 : 2 7216 * If default and use are both present, use must have 7217 * the actual value optional. 7218 */ 7219 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7220 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7221 xmlSchemaPSimpleTypeErr(pctxt, 7222 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7223 NULL, node, NULL, 7224 "(optional | prohibited | required)", NULL, 7225 "The value of the attribute 'use' must be 'optional' " 7226 "if the attribute 'default' is present", 7227 NULL, NULL); 7228 } 7229 /* 7230 * We want correct attributes. 7231 */ 7232 if (nberrors != pctxt->nberrors) 7233 return(NULL); 7234 if (! isRef) { 7235 xmlSchemaAttributePtr attrDecl; 7236 7237 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7238 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7239 ns = pctxt->targetNamespace; 7240 /* 7241 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7242 * TODO: Move this to the component layer. 7243 */ 7244 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7246 XML_SCHEMAP_NO_XSI, 7247 node, NULL, 7248 "The target namespace must not match '%s'", 7249 xmlSchemaInstanceNs, NULL); 7250 } 7251 attr = xmlSchemaGetPropNode(node, "name"); 7252 if (attr == NULL) { 7253 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7254 NULL, node, "name", NULL); 7255 return (NULL); 7256 } 7257 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7259 return (NULL); 7260 } 7261 /* 7262 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7263 * TODO: Move this to the component layer. 7264 */ 7265 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7266 xmlSchemaPSimpleTypeErr(pctxt, 7267 XML_SCHEMAP_NO_XMLNS, 7268 NULL, (xmlNodePtr) attr, 7269 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7270 "The value of the attribute must not match 'xmlns'", 7271 NULL, NULL); 7272 return (NULL); 7273 } 7274 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7275 goto check_children; 7276 /* 7277 * Create the attribute use component. 7278 */ 7279 use = xmlSchemaAddAttributeUse(pctxt, node); 7280 if (use == NULL) 7281 return(NULL); 7282 use->occurs = occurs; 7283 /* 7284 * Create the attribute declaration. 7285 */ 7286 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7287 if (attrDecl == NULL) 7288 return (NULL); 7289 if (tmpName != NULL) { 7290 attrDecl->typeName = tmpName; 7291 attrDecl->typeNs = tmpNs; 7292 } 7293 use->attrDecl = attrDecl; 7294 /* 7295 * Value constraint. 7296 */ 7297 if (defValue != NULL) { 7298 attrDecl->defValue = defValue; 7299 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7300 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7301 } 7302 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7303 xmlSchemaQNameRefPtr ref; 7304 7305 /* 7306 * Create the attribute use component. 7307 */ 7308 use = xmlSchemaAddAttributeUse(pctxt, node); 7309 if (use == NULL) 7310 return(NULL); 7311 /* 7312 * We need to resolve the reference at later stage. 7313 */ 7314 WXS_ADD_PENDING(pctxt, use); 7315 use->occurs = occurs; 7316 /* 7317 * Create a QName reference to the attribute declaration. 7318 */ 7319 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7320 tmpName, tmpNs); 7321 if (ref == NULL) 7322 return(NULL); 7323 /* 7324 * Assign the reference. This will be substituted for the 7325 * referenced attribute declaration when the QName is resolved. 7326 */ 7327 use->attrDecl = WXS_ATTR_CAST ref; 7328 /* 7329 * Value constraint. 7330 */ 7331 if (defValue != NULL) 7332 use->defValue = defValue; 7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7334 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7335 } 7336 7337 check_children: 7338 /* 7339 * And now for the children... 7340 */ 7341 child = node->children; 7342 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7343 xmlSchemaAttributeUseProhibPtr prohib; 7344 7345 if (IS_SCHEMA(child, "annotation")) { 7346 xmlSchemaParseAnnotation(pctxt, child, 0); 7347 child = child->next; 7348 } 7349 if (child != NULL) { 7350 xmlSchemaPContentErr(pctxt, 7351 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7352 NULL, node, child, NULL, 7353 "(annotation?)"); 7354 } 7355 /* 7356 * Check for pointlessness of attribute prohibitions. 7357 */ 7358 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7359 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7360 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7361 node, NULL, 7362 "Skipping attribute use prohibition, since it is " 7363 "pointless inside an <attributeGroup>", 7364 NULL, NULL, NULL); 7365 return(NULL); 7366 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7367 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7368 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7369 node, NULL, 7370 "Skipping attribute use prohibition, since it is " 7371 "pointless when extending a type", 7372 NULL, NULL, NULL); 7373 return(NULL); 7374 } 7375 if (! isRef) { 7376 tmpName = name; 7377 tmpNs = ns; 7378 } 7379 /* 7380 * Check for duplicate attribute prohibitions. 7381 */ 7382 if (uses) { 7383 int i; 7384 7385 for (i = 0; i < uses->nbItems; i++) { 7386 use = uses->items[i]; 7387 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7388 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7389 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7390 { 7391 xmlChar *str = NULL; 7392 7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7395 node, NULL, 7396 "Skipping duplicate attribute use prohibition '%s'", 7397 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7398 NULL, NULL); 7399 FREE_AND_NULL(str) 7400 return(NULL); 7401 } 7402 } 7403 } 7404 /* 7405 * Create the attribute prohibition helper component. 7406 */ 7407 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7408 if (prohib == NULL) 7409 return(NULL); 7410 prohib->node = node; 7411 prohib->name = tmpName; 7412 prohib->targetNamespace = tmpNs; 7413 if (isRef) { 7414 /* 7415 * We need at least to resolve to the attribute declaration. 7416 */ 7417 WXS_ADD_PENDING(pctxt, prohib); 7418 } 7419 return(WXS_BASIC_CAST prohib); 7420 } else { 7421 if (IS_SCHEMA(child, "annotation")) { 7422 /* 7423 * TODO: Should this go into the attr decl? 7424 */ 7425 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7426 child = child->next; 7427 } 7428 if (isRef) { 7429 if (child != NULL) { 7430 if (IS_SCHEMA(child, "simpleType")) 7431 /* 7432 * 3.2.3 : 3.2 7433 * If ref is present, then all of <simpleType>, 7434 * form and type must be absent. 7435 */ 7436 xmlSchemaPContentErr(pctxt, 7437 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7438 NULL, node, child, NULL, 7439 "(annotation?)"); 7440 else 7441 xmlSchemaPContentErr(pctxt, 7442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7443 NULL, node, child, NULL, 7444 "(annotation?)"); 7445 } 7446 } else { 7447 if (IS_SCHEMA(child, "simpleType")) { 7448 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7449 /* 7450 * 3.2.3 : 4 7451 * type and <simpleType> must not both be present. 7452 */ 7453 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7454 NULL, node, child, 7455 "The attribute 'type' and the <simpleType> child " 7456 "are mutually exclusive", NULL); 7457 } else 7458 WXS_ATTRUSE_TYPEDEF(use) = 7459 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7460 child = child->next; 7461 } 7462 if (child != NULL) 7463 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7464 NULL, node, child, NULL, 7465 "(annotation?, simpleType?)"); 7466 } 7467 } 7468 return (WXS_BASIC_CAST use); 7469 } 7470 7471 7472 static xmlSchemaAttributePtr 7473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7474 xmlSchemaPtr schema, 7475 xmlNodePtr node) 7476 { 7477 const xmlChar *attrValue; 7478 xmlSchemaAttributePtr ret; 7479 xmlNodePtr child = NULL; 7480 xmlAttrPtr attr; 7481 7482 /* 7483 * Note that the w3c spec assumes the schema to be validated with schema 7484 * for schemas beforehand. 7485 * 7486 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7487 */ 7488 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7489 return (NULL); 7490 /* 7491 * 3.2.3 : 3.1 7492 * One of ref or name must be present, but not both 7493 */ 7494 attr = xmlSchemaGetPropNode(node, "name"); 7495 if (attr == NULL) { 7496 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7497 NULL, node, "name", NULL); 7498 return (NULL); 7499 } 7500 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7502 return (NULL); 7503 } 7504 /* 7505 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7506 * TODO: Move this to the component layer. 7507 */ 7508 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7509 xmlSchemaPSimpleTypeErr(pctxt, 7510 XML_SCHEMAP_NO_XMLNS, 7511 NULL, (xmlNodePtr) attr, 7512 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7513 "The value of the attribute must not match 'xmlns'", 7514 NULL, NULL); 7515 return (NULL); 7516 } 7517 /* 7518 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7519 * TODO: Move this to the component layer. 7520 * Or better leave it here and add it to the component layer 7521 * if we have a schema construction API. 7522 */ 7523 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7524 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7525 XML_SCHEMAP_NO_XSI, node, NULL, 7526 "The target namespace must not match '%s'", 7527 xmlSchemaInstanceNs, NULL); 7528 } 7529 7530 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7531 pctxt->targetNamespace, node, 1); 7532 if (ret == NULL) 7533 return (NULL); 7534 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7535 7536 /* 7537 * Check for illegal attributes. 7538 */ 7539 attr = node->properties; 7540 while (attr != NULL) { 7541 if (attr->ns == NULL) { 7542 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7543 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7544 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7545 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7546 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7547 { 7548 xmlSchemaPIllegalAttrErr(pctxt, 7549 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7550 } 7551 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7552 xmlSchemaPIllegalAttrErr(pctxt, 7553 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7554 } 7555 attr = attr->next; 7556 } 7557 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7558 node, "type", &ret->typeNs, &ret->typeName); 7559 7560 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7561 /* 7562 * Attribute "fixed". 7563 */ 7564 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7565 if (ret->defValue != NULL) 7566 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7567 /* 7568 * Attribute "default". 7569 */ 7570 attr = xmlSchemaGetPropNode(node, "default"); 7571 if (attr != NULL) { 7572 /* 7573 * 3.2.3 : 1 7574 * default and fixed must not both be present. 7575 */ 7576 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7577 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7578 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7579 } else 7580 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7581 } 7582 /* 7583 * And now for the children... 7584 */ 7585 child = node->children; 7586 if (IS_SCHEMA(child, "annotation")) { 7587 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7588 child = child->next; 7589 } 7590 if (IS_SCHEMA(child, "simpleType")) { 7591 if (ret->typeName != NULL) { 7592 /* 7593 * 3.2.3 : 4 7594 * type and <simpleType> must not both be present. 7595 */ 7596 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7597 NULL, node, child, 7598 "The attribute 'type' and the <simpleType> child " 7599 "are mutually exclusive", NULL); 7600 } else 7601 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7602 child = child->next; 7603 } 7604 if (child != NULL) 7605 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7606 NULL, node, child, NULL, 7607 "(annotation?, simpleType?)"); 7608 7609 return (ret); 7610 } 7611 7612 /** 7613 * xmlSchemaParseAttributeGroupRef: 7614 * @ctxt: a schema validation context 7615 * @schema: the schema being built 7616 * @node: a subtree containing XML Schema informations 7617 * 7618 * Parse an attribute group definition reference. 7619 * Note that a reference to an attribute group does not 7620 * correspond to any component at all. 7621 * *WARNING* this interface is highly subject to change 7622 * 7623 * Returns the attribute group or NULL in case of error. 7624 */ 7625 static xmlSchemaQNameRefPtr 7626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7627 xmlSchemaPtr schema, 7628 xmlNodePtr node) 7629 { 7630 xmlSchemaQNameRefPtr ret; 7631 xmlNodePtr child = NULL; 7632 xmlAttrPtr attr; 7633 const xmlChar *refNs = NULL, *ref = NULL; 7634 7635 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7636 return (NULL); 7637 7638 attr = xmlSchemaGetPropNode(node, "ref"); 7639 if (attr == NULL) { 7640 xmlSchemaPMissingAttrErr(pctxt, 7641 XML_SCHEMAP_S4S_ATTR_MISSING, 7642 NULL, node, "ref", NULL); 7643 return (NULL); 7644 } 7645 xmlSchemaPValAttrNodeQName(pctxt, schema, 7646 NULL, attr, &refNs, &ref); 7647 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7648 return(NULL); 7649 7650 /* 7651 * Check for illegal attributes. 7652 */ 7653 attr = node->properties; 7654 while (attr != NULL) { 7655 if (attr->ns == NULL) { 7656 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7657 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7658 { 7659 xmlSchemaPIllegalAttrErr(pctxt, 7660 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7661 } 7662 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7663 xmlSchemaPIllegalAttrErr(pctxt, 7664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7665 } 7666 attr = attr->next; 7667 } 7668 /* Attribute ID */ 7669 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7670 7671 /* 7672 * And now for the children... 7673 */ 7674 child = node->children; 7675 if (IS_SCHEMA(child, "annotation")) { 7676 /* 7677 * TODO: We do not have a place to store the annotation, do we? 7678 */ 7679 xmlSchemaParseAnnotation(pctxt, child, 0); 7680 child = child->next; 7681 } 7682 if (child != NULL) { 7683 xmlSchemaPContentErr(pctxt, 7684 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7685 NULL, node, child, NULL, 7686 "(annotation?)"); 7687 } 7688 7689 /* 7690 * Handle attribute group redefinitions. 7691 */ 7692 if (pctxt->isRedefine && pctxt->redef && 7693 (pctxt->redef->item->type == 7694 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7695 (ref == pctxt->redef->refName) && 7696 (refNs == pctxt->redef->refTargetNs)) 7697 { 7698 /* 7699 * SPEC src-redefine: 7700 * (7.1) "If it has an <attributeGroup> among its contents 7701 * the actual value of whose ref [attribute] is the same 7702 * as the actual value of its own name attribute plus 7703 * target namespace, then it must have exactly one such group." 7704 */ 7705 if (pctxt->redefCounter != 0) { 7706 xmlChar *str = NULL; 7707 7708 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7709 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7710 "The redefining attribute group definition " 7711 "'%s' must not contain more than one " 7712 "reference to the redefined definition", 7713 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7714 FREE_AND_NULL(str); 7715 return(NULL); 7716 } 7717 pctxt->redefCounter++; 7718 /* 7719 * URGENT TODO: How to ensure that the reference will not be 7720 * handled by the normal component resolution mechanism? 7721 */ 7722 ret = xmlSchemaNewQNameRef(pctxt, 7723 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7724 if (ret == NULL) 7725 return(NULL); 7726 ret->node = node; 7727 pctxt->redef->reference = WXS_BASIC_CAST ret; 7728 } else { 7729 /* 7730 * Create a QName-reference helper component. We will substitute this 7731 * component for the attribute uses of the referenced attribute group 7732 * definition. 7733 */ 7734 ret = xmlSchemaNewQNameRef(pctxt, 7735 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7736 if (ret == NULL) 7737 return(NULL); 7738 ret->node = node; 7739 /* Add to pending items, to be able to resolve the reference. */ 7740 WXS_ADD_PENDING(pctxt, ret); 7741 } 7742 return (ret); 7743 } 7744 7745 /** 7746 * xmlSchemaParseAttributeGroupDefinition: 7747 * @pctxt: a schema validation context 7748 * @schema: the schema being built 7749 * @node: a subtree containing XML Schema informations 7750 * 7751 * parse a XML schema Attribute Group declaration 7752 * *WARNING* this interface is highly subject to change 7753 * 7754 * Returns the attribute group definition or NULL in case of error. 7755 */ 7756 static xmlSchemaAttributeGroupPtr 7757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7758 xmlSchemaPtr schema, 7759 xmlNodePtr node) 7760 { 7761 const xmlChar *name; 7762 xmlSchemaAttributeGroupPtr ret; 7763 xmlNodePtr child = NULL; 7764 xmlAttrPtr attr; 7765 int hasRefs = 0; 7766 7767 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7768 return (NULL); 7769 7770 attr = xmlSchemaGetPropNode(node, "name"); 7771 if (attr == NULL) { 7772 xmlSchemaPMissingAttrErr(pctxt, 7773 XML_SCHEMAP_S4S_ATTR_MISSING, 7774 NULL, node, "name", NULL); 7775 return (NULL); 7776 } 7777 /* 7778 * The name is crucial, exit if invalid. 7779 */ 7780 if (xmlSchemaPValAttrNode(pctxt, 7781 NULL, attr, 7782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7783 return (NULL); 7784 } 7785 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7786 name, pctxt->targetNamespace, node); 7787 if (ret == NULL) 7788 return (NULL); 7789 /* 7790 * Check for illegal attributes. 7791 */ 7792 attr = node->properties; 7793 while (attr != NULL) { 7794 if (attr->ns == NULL) { 7795 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7796 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7797 { 7798 xmlSchemaPIllegalAttrErr(pctxt, 7799 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7800 } 7801 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7802 xmlSchemaPIllegalAttrErr(pctxt, 7803 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7804 } 7805 attr = attr->next; 7806 } 7807 /* Attribute ID */ 7808 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7809 /* 7810 * And now for the children... 7811 */ 7812 child = node->children; 7813 if (IS_SCHEMA(child, "annotation")) { 7814 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7815 child = child->next; 7816 } 7817 /* 7818 * Parse contained attribute decls/refs. 7819 */ 7820 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7821 (xmlSchemaItemListPtr *) &(ret->attrUses), 7822 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7823 return(NULL); 7824 if (hasRefs) 7825 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7826 /* 7827 * Parse the attribute wildcard. 7828 */ 7829 if (IS_SCHEMA(child, "anyAttribute")) { 7830 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7831 schema, child); 7832 child = child->next; 7833 } 7834 if (child != NULL) { 7835 xmlSchemaPContentErr(pctxt, 7836 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7837 NULL, node, child, NULL, 7838 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7839 } 7840 return (ret); 7841 } 7842 7843 /** 7844 * xmlSchemaPValAttrFormDefault: 7845 * @value: the value 7846 * @flags: the flags to be modified 7847 * @flagQualified: the specific flag for "qualified" 7848 * 7849 * Returns 0 if the value is valid, 1 otherwise. 7850 */ 7851 static int 7852 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7853 int *flags, 7854 int flagQualified) 7855 { 7856 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7857 if ((*flags & flagQualified) == 0) 7858 *flags |= flagQualified; 7859 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7860 return (1); 7861 7862 return (0); 7863 } 7864 7865 /** 7866 * xmlSchemaPValAttrBlockFinal: 7867 * @value: the value 7868 * @flags: the flags to be modified 7869 * @flagAll: the specific flag for "#all" 7870 * @flagExtension: the specific flag for "extension" 7871 * @flagRestriction: the specific flag for "restriction" 7872 * @flagSubstitution: the specific flag for "substitution" 7873 * @flagList: the specific flag for "list" 7874 * @flagUnion: the specific flag for "union" 7875 * 7876 * Validates the value of the attribute "final" and "block". The value 7877 * is converted into the specified flag values and returned in @flags. 7878 * 7879 * Returns 0 if the value is valid, 1 otherwise. 7880 */ 7881 7882 static int 7883 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7884 int *flags, 7885 int flagAll, 7886 int flagExtension, 7887 int flagRestriction, 7888 int flagSubstitution, 7889 int flagList, 7890 int flagUnion) 7891 { 7892 int ret = 0; 7893 7894 /* 7895 * TODO: This does not check for dublicate entries. 7896 */ 7897 if ((flags == NULL) || (value == NULL)) 7898 return (-1); 7899 if (value[0] == 0) 7900 return (0); 7901 if (xmlStrEqual(value, BAD_CAST "#all")) { 7902 if (flagAll != -1) 7903 *flags |= flagAll; 7904 else { 7905 if (flagExtension != -1) 7906 *flags |= flagExtension; 7907 if (flagRestriction != -1) 7908 *flags |= flagRestriction; 7909 if (flagSubstitution != -1) 7910 *flags |= flagSubstitution; 7911 if (flagList != -1) 7912 *flags |= flagList; 7913 if (flagUnion != -1) 7914 *flags |= flagUnion; 7915 } 7916 } else { 7917 const xmlChar *end, *cur = value; 7918 xmlChar *item; 7919 7920 do { 7921 while (IS_BLANK_CH(*cur)) 7922 cur++; 7923 end = cur; 7924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7925 end++; 7926 if (end == cur) 7927 break; 7928 item = xmlStrndup(cur, end - cur); 7929 if (xmlStrEqual(item, BAD_CAST "extension")) { 7930 if (flagExtension != -1) { 7931 if ((*flags & flagExtension) == 0) 7932 *flags |= flagExtension; 7933 } else 7934 ret = 1; 7935 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7936 if (flagRestriction != -1) { 7937 if ((*flags & flagRestriction) == 0) 7938 *flags |= flagRestriction; 7939 } else 7940 ret = 1; 7941 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7942 if (flagSubstitution != -1) { 7943 if ((*flags & flagSubstitution) == 0) 7944 *flags |= flagSubstitution; 7945 } else 7946 ret = 1; 7947 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7948 if (flagList != -1) { 7949 if ((*flags & flagList) == 0) 7950 *flags |= flagList; 7951 } else 7952 ret = 1; 7953 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7954 if (flagUnion != -1) { 7955 if ((*flags & flagUnion) == 0) 7956 *flags |= flagUnion; 7957 } else 7958 ret = 1; 7959 } else 7960 ret = 1; 7961 if (item != NULL) 7962 xmlFree(item); 7963 cur = end; 7964 } while ((ret == 0) && (*cur != 0)); 7965 } 7966 7967 return (ret); 7968 } 7969 7970 static int 7971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 7972 xmlSchemaIDCPtr idc, 7973 xmlSchemaIDCSelectPtr selector, 7974 xmlAttrPtr attr, 7975 int isField) 7976 { 7977 xmlNodePtr node; 7978 7979 /* 7980 * c-selector-xpath: 7981 * Schema Component Constraint: Selector Value OK 7982 * 7983 * TODO: 1 The {selector} must be a valid XPath expression, as defined 7984 * in [XPath]. 7985 */ 7986 if (selector == NULL) { 7987 xmlSchemaPErr(ctxt, idc->node, 7988 XML_SCHEMAP_INTERNAL, 7989 "Internal error: xmlSchemaCheckCSelectorXPath, " 7990 "the selector is not specified.\n", NULL, NULL); 7991 return (-1); 7992 } 7993 if (attr == NULL) 7994 node = idc->node; 7995 else 7996 node = (xmlNodePtr) attr; 7997 if (selector->xpath == NULL) { 7998 xmlSchemaPCustomErr(ctxt, 7999 /* TODO: Adjust error code. */ 8000 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8001 NULL, node, 8002 "The XPath expression of the selector is not valid", NULL); 8003 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8004 } else { 8005 const xmlChar **nsArray = NULL; 8006 xmlNsPtr *nsList = NULL; 8007 /* 8008 * Compile the XPath expression. 8009 */ 8010 /* 8011 * TODO: We need the array of in-scope namespaces for compilation. 8012 * TODO: Call xmlPatterncompile with different options for selector/ 8013 * field. 8014 */ 8015 if (attr == NULL) 8016 nsList = NULL; 8017 else 8018 nsList = xmlGetNsList(attr->doc, attr->parent); 8019 /* 8020 * Build an array of prefixes and namespaces. 8021 */ 8022 if (nsList != NULL) { 8023 int i, count = 0; 8024 8025 for (i = 0; nsList[i] != NULL; i++) 8026 count++; 8027 8028 nsArray = (const xmlChar **) xmlMalloc( 8029 (count * 2 + 1) * sizeof(const xmlChar *)); 8030 if (nsArray == NULL) { 8031 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8032 NULL); 8033 xmlFree(nsList); 8034 return (-1); 8035 } 8036 for (i = 0; i < count; i++) { 8037 nsArray[2 * i] = nsList[i]->href; 8038 nsArray[2 * i + 1] = nsList[i]->prefix; 8039 } 8040 nsArray[count * 2] = NULL; 8041 xmlFree(nsList); 8042 } 8043 /* 8044 * TODO: Differentiate between "selector" and "field". 8045 */ 8046 if (isField) 8047 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8048 NULL, XML_PATTERN_XSFIELD, nsArray); 8049 else 8050 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8051 NULL, XML_PATTERN_XSSEL, nsArray); 8052 if (nsArray != NULL) 8053 xmlFree((xmlChar **) nsArray); 8054 8055 if (selector->xpathComp == NULL) { 8056 xmlSchemaPCustomErr(ctxt, 8057 /* TODO: Adjust error code? */ 8058 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8059 NULL, node, 8060 "The XPath expression '%s' could not be " 8061 "compiled", selector->xpath); 8062 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8063 } 8064 } 8065 return (0); 8066 } 8067 8068 #define ADD_ANNOTATION(annot) \ 8069 xmlSchemaAnnotPtr cur = item->annot; \ 8070 if (item->annot == NULL) { \ 8071 item->annot = annot; \ 8072 return (annot); \ 8073 } \ 8074 cur = item->annot; \ 8075 if (cur->next != NULL) { \ 8076 cur = cur->next; \ 8077 } \ 8078 cur->next = annot; 8079 8080 /** 8081 * xmlSchemaAssignAnnotation: 8082 * @item: the schema component 8083 * @annot: the annotation 8084 * 8085 * Adds the annotation to the given schema component. 8086 * 8087 * Returns the given annotaion. 8088 */ 8089 static xmlSchemaAnnotPtr 8090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8091 xmlSchemaAnnotPtr annot) 8092 { 8093 if ((annItem == NULL) || (annot == NULL)) 8094 return (NULL); 8095 switch (annItem->type) { 8096 case XML_SCHEMA_TYPE_ELEMENT: { 8097 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8098 ADD_ANNOTATION(annot) 8099 } 8100 break; 8101 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8102 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8103 ADD_ANNOTATION(annot) 8104 } 8105 break; 8106 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8107 case XML_SCHEMA_TYPE_ANY: { 8108 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8109 ADD_ANNOTATION(annot) 8110 } 8111 break; 8112 case XML_SCHEMA_TYPE_PARTICLE: 8113 case XML_SCHEMA_TYPE_IDC_KEY: 8114 case XML_SCHEMA_TYPE_IDC_KEYREF: 8115 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8116 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8117 ADD_ANNOTATION(annot) 8118 } 8119 break; 8120 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8121 xmlSchemaAttributeGroupPtr item = 8122 (xmlSchemaAttributeGroupPtr) annItem; 8123 ADD_ANNOTATION(annot) 8124 } 8125 break; 8126 case XML_SCHEMA_TYPE_NOTATION: { 8127 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8128 ADD_ANNOTATION(annot) 8129 } 8130 break; 8131 case XML_SCHEMA_FACET_MININCLUSIVE: 8132 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8133 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8134 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8135 case XML_SCHEMA_FACET_TOTALDIGITS: 8136 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8137 case XML_SCHEMA_FACET_PATTERN: 8138 case XML_SCHEMA_FACET_ENUMERATION: 8139 case XML_SCHEMA_FACET_WHITESPACE: 8140 case XML_SCHEMA_FACET_LENGTH: 8141 case XML_SCHEMA_FACET_MAXLENGTH: 8142 case XML_SCHEMA_FACET_MINLENGTH: { 8143 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8144 ADD_ANNOTATION(annot) 8145 } 8146 break; 8147 case XML_SCHEMA_TYPE_SIMPLE: 8148 case XML_SCHEMA_TYPE_COMPLEX: { 8149 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8150 ADD_ANNOTATION(annot) 8151 } 8152 break; 8153 case XML_SCHEMA_TYPE_GROUP: { 8154 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8155 ADD_ANNOTATION(annot) 8156 } 8157 break; 8158 case XML_SCHEMA_TYPE_SEQUENCE: 8159 case XML_SCHEMA_TYPE_CHOICE: 8160 case XML_SCHEMA_TYPE_ALL: { 8161 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8162 ADD_ANNOTATION(annot) 8163 } 8164 break; 8165 default: 8166 xmlSchemaPCustomErr(NULL, 8167 XML_SCHEMAP_INTERNAL, 8168 NULL, NULL, 8169 "Internal error: xmlSchemaAddAnnotation, " 8170 "The item is not a annotated schema component", NULL); 8171 break; 8172 } 8173 return (annot); 8174 } 8175 8176 /** 8177 * xmlSchemaParseIDCSelectorAndField: 8178 * @ctxt: a schema validation context 8179 * @schema: the schema being built 8180 * @node: a subtree containing XML Schema informations 8181 * 8182 * Parses a XML Schema identity-contraint definition's 8183 * <selector> and <field> elements. 8184 * 8185 * Returns the parsed identity-constraint definition. 8186 */ 8187 static xmlSchemaIDCSelectPtr 8188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8189 xmlSchemaIDCPtr idc, 8190 xmlNodePtr node, 8191 int isField) 8192 { 8193 xmlSchemaIDCSelectPtr item; 8194 xmlNodePtr child = NULL; 8195 xmlAttrPtr attr; 8196 8197 /* 8198 * Check for illegal attributes. 8199 */ 8200 attr = node->properties; 8201 while (attr != NULL) { 8202 if (attr->ns == NULL) { 8203 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8204 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8205 xmlSchemaPIllegalAttrErr(ctxt, 8206 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8207 } 8208 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8209 xmlSchemaPIllegalAttrErr(ctxt, 8210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8211 } 8212 attr = attr->next; 8213 } 8214 /* 8215 * Create the item. 8216 */ 8217 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8218 if (item == NULL) { 8219 xmlSchemaPErrMemory(ctxt, 8220 "allocating a 'selector' of an identity-constraint definition", 8221 NULL); 8222 return (NULL); 8223 } 8224 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8225 /* 8226 * Attribute "xpath" (mandatory). 8227 */ 8228 attr = xmlSchemaGetPropNode(node, "xpath"); 8229 if (attr == NULL) { 8230 xmlSchemaPMissingAttrErr(ctxt, 8231 XML_SCHEMAP_S4S_ATTR_MISSING, 8232 NULL, node, 8233 "name", NULL); 8234 } else { 8235 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8236 /* 8237 * URGENT TODO: "field"s have an other syntax than "selector"s. 8238 */ 8239 8240 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8241 isField) == -1) { 8242 xmlSchemaPErr(ctxt, 8243 (xmlNodePtr) attr, 8244 XML_SCHEMAP_INTERNAL, 8245 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8246 "validating the XPath expression of a IDC selector.\n", 8247 NULL, NULL); 8248 } 8249 8250 } 8251 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8252 /* 8253 * And now for the children... 8254 */ 8255 child = node->children; 8256 if (IS_SCHEMA(child, "annotation")) { 8257 /* 8258 * Add the annotation to the parent IDC. 8259 */ 8260 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8261 xmlSchemaParseAnnotation(ctxt, child, 1)); 8262 child = child->next; 8263 } 8264 if (child != NULL) { 8265 xmlSchemaPContentErr(ctxt, 8266 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8267 NULL, node, child, 8268 NULL, "(annotation?)"); 8269 } 8270 8271 return (item); 8272 } 8273 8274 /** 8275 * xmlSchemaParseIDC: 8276 * @ctxt: a schema validation context 8277 * @schema: the schema being built 8278 * @node: a subtree containing XML Schema informations 8279 * 8280 * Parses a XML Schema identity-contraint definition. 8281 * 8282 * Returns the parsed identity-constraint definition. 8283 */ 8284 static xmlSchemaIDCPtr 8285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8286 xmlSchemaPtr schema, 8287 xmlNodePtr node, 8288 xmlSchemaTypeType idcCategory, 8289 const xmlChar *targetNamespace) 8290 { 8291 xmlSchemaIDCPtr item = NULL; 8292 xmlNodePtr child = NULL; 8293 xmlAttrPtr attr; 8294 const xmlChar *name = NULL; 8295 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8296 8297 /* 8298 * Check for illegal attributes. 8299 */ 8300 attr = node->properties; 8301 while (attr != NULL) { 8302 if (attr->ns == NULL) { 8303 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8304 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8305 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8306 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8307 xmlSchemaPIllegalAttrErr(ctxt, 8308 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8309 } 8310 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8311 xmlSchemaPIllegalAttrErr(ctxt, 8312 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8313 } 8314 attr = attr->next; 8315 } 8316 /* 8317 * Attribute "name" (mandatory). 8318 */ 8319 attr = xmlSchemaGetPropNode(node, "name"); 8320 if (attr == NULL) { 8321 xmlSchemaPMissingAttrErr(ctxt, 8322 XML_SCHEMAP_S4S_ATTR_MISSING, 8323 NULL, node, 8324 "name", NULL); 8325 return (NULL); 8326 } else if (xmlSchemaPValAttrNode(ctxt, 8327 NULL, attr, 8328 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8329 return (NULL); 8330 } 8331 /* Create the component. */ 8332 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8333 idcCategory, node); 8334 if (item == NULL) 8335 return(NULL); 8336 8337 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8338 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8339 /* 8340 * Attribute "refer" (mandatory). 8341 */ 8342 attr = xmlSchemaGetPropNode(node, "refer"); 8343 if (attr == NULL) { 8344 xmlSchemaPMissingAttrErr(ctxt, 8345 XML_SCHEMAP_S4S_ATTR_MISSING, 8346 NULL, node, 8347 "refer", NULL); 8348 } else { 8349 /* 8350 * Create a reference item. 8351 */ 8352 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8353 NULL, NULL); 8354 if (item->ref == NULL) 8355 return (NULL); 8356 xmlSchemaPValAttrNodeQName(ctxt, schema, 8357 NULL, attr, 8358 &(item->ref->targetNamespace), 8359 &(item->ref->name)); 8360 xmlSchemaCheckReference(ctxt, schema, node, attr, 8361 item->ref->targetNamespace); 8362 } 8363 } 8364 /* 8365 * And now for the children... 8366 */ 8367 child = node->children; 8368 if (IS_SCHEMA(child, "annotation")) { 8369 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8370 child = child->next; 8371 } 8372 if (child == NULL) { 8373 xmlSchemaPContentErr(ctxt, 8374 XML_SCHEMAP_S4S_ELEM_MISSING, 8375 NULL, node, child, 8376 "A child element is missing", 8377 "(annotation?, (selector, field+))"); 8378 } 8379 /* 8380 * Child element <selector>. 8381 */ 8382 if (IS_SCHEMA(child, "selector")) { 8383 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8384 item, child, 0); 8385 child = child->next; 8386 /* 8387 * Child elements <field>. 8388 */ 8389 if (IS_SCHEMA(child, "field")) { 8390 do { 8391 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8392 item, child, 1); 8393 if (field != NULL) { 8394 field->index = item->nbFields; 8395 item->nbFields++; 8396 if (lastField != NULL) 8397 lastField->next = field; 8398 else 8399 item->fields = field; 8400 lastField = field; 8401 } 8402 child = child->next; 8403 } while (IS_SCHEMA(child, "field")); 8404 } else { 8405 xmlSchemaPContentErr(ctxt, 8406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8407 NULL, node, child, 8408 NULL, "(annotation?, (selector, field+))"); 8409 } 8410 } 8411 if (child != NULL) { 8412 xmlSchemaPContentErr(ctxt, 8413 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8414 NULL, node, child, 8415 NULL, "(annotation?, (selector, field+))"); 8416 } 8417 8418 return (item); 8419 } 8420 8421 /** 8422 * xmlSchemaParseElement: 8423 * @ctxt: a schema validation context 8424 * @schema: the schema being built 8425 * @node: a subtree containing XML Schema informations 8426 * @topLevel: indicates if this is global declaration 8427 * 8428 * Parses a XML schema element declaration. 8429 * *WARNING* this interface is highly subject to change 8430 * 8431 * Returns the element declaration or a particle; NULL in case 8432 * of an error or if the particle has minOccurs==maxOccurs==0. 8433 */ 8434 static xmlSchemaBasicItemPtr 8435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8436 xmlNodePtr node, int *isElemRef, int topLevel) 8437 { 8438 xmlSchemaElementPtr decl = NULL; 8439 xmlSchemaParticlePtr particle = NULL; 8440 xmlSchemaAnnotPtr annot = NULL; 8441 xmlNodePtr child = NULL; 8442 xmlAttrPtr attr, nameAttr; 8443 int min, max, isRef = 0; 8444 xmlChar *des = NULL; 8445 8446 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8447 /* TODO: Complete implementation of 3.3.6 */ 8448 8449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8450 return (NULL); 8451 8452 if (isElemRef != NULL) 8453 *isElemRef = 0; 8454 /* 8455 * If we get a "ref" attribute on a local <element> we will assume it's 8456 * a reference - even if there's a "name" attribute; this seems to be more 8457 * robust. 8458 */ 8459 nameAttr = xmlSchemaGetPropNode(node, "name"); 8460 attr = xmlSchemaGetPropNode(node, "ref"); 8461 if ((topLevel) || (attr == NULL)) { 8462 if (nameAttr == NULL) { 8463 xmlSchemaPMissingAttrErr(ctxt, 8464 XML_SCHEMAP_S4S_ATTR_MISSING, 8465 NULL, node, "name", NULL); 8466 return (NULL); 8467 } 8468 } else 8469 isRef = 1; 8470 8471 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8472 child = node->children; 8473 if (IS_SCHEMA(child, "annotation")) { 8474 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8475 child = child->next; 8476 } 8477 /* 8478 * Skip particle part if a global declaration. 8479 */ 8480 if (topLevel) 8481 goto declaration_part; 8482 /* 8483 * The particle part ================================================== 8484 */ 8485 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8486 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8487 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8488 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8489 if (particle == NULL) 8490 goto return_null; 8491 8492 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8493 8494 if (isRef) { 8495 const xmlChar *refNs = NULL, *ref = NULL; 8496 xmlSchemaQNameRefPtr refer = NULL; 8497 /* 8498 * The reference part ============================================= 8499 */ 8500 if (isElemRef != NULL) 8501 *isElemRef = 1; 8502 8503 xmlSchemaPValAttrNodeQName(ctxt, schema, 8504 NULL, attr, &refNs, &ref); 8505 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8506 /* 8507 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8508 */ 8509 if (nameAttr != NULL) { 8510 xmlSchemaPMutualExclAttrErr(ctxt, 8511 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8512 } 8513 /* 8514 * Check for illegal attributes. 8515 */ 8516 attr = node->properties; 8517 while (attr != NULL) { 8518 if (attr->ns == NULL) { 8519 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8520 xmlStrEqual(attr->name, BAD_CAST "name") || 8521 xmlStrEqual(attr->name, BAD_CAST "id") || 8522 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8523 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8524 { 8525 attr = attr->next; 8526 continue; 8527 } else { 8528 /* SPEC (3.3.3 : 2.2) */ 8529 xmlSchemaPCustomAttrErr(ctxt, 8530 XML_SCHEMAP_SRC_ELEMENT_2_2, 8531 NULL, NULL, attr, 8532 "Only the attributes 'minOccurs', 'maxOccurs' and " 8533 "'id' are allowed in addition to 'ref'"); 8534 break; 8535 } 8536 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8537 xmlSchemaPIllegalAttrErr(ctxt, 8538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8539 } 8540 attr = attr->next; 8541 } 8542 /* 8543 * No children except <annotation> expected. 8544 */ 8545 if (child != NULL) { 8546 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8547 NULL, node, child, NULL, "(annotation?)"); 8548 } 8549 if ((min == 0) && (max == 0)) 8550 goto return_null; 8551 /* 8552 * Create the reference item and attach it to the particle. 8553 */ 8554 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8555 ref, refNs); 8556 if (refer == NULL) 8557 goto return_null; 8558 particle->children = (xmlSchemaTreeItemPtr) refer; 8559 particle->annot = annot; 8560 /* 8561 * Add the particle to pending components, since the reference 8562 * need to be resolved. 8563 */ 8564 WXS_ADD_PENDING(ctxt, particle); 8565 return ((xmlSchemaBasicItemPtr) particle); 8566 } 8567 /* 8568 * The declaration part =============================================== 8569 */ 8570 declaration_part: 8571 { 8572 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8573 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8574 8575 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8576 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8577 goto return_null; 8578 /* 8579 * Evaluate the target namespace. 8580 */ 8581 if (topLevel) { 8582 ns = ctxt->targetNamespace; 8583 } else { 8584 attr = xmlSchemaGetPropNode(node, "form"); 8585 if (attr != NULL) { 8586 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8587 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8588 ns = ctxt->targetNamespace; 8589 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8590 xmlSchemaPSimpleTypeErr(ctxt, 8591 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8592 NULL, (xmlNodePtr) attr, 8593 NULL, "(qualified | unqualified)", 8594 attrValue, NULL, NULL, NULL); 8595 } 8596 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8597 ns = ctxt->targetNamespace; 8598 } 8599 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8600 if (decl == NULL) { 8601 goto return_null; 8602 } 8603 /* 8604 * Check for illegal attributes. 8605 */ 8606 attr = node->properties; 8607 while (attr != NULL) { 8608 if (attr->ns == NULL) { 8609 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8610 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8611 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8612 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8613 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8614 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8615 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8616 { 8617 if (topLevel == 0) { 8618 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8619 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8620 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8621 { 8622 xmlSchemaPIllegalAttrErr(ctxt, 8623 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8624 } 8625 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8626 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8627 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8628 8629 xmlSchemaPIllegalAttrErr(ctxt, 8630 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8631 } 8632 } 8633 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8634 8635 xmlSchemaPIllegalAttrErr(ctxt, 8636 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8637 } 8638 attr = attr->next; 8639 } 8640 /* 8641 * Extract/validate attributes. 8642 */ 8643 if (topLevel) { 8644 /* 8645 * Process top attributes of global element declarations here. 8646 */ 8647 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8648 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8649 xmlSchemaPValAttrQName(ctxt, schema, 8650 NULL, node, "substitutionGroup", 8651 &(decl->substGroupNs), &(decl->substGroup)); 8652 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8653 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8654 /* 8655 * Attribute "final". 8656 */ 8657 attr = xmlSchemaGetPropNode(node, "final"); 8658 if (attr == NULL) { 8659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8660 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8661 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8662 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8663 } else { 8664 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8665 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8666 -1, 8667 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8668 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8669 xmlSchemaPSimpleTypeErr(ctxt, 8670 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8671 NULL, (xmlNodePtr) attr, 8672 NULL, "(#all | List of (extension | restriction))", 8673 attrValue, NULL, NULL, NULL); 8674 } 8675 } 8676 } 8677 /* 8678 * Attribute "block". 8679 */ 8680 attr = xmlSchemaGetPropNode(node, "block"); 8681 if (attr == NULL) { 8682 /* 8683 * Apply default "block" values. 8684 */ 8685 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8686 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8687 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8688 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8689 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8690 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8691 } else { 8692 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8693 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8694 -1, 8695 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8696 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8697 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8698 xmlSchemaPSimpleTypeErr(ctxt, 8699 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8700 NULL, (xmlNodePtr) attr, 8701 NULL, "(#all | List of (extension | " 8702 "restriction | substitution))", attrValue, 8703 NULL, NULL, NULL); 8704 } 8705 } 8706 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8707 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8708 8709 attr = xmlSchemaGetPropNode(node, "type"); 8710 if (attr != NULL) { 8711 xmlSchemaPValAttrNodeQName(ctxt, schema, 8712 NULL, attr, 8713 &(decl->namedTypeNs), &(decl->namedType)); 8714 xmlSchemaCheckReference(ctxt, schema, node, 8715 attr, decl->namedTypeNs); 8716 } 8717 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8718 attr = xmlSchemaGetPropNode(node, "fixed"); 8719 if (attr != NULL) { 8720 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8721 if (decl->value != NULL) { 8722 /* 8723 * 3.3.3 : 1 8724 * default and fixed must not both be present. 8725 */ 8726 xmlSchemaPMutualExclAttrErr(ctxt, 8727 XML_SCHEMAP_SRC_ELEMENT_1, 8728 NULL, attr, "default", "fixed"); 8729 } else { 8730 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8731 decl->value = fixed; 8732 } 8733 } 8734 /* 8735 * And now for the children... 8736 */ 8737 if (IS_SCHEMA(child, "complexType")) { 8738 /* 8739 * 3.3.3 : 3 8740 * "type" and either <simpleType> or <complexType> are mutually 8741 * exclusive 8742 */ 8743 if (decl->namedType != NULL) { 8744 xmlSchemaPContentErr(ctxt, 8745 XML_SCHEMAP_SRC_ELEMENT_3, 8746 NULL, node, child, 8747 "The attribute 'type' and the <complexType> child are " 8748 "mutually exclusive", NULL); 8749 } else 8750 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8751 child = child->next; 8752 } else if (IS_SCHEMA(child, "simpleType")) { 8753 /* 8754 * 3.3.3 : 3 8755 * "type" and either <simpleType> or <complexType> are 8756 * mutually exclusive 8757 */ 8758 if (decl->namedType != NULL) { 8759 xmlSchemaPContentErr(ctxt, 8760 XML_SCHEMAP_SRC_ELEMENT_3, 8761 NULL, node, child, 8762 "The attribute 'type' and the <simpleType> child are " 8763 "mutually exclusive", NULL); 8764 } else 8765 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8766 child = child->next; 8767 } 8768 while ((IS_SCHEMA(child, "unique")) || 8769 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8770 if (IS_SCHEMA(child, "unique")) { 8771 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8772 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8773 } else if (IS_SCHEMA(child, "key")) { 8774 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8775 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8776 } else if (IS_SCHEMA(child, "keyref")) { 8777 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8778 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8779 } 8780 if (lastIDC != NULL) 8781 lastIDC->next = curIDC; 8782 else 8783 decl->idcs = (void *) curIDC; 8784 lastIDC = curIDC; 8785 child = child->next; 8786 } 8787 if (child != NULL) { 8788 xmlSchemaPContentErr(ctxt, 8789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8790 NULL, node, child, 8791 NULL, "(annotation?, ((simpleType | complexType)?, " 8792 "(unique | key | keyref)*))"); 8793 } 8794 decl->annot = annot; 8795 } 8796 /* 8797 * NOTE: Element Declaration Representation OK 4. will be checked at a 8798 * different layer. 8799 */ 8800 FREE_AND_NULL(des) 8801 if (topLevel) 8802 return ((xmlSchemaBasicItemPtr) decl); 8803 else { 8804 particle->children = (xmlSchemaTreeItemPtr) decl; 8805 return ((xmlSchemaBasicItemPtr) particle); 8806 } 8807 8808 return_null: 8809 FREE_AND_NULL(des); 8810 if (annot != NULL) { 8811 if (particle != NULL) 8812 particle->annot = NULL; 8813 if (decl != NULL) 8814 decl->annot = NULL; 8815 xmlSchemaFreeAnnot(annot); 8816 } 8817 return (NULL); 8818 } 8819 8820 /** 8821 * xmlSchemaParseUnion: 8822 * @ctxt: a schema validation context 8823 * @schema: the schema being built 8824 * @node: a subtree containing XML Schema informations 8825 * 8826 * parse a XML schema Union definition 8827 * *WARNING* this interface is highly subject to change 8828 * 8829 * Returns -1 in case of internal error, 0 in case of success and a positive 8830 * error code otherwise. 8831 */ 8832 static int 8833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8834 xmlNodePtr node) 8835 { 8836 xmlSchemaTypePtr type; 8837 xmlNodePtr child = NULL; 8838 xmlAttrPtr attr; 8839 const xmlChar *cur = NULL; 8840 8841 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8842 return (-1); 8843 /* Not a component, don't create it. */ 8844 type = ctxt->ctxtType; 8845 /* 8846 * Mark the simple type as being of variety "union". 8847 */ 8848 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8849 /* 8850 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8851 * then the simple ur-type definition." 8852 */ 8853 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8854 /* 8855 * Check for illegal attributes. 8856 */ 8857 attr = node->properties; 8858 while (attr != NULL) { 8859 if (attr->ns == NULL) { 8860 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8861 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8862 xmlSchemaPIllegalAttrErr(ctxt, 8863 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8864 } 8865 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8866 xmlSchemaPIllegalAttrErr(ctxt, 8867 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8868 } 8869 attr = attr->next; 8870 } 8871 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8872 /* 8873 * Attribute "memberTypes". This is a list of QNames. 8874 * TODO: Check the value to contain anything. 8875 */ 8876 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8877 if (attr != NULL) { 8878 const xmlChar *end; 8879 xmlChar *tmp; 8880 const xmlChar *localName, *nsName; 8881 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8882 xmlSchemaQNameRefPtr ref; 8883 8884 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8885 type->base = cur; 8886 do { 8887 while (IS_BLANK_CH(*cur)) 8888 cur++; 8889 end = cur; 8890 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8891 end++; 8892 if (end == cur) 8893 break; 8894 tmp = xmlStrndup(cur, end - cur); 8895 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8896 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8897 /* 8898 * Create the member type link. 8899 */ 8900 link = (xmlSchemaTypeLinkPtr) 8901 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8902 if (link == NULL) { 8903 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8904 "allocating a type link", NULL); 8905 return (-1); 8906 } 8907 link->type = NULL; 8908 link->next = NULL; 8909 if (lastLink == NULL) 8910 type->memberTypes = link; 8911 else 8912 lastLink->next = link; 8913 lastLink = link; 8914 /* 8915 * Create a reference item. 8916 */ 8917 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8918 localName, nsName); 8919 if (ref == NULL) { 8920 FREE_AND_NULL(tmp) 8921 return (-1); 8922 } 8923 /* 8924 * Assign the reference to the link, it will be resolved 8925 * later during fixup of the union simple type. 8926 */ 8927 link->type = (xmlSchemaTypePtr) ref; 8928 } 8929 FREE_AND_NULL(tmp) 8930 cur = end; 8931 } while (*cur != 0); 8932 8933 } 8934 /* 8935 * And now for the children... 8936 */ 8937 child = node->children; 8938 if (IS_SCHEMA(child, "annotation")) { 8939 /* 8940 * Add the annotation to the simple type ancestor. 8941 */ 8942 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8943 xmlSchemaParseAnnotation(ctxt, child, 1)); 8944 child = child->next; 8945 } 8946 if (IS_SCHEMA(child, "simpleType")) { 8947 xmlSchemaTypePtr subtype, last = NULL; 8948 8949 /* 8950 * Anchor the member types in the "subtypes" field of the 8951 * simple type. 8952 */ 8953 while (IS_SCHEMA(child, "simpleType")) { 8954 subtype = (xmlSchemaTypePtr) 8955 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8956 if (subtype != NULL) { 8957 if (last == NULL) { 8958 type->subtypes = subtype; 8959 last = subtype; 8960 } else { 8961 last->next = subtype; 8962 last = subtype; 8963 } 8964 last->next = NULL; 8965 } 8966 child = child->next; 8967 } 8968 } 8969 if (child != NULL) { 8970 xmlSchemaPContentErr(ctxt, 8971 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8972 NULL, node, child, NULL, "(annotation?, simpleType*)"); 8973 } 8974 if ((attr == NULL) && (type->subtypes == NULL)) { 8975 /* 8976 * src-union-memberTypes-or-simpleTypes 8977 * Either the memberTypes [attribute] of the <union> element must 8978 * be non-empty or there must be at least one simpleType [child]. 8979 */ 8980 xmlSchemaPCustomErr(ctxt, 8981 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 8982 NULL, node, 8983 "Either the attribute 'memberTypes' or " 8984 "at least one <simpleType> child must be present", NULL); 8985 } 8986 return (0); 8987 } 8988 8989 /** 8990 * xmlSchemaParseList: 8991 * @ctxt: a schema validation context 8992 * @schema: the schema being built 8993 * @node: a subtree containing XML Schema informations 8994 * 8995 * parse a XML schema List definition 8996 * *WARNING* this interface is highly subject to change 8997 * 8998 * Returns -1 in case of error, 0 if the declaration is improper and 8999 * 1 in case of success. 9000 */ 9001 static xmlSchemaTypePtr 9002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9003 xmlNodePtr node) 9004 { 9005 xmlSchemaTypePtr type; 9006 xmlNodePtr child = NULL; 9007 xmlAttrPtr attr; 9008 9009 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9010 return (NULL); 9011 /* Not a component, don't create it. */ 9012 type = ctxt->ctxtType; 9013 /* 9014 * Mark the type as being of variety "list". 9015 */ 9016 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9017 /* 9018 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9019 * then the simple ur-type definition." 9020 */ 9021 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9022 /* 9023 * Check for illegal attributes. 9024 */ 9025 attr = node->properties; 9026 while (attr != NULL) { 9027 if (attr->ns == NULL) { 9028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9029 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9030 xmlSchemaPIllegalAttrErr(ctxt, 9031 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9032 } 9033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9034 xmlSchemaPIllegalAttrErr(ctxt, 9035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9036 } 9037 attr = attr->next; 9038 } 9039 9040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9041 9042 /* 9043 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9044 * fields for holding the reference to the itemType. 9045 * 9046 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9047 * the "ref" fields. 9048 */ 9049 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9050 node, "itemType", &(type->baseNs), &(type->base)); 9051 /* 9052 * And now for the children... 9053 */ 9054 child = node->children; 9055 if (IS_SCHEMA(child, "annotation")) { 9056 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9057 xmlSchemaParseAnnotation(ctxt, child, 1)); 9058 child = child->next; 9059 } 9060 if (IS_SCHEMA(child, "simpleType")) { 9061 /* 9062 * src-list-itemType-or-simpleType 9063 * Either the itemType [attribute] or the <simpleType> [child] of 9064 * the <list> element must be present, but not both. 9065 */ 9066 if (type->base != NULL) { 9067 xmlSchemaPCustomErr(ctxt, 9068 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9069 NULL, node, 9070 "The attribute 'itemType' and the <simpleType> child " 9071 "are mutually exclusive", NULL); 9072 } else { 9073 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9074 } 9075 child = child->next; 9076 } else if (type->base == NULL) { 9077 xmlSchemaPCustomErr(ctxt, 9078 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9079 NULL, node, 9080 "Either the attribute 'itemType' or the <simpleType> child " 9081 "must be present", NULL); 9082 } 9083 if (child != NULL) { 9084 xmlSchemaPContentErr(ctxt, 9085 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9086 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9087 } 9088 if ((type->base == NULL) && 9089 (type->subtypes == NULL) && 9090 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9091 xmlSchemaPCustomErr(ctxt, 9092 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9093 NULL, node, 9094 "Either the attribute 'itemType' or the <simpleType> child " 9095 "must be present", NULL); 9096 } 9097 return (NULL); 9098 } 9099 9100 /** 9101 * xmlSchemaParseSimpleType: 9102 * @ctxt: a schema validation context 9103 * @schema: the schema being built 9104 * @node: a subtree containing XML Schema informations 9105 * 9106 * parse a XML schema Simple Type definition 9107 * *WARNING* this interface is highly subject to change 9108 * 9109 * Returns -1 in case of error, 0 if the declaration is improper and 9110 * 1 in case of success. 9111 */ 9112 static xmlSchemaTypePtr 9113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9114 xmlNodePtr node, int topLevel) 9115 { 9116 xmlSchemaTypePtr type, oldCtxtType; 9117 xmlNodePtr child = NULL; 9118 const xmlChar *attrValue = NULL; 9119 xmlAttrPtr attr; 9120 int hasRestriction = 0; 9121 9122 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9123 return (NULL); 9124 9125 if (topLevel) { 9126 attr = xmlSchemaGetPropNode(node, "name"); 9127 if (attr == NULL) { 9128 xmlSchemaPMissingAttrErr(ctxt, 9129 XML_SCHEMAP_S4S_ATTR_MISSING, 9130 NULL, node, 9131 "name", NULL); 9132 return (NULL); 9133 } else { 9134 if (xmlSchemaPValAttrNode(ctxt, 9135 NULL, attr, 9136 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9137 return (NULL); 9138 /* 9139 * Skip built-in types. 9140 */ 9141 if (ctxt->isS4S) { 9142 xmlSchemaTypePtr biType; 9143 9144 if (ctxt->isRedefine) { 9145 /* 9146 * REDEFINE: Disallow redefinition of built-in-types. 9147 * TODO: It seems that the spec does not say anything 9148 * about this case. 9149 */ 9150 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9151 NULL, node, 9152 "Redefinition of built-in simple types is not " 9153 "supported", NULL); 9154 return(NULL); 9155 } 9156 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9157 if (biType != NULL) 9158 return (biType); 9159 } 9160 } 9161 } 9162 /* 9163 * TargetNamespace: 9164 * SPEC "The actual value of the targetNamespace [attribute] 9165 * of the <schema> ancestor element information item if present, 9166 * otherwise absent. 9167 */ 9168 if (topLevel == 0) { 9169 #ifdef ENABLE_NAMED_LOCALS 9170 char buf[40]; 9171 #endif 9172 /* 9173 * Parse as local simple type definition. 9174 */ 9175 #ifdef ENABLE_NAMED_LOCALS 9176 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9177 type = xmlSchemaAddType(ctxt, schema, 9178 XML_SCHEMA_TYPE_SIMPLE, 9179 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9180 ctxt->targetNamespace, node, 0); 9181 #else 9182 type = xmlSchemaAddType(ctxt, schema, 9183 XML_SCHEMA_TYPE_SIMPLE, 9184 NULL, ctxt->targetNamespace, node, 0); 9185 #endif 9186 if (type == NULL) 9187 return (NULL); 9188 type->type = XML_SCHEMA_TYPE_SIMPLE; 9189 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9190 /* 9191 * Check for illegal attributes. 9192 */ 9193 attr = node->properties; 9194 while (attr != NULL) { 9195 if (attr->ns == NULL) { 9196 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9197 xmlSchemaPIllegalAttrErr(ctxt, 9198 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9199 } 9200 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9201 xmlSchemaPIllegalAttrErr(ctxt, 9202 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9203 } 9204 attr = attr->next; 9205 } 9206 } else { 9207 /* 9208 * Parse as global simple type definition. 9209 * 9210 * Note that attrValue is the value of the attribute "name" here. 9211 */ 9212 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9213 attrValue, ctxt->targetNamespace, node, 1); 9214 if (type == NULL) 9215 return (NULL); 9216 type->type = XML_SCHEMA_TYPE_SIMPLE; 9217 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9218 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9219 /* 9220 * Check for illegal attributes. 9221 */ 9222 attr = node->properties; 9223 while (attr != NULL) { 9224 if (attr->ns == NULL) { 9225 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9226 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9227 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9228 xmlSchemaPIllegalAttrErr(ctxt, 9229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9230 } 9231 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9232 xmlSchemaPIllegalAttrErr(ctxt, 9233 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9234 } 9235 attr = attr->next; 9236 } 9237 /* 9238 * Attribute "final". 9239 */ 9240 attr = xmlSchemaGetPropNode(node, "final"); 9241 if (attr == NULL) { 9242 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9243 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9244 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9245 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9247 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9248 } else { 9249 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9250 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9251 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9252 XML_SCHEMAS_TYPE_FINAL_LIST, 9253 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9254 9255 xmlSchemaPSimpleTypeErr(ctxt, 9256 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9257 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9258 NULL, "(#all | List of (list | union | restriction)", 9259 attrValue, NULL, NULL, NULL); 9260 } 9261 } 9262 } 9263 type->targetNamespace = ctxt->targetNamespace; 9264 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9265 /* 9266 * And now for the children... 9267 */ 9268 oldCtxtType = ctxt->ctxtType; 9269 9270 ctxt->ctxtType = type; 9271 9272 child = node->children; 9273 if (IS_SCHEMA(child, "annotation")) { 9274 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9275 child = child->next; 9276 } 9277 if (child == NULL) { 9278 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9279 NULL, node, child, NULL, 9280 "(annotation?, (restriction | list | union))"); 9281 } else if (IS_SCHEMA(child, "restriction")) { 9282 xmlSchemaParseRestriction(ctxt, schema, child, 9283 XML_SCHEMA_TYPE_SIMPLE); 9284 hasRestriction = 1; 9285 child = child->next; 9286 } else if (IS_SCHEMA(child, "list")) { 9287 xmlSchemaParseList(ctxt, schema, child); 9288 child = child->next; 9289 } else if (IS_SCHEMA(child, "union")) { 9290 xmlSchemaParseUnion(ctxt, schema, child); 9291 child = child->next; 9292 } 9293 if (child != NULL) { 9294 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9295 NULL, node, child, NULL, 9296 "(annotation?, (restriction | list | union))"); 9297 } 9298 /* 9299 * REDEFINE: SPEC src-redefine (5) 9300 * "Within the [children], each <simpleType> must have a 9301 * <restriction> among its [children] ... the actual value of whose 9302 * base [attribute] must be the same as the actual value of its own 9303 * name attribute plus target namespace;" 9304 */ 9305 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9306 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9307 NULL, node, "This is a redefinition, thus the " 9308 "<simpleType> must have a <restriction> child", NULL); 9309 } 9310 9311 ctxt->ctxtType = oldCtxtType; 9312 return (type); 9313 } 9314 9315 /** 9316 * xmlSchemaParseModelGroupDefRef: 9317 * @ctxt: the parser context 9318 * @schema: the schema being built 9319 * @node: the node 9320 * 9321 * Parses a reference to a model group definition. 9322 * 9323 * We will return a particle component with a qname-component or 9324 * NULL in case of an error. 9325 */ 9326 static xmlSchemaTreeItemPtr 9327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9328 xmlSchemaPtr schema, 9329 xmlNodePtr node) 9330 { 9331 xmlSchemaParticlePtr item; 9332 xmlNodePtr child = NULL; 9333 xmlAttrPtr attr; 9334 const xmlChar *ref = NULL, *refNs = NULL; 9335 int min, max; 9336 9337 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9338 return (NULL); 9339 9340 attr = xmlSchemaGetPropNode(node, "ref"); 9341 if (attr == NULL) { 9342 xmlSchemaPMissingAttrErr(ctxt, 9343 XML_SCHEMAP_S4S_ATTR_MISSING, 9344 NULL, node, "ref", NULL); 9345 return (NULL); 9346 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9347 attr, &refNs, &ref) != 0) { 9348 return (NULL); 9349 } 9350 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9351 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9352 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9353 "(xs:nonNegativeInteger | unbounded)"); 9354 /* 9355 * Check for illegal attributes. 9356 */ 9357 attr = node->properties; 9358 while (attr != NULL) { 9359 if (attr->ns == NULL) { 9360 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9361 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9362 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9363 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9364 xmlSchemaPIllegalAttrErr(ctxt, 9365 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9366 } 9367 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9368 xmlSchemaPIllegalAttrErr(ctxt, 9369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9370 } 9371 attr = attr->next; 9372 } 9373 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9374 item = xmlSchemaAddParticle(ctxt, node, min, max); 9375 if (item == NULL) 9376 return (NULL); 9377 /* 9378 * Create a qname-reference and set as the term; it will be substituted 9379 * for the model group after the reference has been resolved. 9380 */ 9381 item->children = (xmlSchemaTreeItemPtr) 9382 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9383 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9384 /* 9385 * And now for the children... 9386 */ 9387 child = node->children; 9388 /* TODO: Is annotation even allowed for a model group reference? */ 9389 if (IS_SCHEMA(child, "annotation")) { 9390 /* 9391 * TODO: What to do exactly with the annotation? 9392 */ 9393 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9394 child = child->next; 9395 } 9396 if (child != NULL) { 9397 xmlSchemaPContentErr(ctxt, 9398 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9399 NULL, node, child, NULL, 9400 "(annotation?)"); 9401 } 9402 /* 9403 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9404 */ 9405 if ((min == 0) && (max == 0)) 9406 return (NULL); 9407 9408 return ((xmlSchemaTreeItemPtr) item); 9409 } 9410 9411 /** 9412 * xmlSchemaParseModelGroupDefinition: 9413 * @ctxt: a schema validation context 9414 * @schema: the schema being built 9415 * @node: a subtree containing XML Schema informations 9416 * 9417 * Parses a XML schema model group definition. 9418 * 9419 * Note that the contraint src-redefine (6.2) can't be applied until 9420 * references have been resolved. So we will do this at the 9421 * component fixup level. 9422 * 9423 * *WARNING* this interface is highly subject to change 9424 * 9425 * Returns -1 in case of error, 0 if the declaration is improper and 9426 * 1 in case of success. 9427 */ 9428 static xmlSchemaModelGroupDefPtr 9429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9430 xmlSchemaPtr schema, 9431 xmlNodePtr node) 9432 { 9433 xmlSchemaModelGroupDefPtr item; 9434 xmlNodePtr child = NULL; 9435 xmlAttrPtr attr; 9436 const xmlChar *name; 9437 9438 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9439 return (NULL); 9440 9441 attr = xmlSchemaGetPropNode(node, "name"); 9442 if (attr == NULL) { 9443 xmlSchemaPMissingAttrErr(ctxt, 9444 XML_SCHEMAP_S4S_ATTR_MISSING, 9445 NULL, node, 9446 "name", NULL); 9447 return (NULL); 9448 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9449 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9450 return (NULL); 9451 } 9452 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9453 ctxt->targetNamespace, node); 9454 if (item == NULL) 9455 return (NULL); 9456 /* 9457 * Check for illegal attributes. 9458 */ 9459 attr = node->properties; 9460 while (attr != NULL) { 9461 if (attr->ns == NULL) { 9462 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9463 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9464 xmlSchemaPIllegalAttrErr(ctxt, 9465 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9466 } 9467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9468 xmlSchemaPIllegalAttrErr(ctxt, 9469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9470 } 9471 attr = attr->next; 9472 } 9473 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9474 /* 9475 * And now for the children... 9476 */ 9477 child = node->children; 9478 if (IS_SCHEMA(child, "annotation")) { 9479 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9480 child = child->next; 9481 } 9482 if (IS_SCHEMA(child, "all")) { 9483 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9484 XML_SCHEMA_TYPE_ALL, 0); 9485 child = child->next; 9486 } else if (IS_SCHEMA(child, "choice")) { 9487 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9488 XML_SCHEMA_TYPE_CHOICE, 0); 9489 child = child->next; 9490 } else if (IS_SCHEMA(child, "sequence")) { 9491 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9492 XML_SCHEMA_TYPE_SEQUENCE, 0); 9493 child = child->next; 9494 } 9495 9496 9497 9498 if (child != NULL) { 9499 xmlSchemaPContentErr(ctxt, 9500 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9501 NULL, node, child, NULL, 9502 "(annotation?, (all | choice | sequence)?)"); 9503 } 9504 return (item); 9505 } 9506 9507 /** 9508 * xmlSchemaCleanupDoc: 9509 * @ctxt: a schema validation context 9510 * @node: the root of the document. 9511 * 9512 * removes unwanted nodes in a schemas document tree 9513 */ 9514 static void 9515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9516 { 9517 xmlNodePtr delete, cur; 9518 9519 if ((ctxt == NULL) || (root == NULL)) return; 9520 9521 /* 9522 * Remove all the blank text nodes 9523 */ 9524 delete = NULL; 9525 cur = root; 9526 while (cur != NULL) { 9527 if (delete != NULL) { 9528 xmlUnlinkNode(delete); 9529 xmlFreeNode(delete); 9530 delete = NULL; 9531 } 9532 if (cur->type == XML_TEXT_NODE) { 9533 if (IS_BLANK_NODE(cur)) { 9534 if (xmlNodeGetSpacePreserve(cur) != 1) { 9535 delete = cur; 9536 } 9537 } 9538 } else if ((cur->type != XML_ELEMENT_NODE) && 9539 (cur->type != XML_CDATA_SECTION_NODE)) { 9540 delete = cur; 9541 goto skip_children; 9542 } 9543 9544 /* 9545 * Skip to next node 9546 */ 9547 if (cur->children != NULL) { 9548 if ((cur->children->type != XML_ENTITY_DECL) && 9549 (cur->children->type != XML_ENTITY_REF_NODE) && 9550 (cur->children->type != XML_ENTITY_NODE)) { 9551 cur = cur->children; 9552 continue; 9553 } 9554 } 9555 skip_children: 9556 if (cur->next != NULL) { 9557 cur = cur->next; 9558 continue; 9559 } 9560 9561 do { 9562 cur = cur->parent; 9563 if (cur == NULL) 9564 break; 9565 if (cur == root) { 9566 cur = NULL; 9567 break; 9568 } 9569 if (cur->next != NULL) { 9570 cur = cur->next; 9571 break; 9572 } 9573 } while (cur != NULL); 9574 } 9575 if (delete != NULL) { 9576 xmlUnlinkNode(delete); 9577 xmlFreeNode(delete); 9578 delete = NULL; 9579 } 9580 } 9581 9582 9583 static void 9584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9585 { 9586 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9587 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9588 9589 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9590 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9591 9592 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9593 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9594 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9595 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9596 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9597 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9598 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9599 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9600 9601 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9602 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9603 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9604 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9605 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9606 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9607 } 9608 9609 static int 9610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9611 xmlSchemaPtr schema, 9612 xmlNodePtr node) 9613 { 9614 xmlAttrPtr attr; 9615 const xmlChar *val; 9616 int res = 0, oldErrs = ctxt->nberrors; 9617 9618 /* 9619 * Those flags should be moved to the parser context flags, 9620 * since they are not visible at the component level. I.e. 9621 * they are used if processing schema *documents* only. 9622 */ 9623 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9624 HFAILURE; 9625 9626 /* 9627 * Since the version is of type xs:token, we won't bother to 9628 * check it. 9629 */ 9630 /* REMOVED: 9631 attr = xmlSchemaGetPropNode(node, "version"); 9632 if (attr != NULL) { 9633 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9634 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9635 HFAILURE; 9636 } 9637 */ 9638 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9639 if (attr != NULL) { 9640 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9641 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9642 HFAILURE; 9643 if (res != 0) { 9644 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9645 goto exit; 9646 } 9647 } 9648 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9649 if (attr != NULL) { 9650 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9651 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9652 XML_SCHEMAS_QUALIF_ELEM); 9653 HFAILURE; 9654 if (res != 0) { 9655 xmlSchemaPSimpleTypeErr(ctxt, 9656 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9657 NULL, (xmlNodePtr) attr, NULL, 9658 "(qualified | unqualified)", val, NULL, NULL, NULL); 9659 } 9660 } 9661 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9662 if (attr != NULL) { 9663 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9664 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9665 XML_SCHEMAS_QUALIF_ATTR); 9666 HFAILURE; 9667 if (res != 0) { 9668 xmlSchemaPSimpleTypeErr(ctxt, 9669 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9670 NULL, (xmlNodePtr) attr, NULL, 9671 "(qualified | unqualified)", val, NULL, NULL, NULL); 9672 } 9673 } 9674 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9675 if (attr != NULL) { 9676 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9677 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9678 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9679 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9680 -1, 9681 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9682 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9683 HFAILURE; 9684 if (res != 0) { 9685 xmlSchemaPSimpleTypeErr(ctxt, 9686 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9687 NULL, (xmlNodePtr) attr, NULL, 9688 "(#all | List of (extension | restriction | list | union))", 9689 val, NULL, NULL, NULL); 9690 } 9691 } 9692 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9693 if (attr != NULL) { 9694 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9695 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9696 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9697 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9698 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9699 HFAILURE; 9700 if (res != 0) { 9701 xmlSchemaPSimpleTypeErr(ctxt, 9702 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9703 NULL, (xmlNodePtr) attr, NULL, 9704 "(#all | List of (extension | restriction | substitution))", 9705 val, NULL, NULL, NULL); 9706 } 9707 } 9708 9709 exit: 9710 if (oldErrs != ctxt->nberrors) 9711 res = ctxt->err; 9712 return(res); 9713 exit_failure: 9714 return(-1); 9715 } 9716 9717 /** 9718 * xmlSchemaParseSchemaTopLevel: 9719 * @ctxt: a schema validation context 9720 * @schema: the schemas 9721 * @nodes: the list of top level nodes 9722 * 9723 * Returns the internal XML Schema structure built from the resource or 9724 * NULL in case of error 9725 */ 9726 static int 9727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9728 xmlSchemaPtr schema, xmlNodePtr nodes) 9729 { 9730 xmlNodePtr child; 9731 xmlSchemaAnnotPtr annot; 9732 int res = 0, oldErrs, tmpOldErrs; 9733 9734 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9735 return(-1); 9736 9737 oldErrs = ctxt->nberrors; 9738 child = nodes; 9739 while ((IS_SCHEMA(child, "include")) || 9740 (IS_SCHEMA(child, "import")) || 9741 (IS_SCHEMA(child, "redefine")) || 9742 (IS_SCHEMA(child, "annotation"))) { 9743 if (IS_SCHEMA(child, "annotation")) { 9744 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9745 if (schema->annot == NULL) 9746 schema->annot = annot; 9747 else 9748 xmlSchemaFreeAnnot(annot); 9749 } else if (IS_SCHEMA(child, "import")) { 9750 tmpOldErrs = ctxt->nberrors; 9751 res = xmlSchemaParseImport(ctxt, schema, child); 9752 HFAILURE; 9753 HSTOP(ctxt); 9754 if (tmpOldErrs != ctxt->nberrors) 9755 goto exit; 9756 } else if (IS_SCHEMA(child, "include")) { 9757 tmpOldErrs = ctxt->nberrors; 9758 res = xmlSchemaParseInclude(ctxt, schema, child); 9759 HFAILURE; 9760 HSTOP(ctxt); 9761 if (tmpOldErrs != ctxt->nberrors) 9762 goto exit; 9763 } else if (IS_SCHEMA(child, "redefine")) { 9764 tmpOldErrs = ctxt->nberrors; 9765 res = xmlSchemaParseRedefine(ctxt, schema, child); 9766 HFAILURE; 9767 HSTOP(ctxt); 9768 if (tmpOldErrs != ctxt->nberrors) 9769 goto exit; 9770 } 9771 child = child->next; 9772 } 9773 /* 9774 * URGENT TODO: Change the functions to return int results. 9775 * We need especially to catch internal errors. 9776 */ 9777 while (child != NULL) { 9778 if (IS_SCHEMA(child, "complexType")) { 9779 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9780 child = child->next; 9781 } else if (IS_SCHEMA(child, "simpleType")) { 9782 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9783 child = child->next; 9784 } else if (IS_SCHEMA(child, "element")) { 9785 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9786 child = child->next; 9787 } else if (IS_SCHEMA(child, "attribute")) { 9788 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9789 child = child->next; 9790 } else if (IS_SCHEMA(child, "attributeGroup")) { 9791 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9792 child = child->next; 9793 } else if (IS_SCHEMA(child, "group")) { 9794 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9795 child = child->next; 9796 } else if (IS_SCHEMA(child, "notation")) { 9797 xmlSchemaParseNotation(ctxt, schema, child); 9798 child = child->next; 9799 } else { 9800 xmlSchemaPContentErr(ctxt, 9801 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9802 NULL, child->parent, child, 9803 NULL, "((include | import | redefine | annotation)*, " 9804 "(((simpleType | complexType | group | attributeGroup) " 9805 "| element | attribute | notation), annotation*)*)"); 9806 child = child->next; 9807 } 9808 while (IS_SCHEMA(child, "annotation")) { 9809 /* 9810 * TODO: We should add all annotations. 9811 */ 9812 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9813 if (schema->annot == NULL) 9814 schema->annot = annot; 9815 else 9816 xmlSchemaFreeAnnot(annot); 9817 child = child->next; 9818 } 9819 } 9820 exit: 9821 ctxt->ctxtType = NULL; 9822 if (oldErrs != ctxt->nberrors) 9823 res = ctxt->err; 9824 return(res); 9825 exit_failure: 9826 return(-1); 9827 } 9828 9829 static xmlSchemaSchemaRelationPtr 9830 xmlSchemaSchemaRelationCreate(void) 9831 { 9832 xmlSchemaSchemaRelationPtr ret; 9833 9834 ret = (xmlSchemaSchemaRelationPtr) 9835 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9836 if (ret == NULL) { 9837 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9838 return(NULL); 9839 } 9840 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9841 return(ret); 9842 } 9843 9844 #if 0 9845 static void 9846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9847 { 9848 xmlFree(rel); 9849 } 9850 #endif 9851 9852 static void 9853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9854 { 9855 xmlSchemaRedefPtr prev; 9856 9857 while (redef != NULL) { 9858 prev = redef; 9859 redef = redef->next; 9860 xmlFree(prev); 9861 } 9862 } 9863 9864 static void 9865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9866 { 9867 /* 9868 * After the construction context has been freed, there will be 9869 * no schema graph available any more. Only the schema buckets 9870 * will stay alive, which are put into the "schemasImports" and 9871 * "includes" slots of the xmlSchema. 9872 */ 9873 if (con->buckets != NULL) 9874 xmlSchemaItemListFree(con->buckets); 9875 if (con->pending != NULL) 9876 xmlSchemaItemListFree(con->pending); 9877 if (con->substGroups != NULL) 9878 xmlHashFree(con->substGroups, 9879 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9880 if (con->redefs != NULL) 9881 xmlSchemaRedefListFree(con->redefs); 9882 if (con->dict != NULL) 9883 xmlDictFree(con->dict); 9884 xmlFree(con); 9885 } 9886 9887 static xmlSchemaConstructionCtxtPtr 9888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9889 { 9890 xmlSchemaConstructionCtxtPtr ret; 9891 9892 ret = (xmlSchemaConstructionCtxtPtr) 9893 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9894 if (ret == NULL) { 9895 xmlSchemaPErrMemory(NULL, 9896 "allocating schema construction context", NULL); 9897 return (NULL); 9898 } 9899 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9900 9901 ret->buckets = xmlSchemaItemListCreate(); 9902 if (ret->buckets == NULL) { 9903 xmlSchemaPErrMemory(NULL, 9904 "allocating list of schema buckets", NULL); 9905 xmlFree(ret); 9906 return (NULL); 9907 } 9908 ret->pending = xmlSchemaItemListCreate(); 9909 if (ret->pending == NULL) { 9910 xmlSchemaPErrMemory(NULL, 9911 "allocating list of pending global components", NULL); 9912 xmlSchemaConstructionCtxtFree(ret); 9913 return (NULL); 9914 } 9915 ret->dict = dict; 9916 xmlDictReference(dict); 9917 return(ret); 9918 } 9919 9920 static xmlSchemaParserCtxtPtr 9921 xmlSchemaParserCtxtCreate(void) 9922 { 9923 xmlSchemaParserCtxtPtr ret; 9924 9925 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9926 if (ret == NULL) { 9927 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9928 NULL); 9929 return (NULL); 9930 } 9931 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9932 ret->type = XML_SCHEMA_CTXT_PARSER; 9933 ret->attrProhibs = xmlSchemaItemListCreate(); 9934 if (ret->attrProhibs == NULL) { 9935 xmlFree(ret); 9936 return(NULL); 9937 } 9938 return(ret); 9939 } 9940 9941 /** 9942 * xmlSchemaNewParserCtxtUseDict: 9943 * @URL: the location of the schema 9944 * @dict: the dictionary to be used 9945 * 9946 * Create an XML Schemas parse context for that file/resource expected 9947 * to contain an XML Schemas file. 9948 * 9949 * Returns the parser context or NULL in case of error 9950 */ 9951 static xmlSchemaParserCtxtPtr 9952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9953 { 9954 xmlSchemaParserCtxtPtr ret; 9955 9956 ret = xmlSchemaParserCtxtCreate(); 9957 if (ret == NULL) 9958 return (NULL); 9959 ret->dict = dict; 9960 xmlDictReference(dict); 9961 if (URL != NULL) 9962 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9963 return (ret); 9964 } 9965 9966 static int 9967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 9968 { 9969 if (vctxt->pctxt == NULL) { 9970 if (vctxt->schema != NULL) 9971 vctxt->pctxt = 9972 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 9973 else 9974 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 9975 if (vctxt->pctxt == NULL) { 9976 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 9977 "failed to create a temp. parser context"); 9978 return (-1); 9979 } 9980 /* TODO: Pass user data. */ 9981 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 9982 vctxt->warning, vctxt->errCtxt); 9983 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 9984 vctxt->errCtxt); 9985 } 9986 return (0); 9987 } 9988 9989 /** 9990 * xmlSchemaGetSchemaBucket: 9991 * @pctxt: the schema parser context 9992 * @schemaLocation: the URI of the schema document 9993 * 9994 * Returns a schema bucket if it was already parsed. 9995 * 9996 * Returns a schema bucket if it was already parsed from 9997 * @schemaLocation, NULL otherwise. 9998 */ 9999 static xmlSchemaBucketPtr 10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10001 const xmlChar *schemaLocation) 10002 { 10003 xmlSchemaBucketPtr cur; 10004 xmlSchemaItemListPtr list; 10005 10006 list = pctxt->constructor->buckets; 10007 if (list->nbItems == 0) 10008 return(NULL); 10009 else { 10010 int i; 10011 for (i = 0; i < list->nbItems; i++) { 10012 cur = (xmlSchemaBucketPtr) list->items[i]; 10013 /* Pointer comparison! */ 10014 if (cur->schemaLocation == schemaLocation) 10015 return(cur); 10016 } 10017 } 10018 return(NULL); 10019 } 10020 10021 static xmlSchemaBucketPtr 10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10023 const xmlChar *schemaLocation, 10024 const xmlChar *targetNamespace) 10025 { 10026 xmlSchemaBucketPtr cur; 10027 xmlSchemaItemListPtr list; 10028 10029 list = pctxt->constructor->buckets; 10030 if (list->nbItems == 0) 10031 return(NULL); 10032 else { 10033 int i; 10034 for (i = 0; i < list->nbItems; i++) { 10035 cur = (xmlSchemaBucketPtr) list->items[i]; 10036 /* Pointer comparison! */ 10037 if ((cur->origTargetNamespace == NULL) && 10038 (cur->schemaLocation == schemaLocation) && 10039 (cur->targetNamespace == targetNamespace)) 10040 return(cur); 10041 } 10042 } 10043 return(NULL); 10044 } 10045 10046 10047 #define IS_BAD_SCHEMA_DOC(b) \ 10048 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10049 10050 static xmlSchemaBucketPtr 10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10052 const xmlChar *targetNamespace, 10053 int imported) 10054 { 10055 xmlSchemaBucketPtr cur; 10056 xmlSchemaItemListPtr list; 10057 10058 list = pctxt->constructor->buckets; 10059 if (list->nbItems == 0) 10060 return(NULL); 10061 else { 10062 int i; 10063 for (i = 0; i < list->nbItems; i++) { 10064 cur = (xmlSchemaBucketPtr) list->items[i]; 10065 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10066 (cur->origTargetNamespace == targetNamespace) && 10067 ((imported && cur->imported) || 10068 ((!imported) && (!cur->imported)))) 10069 return(cur); 10070 } 10071 } 10072 return(NULL); 10073 } 10074 10075 static int 10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10077 xmlSchemaPtr schema, 10078 xmlSchemaBucketPtr bucket) 10079 { 10080 int oldFlags; 10081 xmlDocPtr oldDoc; 10082 xmlNodePtr node; 10083 int ret, oldErrs; 10084 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10085 10086 /* 10087 * Save old values; reset the *main* schema. 10088 * URGENT TODO: This is not good; move the per-document information 10089 * to the parser. Get rid of passing the main schema to the 10090 * parsing functions. 10091 */ 10092 oldFlags = schema->flags; 10093 oldDoc = schema->doc; 10094 if (schema->flags != 0) 10095 xmlSchemaClearSchemaDefaults(schema); 10096 schema->doc = bucket->doc; 10097 pctxt->schema = schema; 10098 /* 10099 * Keep the current target namespace on the parser *not* on the 10100 * main schema. 10101 */ 10102 pctxt->targetNamespace = bucket->targetNamespace; 10103 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10104 10105 if ((bucket->targetNamespace != NULL) && 10106 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10107 /* 10108 * We are parsing the schema for schemas! 10109 */ 10110 pctxt->isS4S = 1; 10111 } 10112 /* Mark it as parsed, even if parsing fails. */ 10113 bucket->parsed++; 10114 /* Compile the schema doc. */ 10115 node = xmlDocGetRootElement(bucket->doc); 10116 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10117 if (ret != 0) 10118 goto exit; 10119 /* An empty schema; just get out. */ 10120 if (node->children == NULL) 10121 goto exit; 10122 oldErrs = pctxt->nberrors; 10123 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10124 if (ret != 0) 10125 goto exit; 10126 /* 10127 * TODO: Not nice, but I'm not 100% sure we will get always an error 10128 * as a result of the obove functions; so better rely on pctxt->err 10129 * as well. 10130 */ 10131 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10132 ret = pctxt->err; 10133 goto exit; 10134 } 10135 10136 exit: 10137 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10138 /* Restore schema values. */ 10139 schema->doc = oldDoc; 10140 schema->flags = oldFlags; 10141 return(ret); 10142 } 10143 10144 static int 10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10146 xmlSchemaPtr schema, 10147 xmlSchemaBucketPtr bucket) 10148 { 10149 xmlSchemaParserCtxtPtr newpctxt; 10150 int res = 0; 10151 10152 if (bucket == NULL) 10153 return(0); 10154 if (bucket->parsed) { 10155 PERROR_INT("xmlSchemaParseNewDoc", 10156 "reparsing a schema doc"); 10157 return(-1); 10158 } 10159 if (bucket->doc == NULL) { 10160 PERROR_INT("xmlSchemaParseNewDoc", 10161 "parsing a schema doc, but there's no doc"); 10162 return(-1); 10163 } 10164 if (pctxt->constructor == NULL) { 10165 PERROR_INT("xmlSchemaParseNewDoc", 10166 "no constructor"); 10167 return(-1); 10168 } 10169 /* Create and init the temporary parser context. */ 10170 newpctxt = xmlSchemaNewParserCtxtUseDict( 10171 (const char *) bucket->schemaLocation, pctxt->dict); 10172 if (newpctxt == NULL) 10173 return(-1); 10174 newpctxt->constructor = pctxt->constructor; 10175 /* 10176 * TODO: Can we avoid that the parser knows about the main schema? 10177 * It would be better if he knows about the current schema bucket 10178 * only. 10179 */ 10180 newpctxt->schema = schema; 10181 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10182 pctxt->errCtxt); 10183 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10184 pctxt->errCtxt); 10185 newpctxt->counter = pctxt->counter; 10186 10187 10188 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10189 10190 /* Channel back errors and cleanup the temporary parser context. */ 10191 if (res != 0) 10192 pctxt->err = res; 10193 pctxt->nberrors += newpctxt->nberrors; 10194 pctxt->counter = newpctxt->counter; 10195 newpctxt->constructor = NULL; 10196 /* Free the parser context. */ 10197 xmlSchemaFreeParserCtxt(newpctxt); 10198 return(res); 10199 } 10200 10201 static void 10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10203 xmlSchemaSchemaRelationPtr rel) 10204 { 10205 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10206 10207 if (cur == NULL) { 10208 bucket->relations = rel; 10209 return; 10210 } 10211 while (cur->next != NULL) 10212 cur = cur->next; 10213 cur->next = rel; 10214 } 10215 10216 10217 static const xmlChar * 10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10219 xmlNodePtr ctxtNode) 10220 { 10221 /* 10222 * Build an absolue location URI. 10223 */ 10224 if (location != NULL) { 10225 if (ctxtNode == NULL) 10226 return(location); 10227 else { 10228 xmlChar *base, *URI; 10229 const xmlChar *ret = NULL; 10230 10231 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10232 if (base == NULL) { 10233 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10234 } else { 10235 URI = xmlBuildURI(location, base); 10236 xmlFree(base); 10237 } 10238 if (URI != NULL) { 10239 ret = xmlDictLookup(dict, URI, -1); 10240 xmlFree(URI); 10241 return(ret); 10242 } 10243 } 10244 } 10245 return(NULL); 10246 } 10247 10248 10249 10250 /** 10251 * xmlSchemaAddSchemaDoc: 10252 * @pctxt: a schema validation context 10253 * @schema: the schema being built 10254 * @node: a subtree containing XML Schema informations 10255 * 10256 * Parse an included (and to-be-redefined) XML schema document. 10257 * 10258 * Returns 0 on success, a positive error code on errors and 10259 * -1 in case of an internal or API error. 10260 */ 10261 10262 static int 10263 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10264 int type, /* import or include or redefine */ 10265 const xmlChar *schemaLocation, 10266 xmlDocPtr schemaDoc, 10267 const char *schemaBuffer, 10268 int schemaBufferLen, 10269 xmlNodePtr invokingNode, 10270 const xmlChar *sourceTargetNamespace, 10271 const xmlChar *importNamespace, 10272 xmlSchemaBucketPtr *bucket) 10273 { 10274 const xmlChar *targetNamespace = NULL; 10275 xmlSchemaSchemaRelationPtr relation = NULL; 10276 xmlDocPtr doc = NULL; 10277 int res = 0, err = 0, located = 0, preserveDoc = 0; 10278 xmlSchemaBucketPtr bkt = NULL; 10279 10280 if (bucket != NULL) 10281 *bucket = NULL; 10282 10283 switch (type) { 10284 case XML_SCHEMA_SCHEMA_IMPORT: 10285 case XML_SCHEMA_SCHEMA_MAIN: 10286 err = XML_SCHEMAP_SRC_IMPORT; 10287 break; 10288 case XML_SCHEMA_SCHEMA_INCLUDE: 10289 err = XML_SCHEMAP_SRC_INCLUDE; 10290 break; 10291 case XML_SCHEMA_SCHEMA_REDEFINE: 10292 err = XML_SCHEMAP_SRC_REDEFINE; 10293 break; 10294 } 10295 10296 10297 /* Special handling for the main schema: 10298 * skip the location and relation logic and just parse the doc. 10299 * We need just a bucket to be returned in this case. 10300 */ 10301 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10302 goto doc_load; 10303 10304 /* Note that we expect the location to be an absulute URI. */ 10305 if (schemaLocation != NULL) { 10306 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10307 if ((bkt != NULL) && 10308 (pctxt->constructor->bucket == bkt)) { 10309 /* Report self-imports/inclusions/redefinitions. */ 10310 10311 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10312 invokingNode, NULL, 10313 "The schema must not import/include/redefine itself", 10314 NULL, NULL); 10315 goto exit; 10316 } 10317 } 10318 /* 10319 * Create a relation for the graph of schemas. 10320 */ 10321 relation = xmlSchemaSchemaRelationCreate(); 10322 if (relation == NULL) 10323 return(-1); 10324 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10325 relation); 10326 relation->type = type; 10327 10328 /* 10329 * Save the namespace import information. 10330 */ 10331 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10332 relation->importNamespace = importNamespace; 10333 if (schemaLocation == NULL) { 10334 /* 10335 * No location; this is just an import of the namespace. 10336 * Note that we don't assign a bucket to the relation 10337 * in this case. 10338 */ 10339 goto exit; 10340 } 10341 targetNamespace = importNamespace; 10342 } 10343 10344 /* Did we already fetch the doc? */ 10345 if (bkt != NULL) { 10346 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10347 /* 10348 * We included/redefined and then try to import a schema, 10349 * but the new location provided for import was different. 10350 */ 10351 if (schemaLocation == NULL) 10352 schemaLocation = BAD_CAST "in_memory_buffer"; 10353 if (!xmlStrEqual(schemaLocation, 10354 bkt->schemaLocation)) { 10355 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10356 invokingNode, NULL, 10357 "The schema document '%s' cannot be imported, since " 10358 "it was already included or redefined", 10359 schemaLocation, NULL); 10360 goto exit; 10361 } 10362 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10363 /* 10364 * We imported and then try to include/redefine a schema, 10365 * but the new location provided for the include/redefine 10366 * was different. 10367 */ 10368 if (schemaLocation == NULL) 10369 schemaLocation = BAD_CAST "in_memory_buffer"; 10370 if (!xmlStrEqual(schemaLocation, 10371 bkt->schemaLocation)) { 10372 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10373 invokingNode, NULL, 10374 "The schema document '%s' cannot be included or " 10375 "redefined, since it was already imported", 10376 schemaLocation, NULL); 10377 goto exit; 10378 } 10379 } 10380 } 10381 10382 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10383 /* 10384 * Given that the schemaLocation [attribute] is only a hint, it is open 10385 * to applications to ignore all but the first <import> for a given 10386 * namespace, regardless of the actual value of schemaLocation, but 10387 * such a strategy risks missing useful information when new 10388 * schemaLocations are offered. 10389 * 10390 * We will use the first <import> that comes with a location. 10391 * Further <import>s *with* a location, will result in an error. 10392 * TODO: Better would be to just report a warning here, but 10393 * we'll try it this way until someone complains. 10394 * 10395 * Schema Document Location Strategy: 10396 * 3 Based on the namespace name, identify an existing schema document, 10397 * either as a resource which is an XML document or a <schema> element 10398 * information item, in some local schema repository; 10399 * 5 Attempt to resolve the namespace name to locate such a resource. 10400 * 10401 * NOTE: (3) and (5) are not supported. 10402 */ 10403 if (bkt != NULL) { 10404 relation->bucket = bkt; 10405 goto exit; 10406 } 10407 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10408 importNamespace, 1); 10409 10410 if (bkt != NULL) { 10411 relation->bucket = bkt; 10412 if (bkt->schemaLocation == NULL) { 10413 /* First given location of the schema; load the doc. */ 10414 bkt->schemaLocation = schemaLocation; 10415 } else { 10416 if (!xmlStrEqual(schemaLocation, 10417 bkt->schemaLocation)) { 10418 /* 10419 * Additional location given; just skip it. 10420 * URGENT TODO: We should report a warning here. 10421 * res = XML_SCHEMAP_SRC_IMPORT; 10422 */ 10423 if (schemaLocation == NULL) 10424 schemaLocation = BAD_CAST "in_memory_buffer"; 10425 10426 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10427 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10428 invokingNode, NULL, 10429 "Skipping import of schema located at '%s' for the " 10430 "namespace '%s', since this namespace was already " 10431 "imported with the schema located at '%s'", 10432 schemaLocation, importNamespace, bkt->schemaLocation); 10433 } 10434 goto exit; 10435 } 10436 } 10437 /* 10438 * No bucket + first location: load the doc and create a 10439 * bucket. 10440 */ 10441 } else { 10442 /* <include> and <redefine> */ 10443 if (bkt != NULL) { 10444 10445 if ((bkt->origTargetNamespace == NULL) && 10446 (bkt->targetNamespace != sourceTargetNamespace)) { 10447 xmlSchemaBucketPtr chamel; 10448 10449 /* 10450 * Chameleon include/redefine: skip loading only if it was 10451 * aleady build for the targetNamespace of the including 10452 * schema. 10453 */ 10454 /* 10455 * URGENT TODO: If the schema is a chameleon-include then copy 10456 * the components into the including schema and modify the 10457 * targetNamespace of those components, do nothing otherwise. 10458 * NOTE: This is currently worked-around by compiling the 10459 * chameleon for every destinct including targetNamespace; thus 10460 * not performant at the moment. 10461 * TODO: Check when the namespace in wildcards for chameleons 10462 * needs to be converted: before we built wildcard intersections 10463 * or after. 10464 * Answer: after! 10465 */ 10466 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10467 schemaLocation, sourceTargetNamespace); 10468 if (chamel != NULL) { 10469 /* A fitting chameleon was already parsed; NOP. */ 10470 relation->bucket = chamel; 10471 goto exit; 10472 } 10473 /* 10474 * We need to parse the chameleon again for a different 10475 * targetNamespace. 10476 * CHAMELEON TODO: Optimize this by only parsing the 10477 * chameleon once, and then copying the components to 10478 * the new targetNamespace. 10479 */ 10480 bkt = NULL; 10481 } else { 10482 relation->bucket = bkt; 10483 goto exit; 10484 } 10485 } 10486 } 10487 if ((bkt != NULL) && (bkt->doc != NULL)) { 10488 PERROR_INT("xmlSchemaAddSchemaDoc", 10489 "trying to load a schema doc, but a doc is already " 10490 "assigned to the schema bucket"); 10491 goto exit_failure; 10492 } 10493 10494 doc_load: 10495 /* 10496 * Load the document. 10497 */ 10498 if (schemaDoc != NULL) { 10499 doc = schemaDoc; 10500 /* Don' free this one, since it was provided by the caller. */ 10501 preserveDoc = 1; 10502 /* TODO: Does the context or the doc hold the location? */ 10503 if (schemaDoc->URL != NULL) 10504 schemaLocation = xmlDictLookup(pctxt->dict, 10505 schemaDoc->URL, -1); 10506 else 10507 schemaLocation = BAD_CAST "in_memory_buffer"; 10508 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10509 xmlParserCtxtPtr parserCtxt; 10510 10511 parserCtxt = xmlNewParserCtxt(); 10512 if (parserCtxt == NULL) { 10513 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10514 "allocating a parser context", NULL); 10515 goto exit_failure; 10516 } 10517 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10518 /* 10519 * TODO: Do we have to burden the schema parser dict with all 10520 * the content of the schema doc? 10521 */ 10522 xmlDictFree(parserCtxt->dict); 10523 parserCtxt->dict = pctxt->dict; 10524 xmlDictReference(parserCtxt->dict); 10525 } 10526 if (schemaLocation != NULL) { 10527 /* Parse from file. */ 10528 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10529 NULL, SCHEMAS_PARSE_OPTIONS); 10530 } else if (schemaBuffer != NULL) { 10531 /* Parse from memory buffer. */ 10532 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10533 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10534 schemaLocation = BAD_CAST "in_memory_buffer"; 10535 if (doc != NULL) 10536 doc->URL = xmlStrdup(schemaLocation); 10537 } 10538 /* 10539 * For <import>: 10540 * 2.1 The referent is (a fragment of) a resource which is an 10541 * XML document (see clause 1.1), which in turn corresponds to 10542 * a <schema> element information item in a well-formed information 10543 * set, which in turn corresponds to a valid schema. 10544 * TODO: (2.1) fragments of XML documents are not supported. 10545 * 10546 * 2.2 The referent is a <schema> element information item in 10547 * a well-formed information set, which in turn corresponds 10548 * to a valid schema. 10549 * TODO: (2.2) is not supported. 10550 */ 10551 if (doc == NULL) { 10552 xmlErrorPtr lerr; 10553 lerr = xmlGetLastError(); 10554 /* 10555 * Check if this a parser error, or if the document could 10556 * just not be located. 10557 * TODO: Try to find specific error codes to react only on 10558 * localisation failures. 10559 */ 10560 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10561 /* 10562 * We assume a parser error here. 10563 */ 10564 located = 1; 10565 /* TODO: Error code ?? */ 10566 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10567 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10568 invokingNode, NULL, 10569 "Failed to parse the XML resource '%s'", 10570 schemaLocation, NULL); 10571 } 10572 } 10573 xmlFreeParserCtxt(parserCtxt); 10574 if ((doc == NULL) && located) 10575 goto exit_error; 10576 } else { 10577 xmlSchemaPErr(pctxt, NULL, 10578 XML_SCHEMAP_NOTHING_TO_PARSE, 10579 "No information for parsing was provided with the " 10580 "given schema parser context.\n", 10581 NULL, NULL); 10582 goto exit_failure; 10583 } 10584 /* 10585 * Preprocess the document. 10586 */ 10587 if (doc != NULL) { 10588 xmlNodePtr docElem = NULL; 10589 10590 located = 1; 10591 docElem = xmlDocGetRootElement(doc); 10592 if (docElem == NULL) { 10593 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10594 invokingNode, NULL, 10595 "The document '%s' has no document element", 10596 schemaLocation, NULL); 10597 goto exit_error; 10598 } 10599 /* 10600 * Remove all the blank text nodes. 10601 */ 10602 xmlSchemaCleanupDoc(pctxt, docElem); 10603 /* 10604 * Check the schema's top level element. 10605 */ 10606 if (!IS_SCHEMA(docElem, "schema")) { 10607 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10608 invokingNode, NULL, 10609 "The XML document '%s' is not a schema document", 10610 schemaLocation, NULL); 10611 goto exit_error; 10612 } 10613 /* 10614 * Note that we don't apply a type check for the 10615 * targetNamespace value here. 10616 */ 10617 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10618 "targetNamespace"); 10619 } 10620 10621 /* after_doc_loading: */ 10622 if ((bkt == NULL) && located) { 10623 /* Only create a bucket if the schema was located. */ 10624 bkt = xmlSchemaBucketCreate(pctxt, type, 10625 targetNamespace); 10626 if (bkt == NULL) 10627 goto exit_failure; 10628 } 10629 if (bkt != NULL) { 10630 bkt->schemaLocation = schemaLocation; 10631 bkt->located = located; 10632 if (doc != NULL) { 10633 bkt->doc = doc; 10634 bkt->targetNamespace = targetNamespace; 10635 bkt->origTargetNamespace = targetNamespace; 10636 if (preserveDoc) 10637 bkt->preserveDoc = 1; 10638 } 10639 if (WXS_IS_BUCKET_IMPMAIN(type)) 10640 bkt->imported++; 10641 /* 10642 * Add it to the graph of schemas. 10643 */ 10644 if (relation != NULL) 10645 relation->bucket = bkt; 10646 } 10647 10648 exit: 10649 /* 10650 * Return the bucket explicitely; this is needed for the 10651 * main schema. 10652 */ 10653 if (bucket != NULL) 10654 *bucket = bkt; 10655 return (0); 10656 10657 exit_error: 10658 if ((doc != NULL) && (! preserveDoc)) { 10659 xmlFreeDoc(doc); 10660 if (bkt != NULL) 10661 bkt->doc = NULL; 10662 } 10663 return(pctxt->err); 10664 10665 exit_failure: 10666 if ((doc != NULL) && (! preserveDoc)) { 10667 xmlFreeDoc(doc); 10668 if (bkt != NULL) 10669 bkt->doc = NULL; 10670 } 10671 return (-1); 10672 } 10673 10674 /** 10675 * xmlSchemaParseImport: 10676 * @ctxt: a schema validation context 10677 * @schema: the schema being built 10678 * @node: a subtree containing XML Schema informations 10679 * 10680 * parse a XML schema Import definition 10681 * *WARNING* this interface is highly subject to change 10682 * 10683 * Returns 0 in case of success, a positive error code if 10684 * not valid and -1 in case of an internal error. 10685 */ 10686 static int 10687 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10688 xmlNodePtr node) 10689 { 10690 xmlNodePtr child; 10691 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10692 const xmlChar *thisTargetNamespace; 10693 xmlAttrPtr attr; 10694 int ret = 0; 10695 xmlSchemaBucketPtr bucket = NULL; 10696 10697 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10698 return (-1); 10699 10700 /* 10701 * Check for illegal attributes. 10702 */ 10703 attr = node->properties; 10704 while (attr != NULL) { 10705 if (attr->ns == NULL) { 10706 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10707 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10708 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10709 xmlSchemaPIllegalAttrErr(pctxt, 10710 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10711 } 10712 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10713 xmlSchemaPIllegalAttrErr(pctxt, 10714 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10715 } 10716 attr = attr->next; 10717 } 10718 /* 10719 * Extract and validate attributes. 10720 */ 10721 if (xmlSchemaPValAttr(pctxt, NULL, node, 10722 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10723 &namespaceName) != 0) { 10724 xmlSchemaPSimpleTypeErr(pctxt, 10725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10726 NULL, node, 10727 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10728 NULL, namespaceName, NULL, NULL, NULL); 10729 return (pctxt->err); 10730 } 10731 10732 if (xmlSchemaPValAttr(pctxt, NULL, node, 10733 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10734 &schemaLocation) != 0) { 10735 xmlSchemaPSimpleTypeErr(pctxt, 10736 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10737 NULL, node, 10738 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10739 NULL, namespaceName, NULL, NULL, NULL); 10740 return (pctxt->err); 10741 } 10742 /* 10743 * And now for the children... 10744 */ 10745 child = node->children; 10746 if (IS_SCHEMA(child, "annotation")) { 10747 /* 10748 * the annotation here is simply discarded ... 10749 * TODO: really? 10750 */ 10751 child = child->next; 10752 } 10753 if (child != NULL) { 10754 xmlSchemaPContentErr(pctxt, 10755 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10756 NULL, node, child, NULL, 10757 "(annotation?)"); 10758 } 10759 /* 10760 * Apply additional constraints. 10761 * 10762 * Note that it is important to use the original @targetNamespace 10763 * (or none at all), to rule out imports of schemas _with_ a 10764 * @targetNamespace if the importing schema is a chameleon schema 10765 * (with no @targetNamespace). 10766 */ 10767 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10768 if (namespaceName != NULL) { 10769 /* 10770 * 1.1 If the namespace [attribute] is present, then its actual value 10771 * must not match the actual value of the enclosing <schema>'s 10772 * targetNamespace [attribute]. 10773 */ 10774 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10775 xmlSchemaPCustomErr(pctxt, 10776 XML_SCHEMAP_SRC_IMPORT_1_1, 10777 NULL, node, 10778 "The value of the attribute 'namespace' must not match " 10779 "the target namespace '%s' of the importing schema", 10780 thisTargetNamespace); 10781 return (pctxt->err); 10782 } 10783 } else { 10784 /* 10785 * 1.2 If the namespace [attribute] is not present, then the enclosing 10786 * <schema> must have a targetNamespace [attribute]. 10787 */ 10788 if (thisTargetNamespace == NULL) { 10789 xmlSchemaPCustomErr(pctxt, 10790 XML_SCHEMAP_SRC_IMPORT_1_2, 10791 NULL, node, 10792 "The attribute 'namespace' must be existent if " 10793 "the importing schema has no target namespace", 10794 NULL); 10795 return (pctxt->err); 10796 } 10797 } 10798 /* 10799 * Locate and acquire the schema document. 10800 */ 10801 if (schemaLocation != NULL) 10802 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10803 schemaLocation, node); 10804 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10805 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10806 namespaceName, &bucket); 10807 10808 if (ret != 0) 10809 return(ret); 10810 10811 /* 10812 * For <import>: "It is *not* an error for the application 10813 * schema reference strategy to fail." 10814 * So just don't parse if no schema document was found. 10815 * Note that we will get no bucket if the schema could not be 10816 * located or if there was no schemaLocation. 10817 */ 10818 if ((bucket == NULL) && (schemaLocation != NULL)) { 10819 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10820 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10821 node, NULL, 10822 "Failed to locate a schema at location '%s'. " 10823 "Skipping the import", schemaLocation, NULL, NULL); 10824 } 10825 10826 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10827 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10828 } 10829 10830 return (ret); 10831 } 10832 10833 static int 10834 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10835 xmlSchemaPtr schema, 10836 xmlNodePtr node, 10837 xmlChar **schemaLocation, 10838 int type) 10839 { 10840 xmlAttrPtr attr; 10841 10842 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10843 (schemaLocation == NULL)) 10844 return (-1); 10845 10846 *schemaLocation = NULL; 10847 /* 10848 * Check for illegal attributes. 10849 * Applies for both <include> and <redefine>. 10850 */ 10851 attr = node->properties; 10852 while (attr != NULL) { 10853 if (attr->ns == NULL) { 10854 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10855 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10856 xmlSchemaPIllegalAttrErr(pctxt, 10857 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10858 } 10859 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10860 xmlSchemaPIllegalAttrErr(pctxt, 10861 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10862 } 10863 attr = attr->next; 10864 } 10865 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10866 /* 10867 * Preliminary step, extract the URI-Reference and make an URI 10868 * from the base. 10869 */ 10870 /* 10871 * Attribute "schemaLocation" is mandatory. 10872 */ 10873 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10874 if (attr != NULL) { 10875 xmlChar *base = NULL; 10876 xmlChar *uri = NULL; 10877 10878 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10879 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10880 (const xmlChar **) schemaLocation) != 0) 10881 goto exit_error; 10882 base = xmlNodeGetBase(node->doc, node); 10883 if (base == NULL) { 10884 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10885 } else { 10886 uri = xmlBuildURI(*schemaLocation, base); 10887 xmlFree(base); 10888 } 10889 if (uri == NULL) { 10890 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10891 "could not build an URI from the schemaLocation") 10892 goto exit_failure; 10893 } 10894 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10895 xmlFree(uri); 10896 } else { 10897 xmlSchemaPMissingAttrErr(pctxt, 10898 XML_SCHEMAP_S4S_ATTR_MISSING, 10899 NULL, node, "schemaLocation", NULL); 10900 goto exit_error; 10901 } 10902 /* 10903 * Report self-inclusion and self-redefinition. 10904 */ 10905 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10906 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10907 xmlSchemaPCustomErr(pctxt, 10908 XML_SCHEMAP_SRC_REDEFINE, 10909 NULL, node, 10910 "The schema document '%s' cannot redefine itself.", 10911 *schemaLocation); 10912 } else { 10913 xmlSchemaPCustomErr(pctxt, 10914 XML_SCHEMAP_SRC_INCLUDE, 10915 NULL, node, 10916 "The schema document '%s' cannot include itself.", 10917 *schemaLocation); 10918 } 10919 goto exit_error; 10920 } 10921 10922 return(0); 10923 exit_error: 10924 return(pctxt->err); 10925 exit_failure: 10926 return(-1); 10927 } 10928 10929 static int 10930 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10931 xmlSchemaPtr schema, 10932 xmlNodePtr node, 10933 int type) 10934 { 10935 xmlNodePtr child = NULL; 10936 const xmlChar *schemaLocation = NULL; 10937 int res = 0; /* hasRedefinitions = 0 */ 10938 int isChameleon = 0, wasChameleon = 0; 10939 xmlSchemaBucketPtr bucket = NULL; 10940 10941 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10942 return (-1); 10943 10944 /* 10945 * Parse attributes. Note that the returned schemaLocation will 10946 * be already converted to an absolute URI. 10947 */ 10948 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10949 node, (xmlChar **) (&schemaLocation), type); 10950 if (res != 0) 10951 return(res); 10952 /* 10953 * Load and add the schema document. 10954 */ 10955 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10956 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10957 if (res != 0) 10958 return(res); 10959 /* 10960 * If we get no schema bucket back, then this means that the schema 10961 * document could not be located or was broken XML or was not 10962 * a schema document. 10963 */ 10964 if ((bucket == NULL) || (bucket->doc == NULL)) { 10965 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 10966 /* 10967 * WARNING for <include>: 10968 * We will raise an error if the schema cannot be located 10969 * for inclusions, since the that was the feedback from the 10970 * schema people. I.e. the following spec piece will *not* be 10971 * satisfied: 10972 * SPEC src-include: "It is not an error for the actual value of the 10973 * schemaLocation [attribute] to fail to resolve it all, in which 10974 * case no corresponding inclusion is performed. 10975 * So do we need a warning report here?" 10976 */ 10977 res = XML_SCHEMAP_SRC_INCLUDE; 10978 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10979 node, NULL, 10980 "Failed to load the document '%s' for inclusion", 10981 schemaLocation, NULL); 10982 } else { 10983 /* 10984 * NOTE: This was changed to raise an error even if no redefinitions 10985 * are specified. 10986 * 10987 * SPEC src-redefine (1) 10988 * "If there are any element information items among the [children] 10989 * other than <annotation> then the actual value of the 10990 * schemaLocation [attribute] must successfully resolve." 10991 * TODO: Ask the WG if a the location has always to resolve 10992 * here as well! 10993 */ 10994 res = XML_SCHEMAP_SRC_REDEFINE; 10995 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10996 node, NULL, 10997 "Failed to load the document '%s' for redefinition", 10998 schemaLocation, NULL); 10999 } 11000 } else { 11001 /* 11002 * Check targetNamespace sanity before parsing the new schema. 11003 * TODO: Note that we won't check further content if the 11004 * targetNamespace was bad. 11005 */ 11006 if (bucket->origTargetNamespace != NULL) { 11007 /* 11008 * SPEC src-include (2.1) 11009 * "SII has a targetNamespace [attribute], and its actual 11010 * value is identical to the actual value of the targetNamespace 11011 * [attribute] of SII (which must have such an [attribute])." 11012 */ 11013 if (pctxt->targetNamespace == NULL) { 11014 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11015 XML_SCHEMAP_SRC_INCLUDE, 11016 node, NULL, 11017 "The target namespace of the included/redefined schema " 11018 "'%s' has to be absent, since the including/redefining " 11019 "schema has no target namespace", 11020 schemaLocation, NULL); 11021 goto exit_error; 11022 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11023 pctxt->targetNamespace)) { 11024 /* TODO: Change error function. */ 11025 xmlSchemaPCustomErrExt(pctxt, 11026 XML_SCHEMAP_SRC_INCLUDE, 11027 NULL, node, 11028 "The target namespace '%s' of the included/redefined " 11029 "schema '%s' differs from '%s' of the " 11030 "including/redefining schema", 11031 bucket->origTargetNamespace, schemaLocation, 11032 pctxt->targetNamespace); 11033 goto exit_error; 11034 } 11035 } else if (pctxt->targetNamespace != NULL) { 11036 /* 11037 * Chameleons: the original target namespace will 11038 * differ from the resulting namespace. 11039 */ 11040 isChameleon = 1; 11041 if (bucket->parsed && 11042 bucket->origTargetNamespace != NULL) { 11043 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11044 XML_SCHEMAP_SRC_INCLUDE, 11045 node, NULL, 11046 "The target namespace of the included/redefined schema " 11047 "'%s' has to be absent or the same as the " 11048 "including/redefining schema's target namespace", 11049 schemaLocation, NULL); 11050 goto exit_error; 11051 } 11052 bucket->targetNamespace = pctxt->targetNamespace; 11053 } 11054 } 11055 /* 11056 * Parse the schema. 11057 */ 11058 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11059 if (isChameleon) { 11060 /* TODO: Get rid of this flag on the schema itself. */ 11061 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11062 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11063 } else 11064 wasChameleon = 1; 11065 } 11066 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11067 /* Restore chameleon flag. */ 11068 if (isChameleon && (!wasChameleon)) 11069 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11070 } 11071 /* 11072 * And now for the children... 11073 */ 11074 child = node->children; 11075 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11076 /* 11077 * Parse (simpleType | complexType | group | attributeGroup))* 11078 */ 11079 pctxt->redefined = bucket; 11080 /* 11081 * How to proceed if the redefined schema was not located? 11082 */ 11083 pctxt->isRedefine = 1; 11084 while (IS_SCHEMA(child, "annotation") || 11085 IS_SCHEMA(child, "simpleType") || 11086 IS_SCHEMA(child, "complexType") || 11087 IS_SCHEMA(child, "group") || 11088 IS_SCHEMA(child, "attributeGroup")) { 11089 if (IS_SCHEMA(child, "annotation")) { 11090 /* 11091 * TODO: discard or not? 11092 */ 11093 } else if (IS_SCHEMA(child, "simpleType")) { 11094 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11095 } else if (IS_SCHEMA(child, "complexType")) { 11096 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11097 /* hasRedefinitions = 1; */ 11098 } else if (IS_SCHEMA(child, "group")) { 11099 /* hasRedefinitions = 1; */ 11100 xmlSchemaParseModelGroupDefinition(pctxt, 11101 schema, child); 11102 } else if (IS_SCHEMA(child, "attributeGroup")) { 11103 /* hasRedefinitions = 1; */ 11104 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11105 child); 11106 } 11107 child = child->next; 11108 } 11109 pctxt->redefined = NULL; 11110 pctxt->isRedefine = 0; 11111 } else { 11112 if (IS_SCHEMA(child, "annotation")) { 11113 /* 11114 * TODO: discard or not? 11115 */ 11116 child = child->next; 11117 } 11118 } 11119 if (child != NULL) { 11120 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11121 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11122 xmlSchemaPContentErr(pctxt, res, 11123 NULL, node, child, NULL, 11124 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11125 } else { 11126 xmlSchemaPContentErr(pctxt, res, 11127 NULL, node, child, NULL, 11128 "(annotation?)"); 11129 } 11130 } 11131 return(res); 11132 11133 exit_error: 11134 return(pctxt->err); 11135 } 11136 11137 static int 11138 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11139 xmlNodePtr node) 11140 { 11141 int res; 11142 #ifndef ENABLE_REDEFINE 11143 TODO 11144 return(0); 11145 #endif 11146 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11147 XML_SCHEMA_SCHEMA_REDEFINE); 11148 if (res != 0) 11149 return(res); 11150 return(0); 11151 } 11152 11153 static int 11154 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11155 xmlNodePtr node) 11156 { 11157 int res; 11158 11159 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11160 XML_SCHEMA_SCHEMA_INCLUDE); 11161 if (res != 0) 11162 return(res); 11163 return(0); 11164 } 11165 11166 /** 11167 * xmlSchemaParseModelGroup: 11168 * @ctxt: a schema validation context 11169 * @schema: the schema being built 11170 * @node: a subtree containing XML Schema informations 11171 * @type: the "compositor" type 11172 * @particleNeeded: if a a model group with a particle 11173 * 11174 * parse a XML schema Sequence definition. 11175 * Applies parts of: 11176 * Schema Representation Constraint: 11177 * Redefinition Constraints and Semantics (src-redefine) 11178 * (6.1), (6.1.1), (6.1.2) 11179 * 11180 * Schema Component Constraint: 11181 * All Group Limited (cos-all-limited) (2) 11182 * TODO: Actually this should go to component-level checks, 11183 * but is done here due to performance. Move it to an other layer 11184 * is schema construction via an API is implemented. 11185 * 11186 * *WARNING* this interface is highly subject to change 11187 * 11188 * Returns -1 in case of error, 0 if the declaration is improper and 11189 * 1 in case of success. 11190 */ 11191 static xmlSchemaTreeItemPtr 11192 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11193 xmlNodePtr node, xmlSchemaTypeType type, 11194 int withParticle) 11195 { 11196 xmlSchemaModelGroupPtr item; 11197 xmlSchemaParticlePtr particle = NULL; 11198 xmlNodePtr child = NULL; 11199 xmlAttrPtr attr; 11200 int min = 1, max = 1, isElemRef, hasRefs = 0; 11201 11202 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11203 return (NULL); 11204 /* 11205 * Create a model group with the given compositor. 11206 */ 11207 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11208 if (item == NULL) 11209 return (NULL); 11210 11211 if (withParticle) { 11212 if (type == XML_SCHEMA_TYPE_ALL) { 11213 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11214 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11215 } else { 11216 /* choice + sequence */ 11217 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11218 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11219 "(xs:nonNegativeInteger | unbounded)"); 11220 } 11221 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11222 /* 11223 * Create a particle 11224 */ 11225 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11226 if (particle == NULL) 11227 return (NULL); 11228 particle->children = (xmlSchemaTreeItemPtr) item; 11229 /* 11230 * Check for illegal attributes. 11231 */ 11232 attr = node->properties; 11233 while (attr != NULL) { 11234 if (attr->ns == NULL) { 11235 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11236 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11237 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11238 xmlSchemaPIllegalAttrErr(ctxt, 11239 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11240 } 11241 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11242 xmlSchemaPIllegalAttrErr(ctxt, 11243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11244 } 11245 attr = attr->next; 11246 } 11247 } else { 11248 /* 11249 * Check for illegal attributes. 11250 */ 11251 attr = node->properties; 11252 while (attr != NULL) { 11253 if (attr->ns == NULL) { 11254 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11255 xmlSchemaPIllegalAttrErr(ctxt, 11256 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11257 } 11258 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11259 xmlSchemaPIllegalAttrErr(ctxt, 11260 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11261 } 11262 attr = attr->next; 11263 } 11264 } 11265 11266 /* 11267 * Extract and validate attributes. 11268 */ 11269 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11270 /* 11271 * And now for the children... 11272 */ 11273 child = node->children; 11274 if (IS_SCHEMA(child, "annotation")) { 11275 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11276 child = child->next; 11277 } 11278 if (type == XML_SCHEMA_TYPE_ALL) { 11279 xmlSchemaParticlePtr part, last = NULL; 11280 11281 while (IS_SCHEMA(child, "element")) { 11282 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11283 schema, child, &isElemRef, 0); 11284 /* 11285 * SPEC cos-all-limited (2) 11286 * "The {max occurs} of all the particles in the {particles} 11287 * of the ('all') group must be 0 or 1. 11288 */ 11289 if (part != NULL) { 11290 if (isElemRef) 11291 hasRefs++; 11292 if (part->minOccurs > 1) { 11293 xmlSchemaPCustomErr(ctxt, 11294 XML_SCHEMAP_COS_ALL_LIMITED, 11295 NULL, child, 11296 "Invalid value for minOccurs (must be 0 or 1)", 11297 NULL); 11298 /* Reset to 1. */ 11299 part->minOccurs = 1; 11300 } 11301 if (part->maxOccurs > 1) { 11302 xmlSchemaPCustomErr(ctxt, 11303 XML_SCHEMAP_COS_ALL_LIMITED, 11304 NULL, child, 11305 "Invalid value for maxOccurs (must be 0 or 1)", 11306 NULL); 11307 /* Reset to 1. */ 11308 part->maxOccurs = 1; 11309 } 11310 if (last == NULL) 11311 item->children = (xmlSchemaTreeItemPtr) part; 11312 else 11313 last->next = (xmlSchemaTreeItemPtr) part; 11314 last = part; 11315 } 11316 child = child->next; 11317 } 11318 if (child != NULL) { 11319 xmlSchemaPContentErr(ctxt, 11320 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11321 NULL, node, child, NULL, 11322 "(annotation?, (annotation?, element*)"); 11323 } 11324 } else { 11325 /* choice + sequence */ 11326 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11327 11328 while ((IS_SCHEMA(child, "element")) || 11329 (IS_SCHEMA(child, "group")) || 11330 (IS_SCHEMA(child, "any")) || 11331 (IS_SCHEMA(child, "choice")) || 11332 (IS_SCHEMA(child, "sequence"))) { 11333 11334 if (IS_SCHEMA(child, "element")) { 11335 part = (xmlSchemaTreeItemPtr) 11336 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11337 if (part && isElemRef) 11338 hasRefs++; 11339 } else if (IS_SCHEMA(child, "group")) { 11340 part = 11341 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11342 if (part != NULL) 11343 hasRefs++; 11344 /* 11345 * Handle redefinitions. 11346 */ 11347 if (ctxt->isRedefine && ctxt->redef && 11348 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11349 part && part->children) 11350 { 11351 if ((xmlSchemaGetQNameRefName(part->children) == 11352 ctxt->redef->refName) && 11353 (xmlSchemaGetQNameRefTargetNs(part->children) == 11354 ctxt->redef->refTargetNs)) 11355 { 11356 /* 11357 * SPEC src-redefine: 11358 * (6.1) "If it has a <group> among its contents at 11359 * some level the actual value of whose ref 11360 * [attribute] is the same as the actual value of 11361 * its own name attribute plus target namespace, then 11362 * all of the following must be true:" 11363 * (6.1.1) "It must have exactly one such group." 11364 */ 11365 if (ctxt->redefCounter != 0) { 11366 xmlChar *str = NULL; 11367 11368 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11369 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11370 "The redefining model group definition " 11371 "'%s' must not contain more than one " 11372 "reference to the redefined definition", 11373 xmlSchemaFormatQName(&str, 11374 ctxt->redef->refTargetNs, 11375 ctxt->redef->refName), 11376 NULL); 11377 FREE_AND_NULL(str) 11378 part = NULL; 11379 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11380 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11381 { 11382 xmlChar *str = NULL; 11383 /* 11384 * SPEC src-redefine: 11385 * (6.1.2) "The actual value of both that 11386 * group's minOccurs and maxOccurs [attribute] 11387 * must be 1 (or absent). 11388 */ 11389 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11390 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11391 "The redefining model group definition " 11392 "'%s' must not contain a reference to the " 11393 "redefined definition with a " 11394 "maxOccurs/minOccurs other than 1", 11395 xmlSchemaFormatQName(&str, 11396 ctxt->redef->refTargetNs, 11397 ctxt->redef->refName), 11398 NULL); 11399 FREE_AND_NULL(str) 11400 part = NULL; 11401 } 11402 ctxt->redef->reference = WXS_BASIC_CAST part; 11403 ctxt->redefCounter++; 11404 } 11405 } 11406 } else if (IS_SCHEMA(child, "any")) { 11407 part = (xmlSchemaTreeItemPtr) 11408 xmlSchemaParseAny(ctxt, schema, child); 11409 } else if (IS_SCHEMA(child, "choice")) { 11410 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11411 XML_SCHEMA_TYPE_CHOICE, 1); 11412 } else if (IS_SCHEMA(child, "sequence")) { 11413 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11414 XML_SCHEMA_TYPE_SEQUENCE, 1); 11415 } 11416 if (part != NULL) { 11417 if (last == NULL) 11418 item->children = part; 11419 else 11420 last->next = part; 11421 last = part; 11422 } 11423 child = child->next; 11424 } 11425 if (child != NULL) { 11426 xmlSchemaPContentErr(ctxt, 11427 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11428 NULL, node, child, NULL, 11429 "(annotation?, (element | group | choice | sequence | any)*)"); 11430 } 11431 } 11432 if ((max == 0) && (min == 0)) 11433 return (NULL); 11434 if (hasRefs) { 11435 /* 11436 * We need to resolve references. 11437 */ 11438 WXS_ADD_PENDING(ctxt, item); 11439 } 11440 if (withParticle) 11441 return ((xmlSchemaTreeItemPtr) particle); 11442 else 11443 return ((xmlSchemaTreeItemPtr) item); 11444 } 11445 11446 /** 11447 * xmlSchemaParseRestriction: 11448 * @ctxt: a schema validation context 11449 * @schema: the schema being built 11450 * @node: a subtree containing XML Schema informations 11451 * 11452 * parse a XML schema Restriction definition 11453 * *WARNING* this interface is highly subject to change 11454 * 11455 * Returns the type definition or NULL in case of error 11456 */ 11457 static xmlSchemaTypePtr 11458 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11459 xmlNodePtr node, xmlSchemaTypeType parentType) 11460 { 11461 xmlSchemaTypePtr type; 11462 xmlNodePtr child = NULL; 11463 xmlAttrPtr attr; 11464 11465 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11466 return (NULL); 11467 /* Not a component, don't create it. */ 11468 type = ctxt->ctxtType; 11469 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11470 11471 /* 11472 * Check for illegal attributes. 11473 */ 11474 attr = node->properties; 11475 while (attr != NULL) { 11476 if (attr->ns == NULL) { 11477 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11478 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11479 xmlSchemaPIllegalAttrErr(ctxt, 11480 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11481 } 11482 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11483 xmlSchemaPIllegalAttrErr(ctxt, 11484 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11485 } 11486 attr = attr->next; 11487 } 11488 /* 11489 * Extract and validate attributes. 11490 */ 11491 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11492 /* 11493 * Attribute 11494 */ 11495 /* 11496 * Extract the base type. The "base" attribute is mandatory if inside 11497 * a complex type or if redefining. 11498 * 11499 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11500 * among its [children]), the simple type definition which is 11501 * the {content type} of the type definition resolved to by 11502 * the actual value of the base [attribute]" 11503 */ 11504 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11505 &(type->baseNs), &(type->base)) == 0) 11506 { 11507 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11508 xmlSchemaPMissingAttrErr(ctxt, 11509 XML_SCHEMAP_S4S_ATTR_MISSING, 11510 NULL, node, "base", NULL); 11511 } else if ((ctxt->isRedefine) && 11512 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11513 { 11514 if (type->base == NULL) { 11515 xmlSchemaPMissingAttrErr(ctxt, 11516 XML_SCHEMAP_S4S_ATTR_MISSING, 11517 NULL, node, "base", NULL); 11518 } else if ((! xmlStrEqual(type->base, type->name)) || 11519 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11520 { 11521 xmlChar *str1 = NULL, *str2 = NULL; 11522 /* 11523 * REDEFINE: SPEC src-redefine (5) 11524 * "Within the [children], each <simpleType> must have a 11525 * <restriction> among its [children] ... the actual value of 11526 * whose base [attribute] must be the same as the actual value 11527 * of its own name attribute plus target namespace;" 11528 */ 11529 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11530 NULL, node, "This is a redefinition, but the QName " 11531 "value '%s' of the 'base' attribute does not match the " 11532 "type's designation '%s'", 11533 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11534 xmlSchemaFormatQName(&str2, type->targetNamespace, 11535 type->name), NULL); 11536 FREE_AND_NULL(str1); 11537 FREE_AND_NULL(str2); 11538 /* Avoid confusion and erase the values. */ 11539 type->base = NULL; 11540 type->baseNs = NULL; 11541 } 11542 } 11543 } 11544 /* 11545 * And now for the children... 11546 */ 11547 child = node->children; 11548 if (IS_SCHEMA(child, "annotation")) { 11549 /* 11550 * Add the annotation to the simple type ancestor. 11551 */ 11552 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11553 xmlSchemaParseAnnotation(ctxt, child, 1)); 11554 child = child->next; 11555 } 11556 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11557 /* 11558 * Corresponds to <simpleType><restriction><simpleType>. 11559 */ 11560 if (IS_SCHEMA(child, "simpleType")) { 11561 if (type->base != NULL) { 11562 /* 11563 * src-restriction-base-or-simpleType 11564 * Either the base [attribute] or the simpleType [child] of the 11565 * <restriction> element must be present, but not both. 11566 */ 11567 xmlSchemaPContentErr(ctxt, 11568 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11569 NULL, node, child, 11570 "The attribute 'base' and the <simpleType> child are " 11571 "mutually exclusive", NULL); 11572 } else { 11573 type->baseType = (xmlSchemaTypePtr) 11574 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11575 } 11576 child = child->next; 11577 } else if (type->base == NULL) { 11578 xmlSchemaPContentErr(ctxt, 11579 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11580 NULL, node, child, 11581 "Either the attribute 'base' or a <simpleType> child " 11582 "must be present", NULL); 11583 } 11584 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11585 /* 11586 * Corresponds to <complexType><complexContent><restriction>... 11587 * followed by: 11588 * 11589 * Model groups <all>, <choice> and <sequence>. 11590 */ 11591 if (IS_SCHEMA(child, "all")) { 11592 type->subtypes = (xmlSchemaTypePtr) 11593 xmlSchemaParseModelGroup(ctxt, schema, child, 11594 XML_SCHEMA_TYPE_ALL, 1); 11595 child = child->next; 11596 } else if (IS_SCHEMA(child, "choice")) { 11597 type->subtypes = (xmlSchemaTypePtr) 11598 xmlSchemaParseModelGroup(ctxt, 11599 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11600 child = child->next; 11601 } else if (IS_SCHEMA(child, "sequence")) { 11602 type->subtypes = (xmlSchemaTypePtr) 11603 xmlSchemaParseModelGroup(ctxt, schema, child, 11604 XML_SCHEMA_TYPE_SEQUENCE, 1); 11605 child = child->next; 11606 /* 11607 * Model group reference <group>. 11608 */ 11609 } else if (IS_SCHEMA(child, "group")) { 11610 type->subtypes = (xmlSchemaTypePtr) 11611 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11612 /* 11613 * Note that the reference will be resolved in 11614 * xmlSchemaResolveTypeReferences(); 11615 */ 11616 child = child->next; 11617 } 11618 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11619 /* 11620 * Corresponds to <complexType><simpleContent><restriction>... 11621 * 11622 * "1.1 the simple type definition corresponding to the <simpleType> 11623 * among the [children] of <restriction> if there is one;" 11624 */ 11625 if (IS_SCHEMA(child, "simpleType")) { 11626 /* 11627 * We will store the to-be-restricted simple type in 11628 * type->contentTypeDef *temporarily*. 11629 */ 11630 type->contentTypeDef = (xmlSchemaTypePtr) 11631 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11632 if ( type->contentTypeDef == NULL) 11633 return (NULL); 11634 child = child->next; 11635 } 11636 } 11637 11638 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11639 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11640 xmlSchemaFacetPtr facet, lastfacet = NULL; 11641 /* 11642 * Corresponds to <complexType><simpleContent><restriction>... 11643 * <simpleType><restriction>... 11644 */ 11645 11646 /* 11647 * Add the facets to the simple type ancestor. 11648 */ 11649 /* 11650 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11651 * Simple Type Definition Schema Representation Constraint: 11652 * *Single Facet Value* 11653 */ 11654 while ((IS_SCHEMA(child, "minInclusive")) || 11655 (IS_SCHEMA(child, "minExclusive")) || 11656 (IS_SCHEMA(child, "maxInclusive")) || 11657 (IS_SCHEMA(child, "maxExclusive")) || 11658 (IS_SCHEMA(child, "totalDigits")) || 11659 (IS_SCHEMA(child, "fractionDigits")) || 11660 (IS_SCHEMA(child, "pattern")) || 11661 (IS_SCHEMA(child, "enumeration")) || 11662 (IS_SCHEMA(child, "whiteSpace")) || 11663 (IS_SCHEMA(child, "length")) || 11664 (IS_SCHEMA(child, "maxLength")) || 11665 (IS_SCHEMA(child, "minLength"))) { 11666 facet = xmlSchemaParseFacet(ctxt, schema, child); 11667 if (facet != NULL) { 11668 if (lastfacet == NULL) 11669 type->facets = facet; 11670 else 11671 lastfacet->next = facet; 11672 lastfacet = facet; 11673 lastfacet->next = NULL; 11674 } 11675 child = child->next; 11676 } 11677 /* 11678 * Create links for derivation and validation. 11679 */ 11680 if (type->facets != NULL) { 11681 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11682 11683 facet = type->facets; 11684 do { 11685 facetLink = (xmlSchemaFacetLinkPtr) 11686 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11687 if (facetLink == NULL) { 11688 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11689 xmlFree(facetLink); 11690 return (NULL); 11691 } 11692 facetLink->facet = facet; 11693 facetLink->next = NULL; 11694 if (lastFacetLink == NULL) 11695 type->facetSet = facetLink; 11696 else 11697 lastFacetLink->next = facetLink; 11698 lastFacetLink = facetLink; 11699 facet = facet->next; 11700 } while (facet != NULL); 11701 } 11702 } 11703 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11704 /* 11705 * Attribute uses/declarations. 11706 */ 11707 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11708 (xmlSchemaItemListPtr *) &(type->attrUses), 11709 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11710 return(NULL); 11711 /* 11712 * Attribute wildcard. 11713 */ 11714 if (IS_SCHEMA(child, "anyAttribute")) { 11715 type->attributeWildcard = 11716 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11717 child = child->next; 11718 } 11719 } 11720 if (child != NULL) { 11721 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11722 xmlSchemaPContentErr(ctxt, 11723 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11724 NULL, node, child, NULL, 11725 "annotation?, (group | all | choice | sequence)?, " 11726 "((attribute | attributeGroup)*, anyAttribute?))"); 11727 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11728 xmlSchemaPContentErr(ctxt, 11729 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11730 NULL, node, child, NULL, 11731 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11732 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11733 "length | minLength | maxLength | enumeration | whiteSpace | " 11734 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11735 } else { 11736 /* Simple type */ 11737 xmlSchemaPContentErr(ctxt, 11738 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11739 NULL, node, child, NULL, 11740 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11741 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11742 "length | minLength | maxLength | enumeration | whiteSpace | " 11743 "pattern)*))"); 11744 } 11745 } 11746 return (NULL); 11747 } 11748 11749 /** 11750 * xmlSchemaParseExtension: 11751 * @ctxt: a schema validation context 11752 * @schema: the schema being built 11753 * @node: a subtree containing XML Schema informations 11754 * 11755 * Parses an <extension>, which is found inside a 11756 * <simpleContent> or <complexContent>. 11757 * *WARNING* this interface is highly subject to change. 11758 * 11759 * TODO: Returns the type definition or NULL in case of error 11760 */ 11761 static xmlSchemaTypePtr 11762 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11763 xmlNodePtr node, xmlSchemaTypeType parentType) 11764 { 11765 xmlSchemaTypePtr type; 11766 xmlNodePtr child = NULL; 11767 xmlAttrPtr attr; 11768 11769 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11770 return (NULL); 11771 /* Not a component, don't create it. */ 11772 type = ctxt->ctxtType; 11773 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11774 11775 /* 11776 * Check for illegal attributes. 11777 */ 11778 attr = node->properties; 11779 while (attr != NULL) { 11780 if (attr->ns == NULL) { 11781 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11782 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11783 xmlSchemaPIllegalAttrErr(ctxt, 11784 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11785 } 11786 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11787 xmlSchemaPIllegalAttrErr(ctxt, 11788 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11789 } 11790 attr = attr->next; 11791 } 11792 11793 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11794 11795 /* 11796 * Attribute "base" - mandatory. 11797 */ 11798 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11799 "base", &(type->baseNs), &(type->base)) == 0) && 11800 (type->base == NULL)) { 11801 xmlSchemaPMissingAttrErr(ctxt, 11802 XML_SCHEMAP_S4S_ATTR_MISSING, 11803 NULL, node, "base", NULL); 11804 } 11805 /* 11806 * And now for the children... 11807 */ 11808 child = node->children; 11809 if (IS_SCHEMA(child, "annotation")) { 11810 /* 11811 * Add the annotation to the type ancestor. 11812 */ 11813 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11814 xmlSchemaParseAnnotation(ctxt, child, 1)); 11815 child = child->next; 11816 } 11817 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11818 /* 11819 * Corresponds to <complexType><complexContent><extension>... and: 11820 * 11821 * Model groups <all>, <choice>, <sequence> and <group>. 11822 */ 11823 if (IS_SCHEMA(child, "all")) { 11824 type->subtypes = (xmlSchemaTypePtr) 11825 xmlSchemaParseModelGroup(ctxt, schema, 11826 child, XML_SCHEMA_TYPE_ALL, 1); 11827 child = child->next; 11828 } else if (IS_SCHEMA(child, "choice")) { 11829 type->subtypes = (xmlSchemaTypePtr) 11830 xmlSchemaParseModelGroup(ctxt, schema, 11831 child, XML_SCHEMA_TYPE_CHOICE, 1); 11832 child = child->next; 11833 } else if (IS_SCHEMA(child, "sequence")) { 11834 type->subtypes = (xmlSchemaTypePtr) 11835 xmlSchemaParseModelGroup(ctxt, schema, 11836 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11837 child = child->next; 11838 } else if (IS_SCHEMA(child, "group")) { 11839 type->subtypes = (xmlSchemaTypePtr) 11840 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11841 /* 11842 * Note that the reference will be resolved in 11843 * xmlSchemaResolveTypeReferences(); 11844 */ 11845 child = child->next; 11846 } 11847 } 11848 if (child != NULL) { 11849 /* 11850 * Attribute uses/declarations. 11851 */ 11852 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11853 (xmlSchemaItemListPtr *) &(type->attrUses), 11854 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11855 return(NULL); 11856 /* 11857 * Attribute wildcard. 11858 */ 11859 if (IS_SCHEMA(child, "anyAttribute")) { 11860 ctxt->ctxtType->attributeWildcard = 11861 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11862 child = child->next; 11863 } 11864 } 11865 if (child != NULL) { 11866 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11867 /* Complex content extension. */ 11868 xmlSchemaPContentErr(ctxt, 11869 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11870 NULL, node, child, NULL, 11871 "(annotation?, ((group | all | choice | sequence)?, " 11872 "((attribute | attributeGroup)*, anyAttribute?)))"); 11873 } else { 11874 /* Simple content extension. */ 11875 xmlSchemaPContentErr(ctxt, 11876 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11877 NULL, node, child, NULL, 11878 "(annotation?, ((attribute | attributeGroup)*, " 11879 "anyAttribute?))"); 11880 } 11881 } 11882 return (NULL); 11883 } 11884 11885 /** 11886 * xmlSchemaParseSimpleContent: 11887 * @ctxt: a schema validation context 11888 * @schema: the schema being built 11889 * @node: a subtree containing XML Schema informations 11890 * 11891 * parse a XML schema SimpleContent definition 11892 * *WARNING* this interface is highly subject to change 11893 * 11894 * Returns the type definition or NULL in case of error 11895 */ 11896 static int 11897 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11898 xmlSchemaPtr schema, xmlNodePtr node, 11899 int *hasRestrictionOrExtension) 11900 { 11901 xmlSchemaTypePtr type; 11902 xmlNodePtr child = NULL; 11903 xmlAttrPtr attr; 11904 11905 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11906 (hasRestrictionOrExtension == NULL)) 11907 return (-1); 11908 *hasRestrictionOrExtension = 0; 11909 /* Not a component, don't create it. */ 11910 type = ctxt->ctxtType; 11911 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11912 /* 11913 * Check for illegal attributes. 11914 */ 11915 attr = node->properties; 11916 while (attr != NULL) { 11917 if (attr->ns == NULL) { 11918 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11919 xmlSchemaPIllegalAttrErr(ctxt, 11920 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11921 } 11922 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11923 xmlSchemaPIllegalAttrErr(ctxt, 11924 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11925 } 11926 attr = attr->next; 11927 } 11928 11929 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11930 11931 /* 11932 * And now for the children... 11933 */ 11934 child = node->children; 11935 if (IS_SCHEMA(child, "annotation")) { 11936 /* 11937 * Add the annotation to the complex type ancestor. 11938 */ 11939 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11940 xmlSchemaParseAnnotation(ctxt, child, 1)); 11941 child = child->next; 11942 } 11943 if (child == NULL) { 11944 xmlSchemaPContentErr(ctxt, 11945 XML_SCHEMAP_S4S_ELEM_MISSING, 11946 NULL, node, NULL, NULL, 11947 "(annotation?, (restriction | extension))"); 11948 } 11949 if (child == NULL) { 11950 xmlSchemaPContentErr(ctxt, 11951 XML_SCHEMAP_S4S_ELEM_MISSING, 11952 NULL, node, NULL, NULL, 11953 "(annotation?, (restriction | extension))"); 11954 } 11955 if (IS_SCHEMA(child, "restriction")) { 11956 xmlSchemaParseRestriction(ctxt, schema, child, 11957 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11958 (*hasRestrictionOrExtension) = 1; 11959 child = child->next; 11960 } else if (IS_SCHEMA(child, "extension")) { 11961 xmlSchemaParseExtension(ctxt, schema, child, 11962 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11963 (*hasRestrictionOrExtension) = 1; 11964 child = child->next; 11965 } 11966 if (child != NULL) { 11967 xmlSchemaPContentErr(ctxt, 11968 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11969 NULL, node, child, NULL, 11970 "(annotation?, (restriction | extension))"); 11971 } 11972 return (0); 11973 } 11974 11975 /** 11976 * xmlSchemaParseComplexContent: 11977 * @ctxt: a schema validation context 11978 * @schema: the schema being built 11979 * @node: a subtree containing XML Schema informations 11980 * 11981 * parse a XML schema ComplexContent definition 11982 * *WARNING* this interface is highly subject to change 11983 * 11984 * Returns the type definition or NULL in case of error 11985 */ 11986 static int 11987 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 11988 xmlSchemaPtr schema, xmlNodePtr node, 11989 int *hasRestrictionOrExtension) 11990 { 11991 xmlSchemaTypePtr type; 11992 xmlNodePtr child = NULL; 11993 xmlAttrPtr attr; 11994 11995 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11996 (hasRestrictionOrExtension == NULL)) 11997 return (-1); 11998 *hasRestrictionOrExtension = 0; 11999 /* Not a component, don't create it. */ 12000 type = ctxt->ctxtType; 12001 /* 12002 * Check for illegal attributes. 12003 */ 12004 attr = node->properties; 12005 while (attr != NULL) { 12006 if (attr->ns == NULL) { 12007 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12008 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12009 { 12010 xmlSchemaPIllegalAttrErr(ctxt, 12011 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12012 } 12013 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12014 xmlSchemaPIllegalAttrErr(ctxt, 12015 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12016 } 12017 attr = attr->next; 12018 } 12019 12020 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12021 12022 /* 12023 * Set the 'mixed' on the complex type ancestor. 12024 */ 12025 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12026 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12027 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12028 } 12029 child = node->children; 12030 if (IS_SCHEMA(child, "annotation")) { 12031 /* 12032 * Add the annotation to the complex type ancestor. 12033 */ 12034 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12035 xmlSchemaParseAnnotation(ctxt, child, 1)); 12036 child = child->next; 12037 } 12038 if (child == NULL) { 12039 xmlSchemaPContentErr(ctxt, 12040 XML_SCHEMAP_S4S_ELEM_MISSING, 12041 NULL, node, NULL, 12042 NULL, "(annotation?, (restriction | extension))"); 12043 } 12044 if (child == NULL) { 12045 xmlSchemaPContentErr(ctxt, 12046 XML_SCHEMAP_S4S_ELEM_MISSING, 12047 NULL, node, NULL, 12048 NULL, "(annotation?, (restriction | extension))"); 12049 } 12050 if (IS_SCHEMA(child, "restriction")) { 12051 xmlSchemaParseRestriction(ctxt, schema, child, 12052 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12053 (*hasRestrictionOrExtension) = 1; 12054 child = child->next; 12055 } else if (IS_SCHEMA(child, "extension")) { 12056 xmlSchemaParseExtension(ctxt, schema, child, 12057 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12058 (*hasRestrictionOrExtension) = 1; 12059 child = child->next; 12060 } 12061 if (child != NULL) { 12062 xmlSchemaPContentErr(ctxt, 12063 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12064 NULL, node, child, 12065 NULL, "(annotation?, (restriction | extension))"); 12066 } 12067 return (0); 12068 } 12069 12070 /** 12071 * xmlSchemaParseComplexType: 12072 * @ctxt: a schema validation context 12073 * @schema: the schema being built 12074 * @node: a subtree containing XML Schema informations 12075 * 12076 * parse a XML schema Complex Type definition 12077 * *WARNING* this interface is highly subject to change 12078 * 12079 * Returns the type definition or NULL in case of error 12080 */ 12081 static xmlSchemaTypePtr 12082 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12083 xmlNodePtr node, int topLevel) 12084 { 12085 xmlSchemaTypePtr type, ctxtType; 12086 xmlNodePtr child = NULL; 12087 const xmlChar *name = NULL; 12088 xmlAttrPtr attr; 12089 const xmlChar *attrValue; 12090 #ifdef ENABLE_NAMED_LOCALS 12091 char buf[40]; 12092 #endif 12093 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12094 12095 12096 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12097 return (NULL); 12098 12099 ctxtType = ctxt->ctxtType; 12100 12101 if (topLevel) { 12102 attr = xmlSchemaGetPropNode(node, "name"); 12103 if (attr == NULL) { 12104 xmlSchemaPMissingAttrErr(ctxt, 12105 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12106 return (NULL); 12107 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12108 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12109 return (NULL); 12110 } 12111 } 12112 12113 if (topLevel == 0) { 12114 /* 12115 * Parse as local complex type definition. 12116 */ 12117 #ifdef ENABLE_NAMED_LOCALS 12118 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12119 type = xmlSchemaAddType(ctxt, schema, 12120 XML_SCHEMA_TYPE_COMPLEX, 12121 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12122 ctxt->targetNamespace, node, 0); 12123 #else 12124 type = xmlSchemaAddType(ctxt, schema, 12125 XML_SCHEMA_TYPE_COMPLEX, 12126 NULL, ctxt->targetNamespace, node, 0); 12127 #endif 12128 if (type == NULL) 12129 return (NULL); 12130 name = type->name; 12131 type->node = node; 12132 type->type = XML_SCHEMA_TYPE_COMPLEX; 12133 /* 12134 * TODO: We need the target namespace. 12135 */ 12136 } else { 12137 /* 12138 * Parse as global complex type definition. 12139 */ 12140 type = xmlSchemaAddType(ctxt, schema, 12141 XML_SCHEMA_TYPE_COMPLEX, 12142 name, ctxt->targetNamespace, node, 1); 12143 if (type == NULL) 12144 return (NULL); 12145 type->node = node; 12146 type->type = XML_SCHEMA_TYPE_COMPLEX; 12147 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12148 } 12149 type->targetNamespace = ctxt->targetNamespace; 12150 /* 12151 * Handle attributes. 12152 */ 12153 attr = node->properties; 12154 while (attr != NULL) { 12155 if (attr->ns == NULL) { 12156 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12157 /* 12158 * Attribute "id". 12159 */ 12160 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12161 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12162 /* 12163 * Attribute "mixed". 12164 */ 12165 if (xmlSchemaPGetBoolNodeValue(ctxt, 12166 NULL, (xmlNodePtr) attr)) 12167 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12168 } else if (topLevel) { 12169 /* 12170 * Attributes of global complex type definitions. 12171 */ 12172 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12173 /* Pass. */ 12174 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12175 /* 12176 * Attribute "abstract". 12177 */ 12178 if (xmlSchemaPGetBoolNodeValue(ctxt, 12179 NULL, (xmlNodePtr) attr)) 12180 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12181 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12182 /* 12183 * Attribute "final". 12184 */ 12185 attrValue = xmlSchemaGetNodeContent(ctxt, 12186 (xmlNodePtr) attr); 12187 if (xmlSchemaPValAttrBlockFinal(attrValue, 12188 &(type->flags), 12189 -1, 12190 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12191 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12192 -1, -1, -1) != 0) 12193 { 12194 xmlSchemaPSimpleTypeErr(ctxt, 12195 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12196 NULL, (xmlNodePtr) attr, NULL, 12197 "(#all | List of (extension | restriction))", 12198 attrValue, NULL, NULL, NULL); 12199 } else 12200 final = 1; 12201 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12202 /* 12203 * Attribute "block". 12204 */ 12205 attrValue = xmlSchemaGetNodeContent(ctxt, 12206 (xmlNodePtr) attr); 12207 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12208 -1, 12209 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12210 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12211 -1, -1, -1) != 0) { 12212 xmlSchemaPSimpleTypeErr(ctxt, 12213 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12214 NULL, (xmlNodePtr) attr, NULL, 12215 "(#all | List of (extension | restriction)) ", 12216 attrValue, NULL, NULL, NULL); 12217 } else 12218 block = 1; 12219 } else { 12220 xmlSchemaPIllegalAttrErr(ctxt, 12221 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12222 } 12223 } else { 12224 xmlSchemaPIllegalAttrErr(ctxt, 12225 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12226 } 12227 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12228 xmlSchemaPIllegalAttrErr(ctxt, 12229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12230 } 12231 attr = attr->next; 12232 } 12233 if (! block) { 12234 /* 12235 * Apply default "block" values. 12236 */ 12237 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12238 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12239 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12240 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12241 } 12242 if (! final) { 12243 /* 12244 * Apply default "block" values. 12245 */ 12246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12247 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12248 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12249 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12250 } 12251 /* 12252 * And now for the children... 12253 */ 12254 child = node->children; 12255 if (IS_SCHEMA(child, "annotation")) { 12256 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12257 child = child->next; 12258 } 12259 ctxt->ctxtType = type; 12260 if (IS_SCHEMA(child, "simpleContent")) { 12261 /* 12262 * <complexType><simpleContent>... 12263 * 3.4.3 : 2.2 12264 * Specifying mixed='true' when the <simpleContent> 12265 * alternative is chosen has no effect 12266 */ 12267 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12268 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12269 xmlSchemaParseSimpleContent(ctxt, schema, child, 12270 &hasRestrictionOrExtension); 12271 child = child->next; 12272 } else if (IS_SCHEMA(child, "complexContent")) { 12273 /* 12274 * <complexType><complexContent>... 12275 */ 12276 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12277 xmlSchemaParseComplexContent(ctxt, schema, child, 12278 &hasRestrictionOrExtension); 12279 child = child->next; 12280 } else { 12281 /* 12282 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12283 * 12284 * SPEC 12285 * "...the third alternative (neither <simpleContent> nor 12286 * <complexContent>) is chosen. This case is understood as shorthand 12287 * for complex content restricting the ur-type definition, and the 12288 * details of the mappings should be modified as necessary. 12289 */ 12290 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12291 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12292 /* 12293 * Parse model groups. 12294 */ 12295 if (IS_SCHEMA(child, "all")) { 12296 type->subtypes = (xmlSchemaTypePtr) 12297 xmlSchemaParseModelGroup(ctxt, schema, child, 12298 XML_SCHEMA_TYPE_ALL, 1); 12299 child = child->next; 12300 } else if (IS_SCHEMA(child, "choice")) { 12301 type->subtypes = (xmlSchemaTypePtr) 12302 xmlSchemaParseModelGroup(ctxt, schema, child, 12303 XML_SCHEMA_TYPE_CHOICE, 1); 12304 child = child->next; 12305 } else if (IS_SCHEMA(child, "sequence")) { 12306 type->subtypes = (xmlSchemaTypePtr) 12307 xmlSchemaParseModelGroup(ctxt, schema, child, 12308 XML_SCHEMA_TYPE_SEQUENCE, 1); 12309 child = child->next; 12310 } else if (IS_SCHEMA(child, "group")) { 12311 type->subtypes = (xmlSchemaTypePtr) 12312 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12313 /* 12314 * Note that the reference will be resolved in 12315 * xmlSchemaResolveTypeReferences(); 12316 */ 12317 child = child->next; 12318 } 12319 /* 12320 * Parse attribute decls/refs. 12321 */ 12322 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12323 (xmlSchemaItemListPtr *) &(type->attrUses), 12324 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12325 return(NULL); 12326 /* 12327 * Parse attribute wildcard. 12328 */ 12329 if (IS_SCHEMA(child, "anyAttribute")) { 12330 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12331 child = child->next; 12332 } 12333 } 12334 if (child != NULL) { 12335 xmlSchemaPContentErr(ctxt, 12336 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12337 NULL, node, child, 12338 NULL, "(annotation?, (simpleContent | complexContent | " 12339 "((group | all | choice | sequence)?, ((attribute | " 12340 "attributeGroup)*, anyAttribute?))))"); 12341 } 12342 /* 12343 * REDEFINE: SPEC src-redefine (5) 12344 */ 12345 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12346 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12347 NULL, node, "This is a redefinition, thus the " 12348 "<complexType> must have a <restriction> or <extension> " 12349 "grand-child", NULL); 12350 } 12351 ctxt->ctxtType = ctxtType; 12352 return (type); 12353 } 12354 12355 /************************************************************************ 12356 * * 12357 * Validating using Schemas * 12358 * * 12359 ************************************************************************/ 12360 12361 /************************************************************************ 12362 * * 12363 * Reading/Writing Schemas * 12364 * * 12365 ************************************************************************/ 12366 12367 #if 0 /* Will be enabled if it is clear what options are needed. */ 12368 /** 12369 * xmlSchemaParserCtxtSetOptions: 12370 * @ctxt: a schema parser context 12371 * @options: a combination of xmlSchemaParserOption 12372 * 12373 * Sets the options to be used during the parse. 12374 * 12375 * Returns 0 in case of success, -1 in case of an 12376 * API error. 12377 */ 12378 static int 12379 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12380 int options) 12381 12382 { 12383 int i; 12384 12385 if (ctxt == NULL) 12386 return (-1); 12387 /* 12388 * WARNING: Change the start value if adding to the 12389 * xmlSchemaParseOption. 12390 */ 12391 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12392 if (options & 1<<i) { 12393 return (-1); 12394 } 12395 } 12396 ctxt->options = options; 12397 return (0); 12398 } 12399 12400 /** 12401 * xmlSchemaValidCtxtGetOptions: 12402 * @ctxt: a schema parser context 12403 * 12404 * Returns the option combination of the parser context. 12405 */ 12406 static int 12407 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12408 12409 { 12410 if (ctxt == NULL) 12411 return (-1); 12412 else 12413 return (ctxt->options); 12414 } 12415 #endif 12416 12417 /** 12418 * xmlSchemaNewParserCtxt: 12419 * @URL: the location of the schema 12420 * 12421 * Create an XML Schemas parse context for that file/resource expected 12422 * to contain an XML Schemas file. 12423 * 12424 * Returns the parser context or NULL in case of error 12425 */ 12426 xmlSchemaParserCtxtPtr 12427 xmlSchemaNewParserCtxt(const char *URL) 12428 { 12429 xmlSchemaParserCtxtPtr ret; 12430 12431 if (URL == NULL) 12432 return (NULL); 12433 12434 ret = xmlSchemaParserCtxtCreate(); 12435 if (ret == NULL) 12436 return(NULL); 12437 ret->dict = xmlDictCreate(); 12438 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12439 return (ret); 12440 } 12441 12442 /** 12443 * xmlSchemaNewMemParserCtxt: 12444 * @buffer: a pointer to a char array containing the schemas 12445 * @size: the size of the array 12446 * 12447 * Create an XML Schemas parse context for that memory buffer expected 12448 * to contain an XML Schemas file. 12449 * 12450 * Returns the parser context or NULL in case of error 12451 */ 12452 xmlSchemaParserCtxtPtr 12453 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12454 { 12455 xmlSchemaParserCtxtPtr ret; 12456 12457 if ((buffer == NULL) || (size <= 0)) 12458 return (NULL); 12459 ret = xmlSchemaParserCtxtCreate(); 12460 if (ret == NULL) 12461 return(NULL); 12462 ret->buffer = buffer; 12463 ret->size = size; 12464 ret->dict = xmlDictCreate(); 12465 return (ret); 12466 } 12467 12468 /** 12469 * xmlSchemaNewDocParserCtxt: 12470 * @doc: a preparsed document tree 12471 * 12472 * Create an XML Schemas parse context for that document. 12473 * NB. The document may be modified during the parsing process. 12474 * 12475 * Returns the parser context or NULL in case of error 12476 */ 12477 xmlSchemaParserCtxtPtr 12478 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12479 { 12480 xmlSchemaParserCtxtPtr ret; 12481 12482 if (doc == NULL) 12483 return (NULL); 12484 ret = xmlSchemaParserCtxtCreate(); 12485 if (ret == NULL) 12486 return(NULL); 12487 ret->doc = doc; 12488 ret->dict = xmlDictCreate(); 12489 /* The application has responsibility for the document */ 12490 ret->preserve = 1; 12491 12492 return (ret); 12493 } 12494 12495 /** 12496 * xmlSchemaFreeParserCtxt: 12497 * @ctxt: the schema parser context 12498 * 12499 * Free the resources associated to the schema parser context 12500 */ 12501 void 12502 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12503 { 12504 if (ctxt == NULL) 12505 return; 12506 if (ctxt->doc != NULL && !ctxt->preserve) 12507 xmlFreeDoc(ctxt->doc); 12508 if (ctxt->vctxt != NULL) { 12509 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12510 } 12511 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12512 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12513 ctxt->constructor = NULL; 12514 ctxt->ownsConstructor = 0; 12515 } 12516 if (ctxt->attrProhibs != NULL) 12517 xmlSchemaItemListFree(ctxt->attrProhibs); 12518 xmlDictFree(ctxt->dict); 12519 xmlFree(ctxt); 12520 } 12521 12522 /************************************************************************ 12523 * * 12524 * Building the content models * 12525 * * 12526 ************************************************************************/ 12527 12528 /** 12529 * xmlSchemaBuildContentModelForSubstGroup: 12530 * 12531 * Returns 1 if nillable, 0 otherwise 12532 */ 12533 static int 12534 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12535 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12536 { 12537 xmlAutomataStatePtr start, tmp; 12538 xmlSchemaElementPtr elemDecl, member; 12539 xmlSchemaSubstGroupPtr substGroup; 12540 int i; 12541 int ret = 0; 12542 12543 elemDecl = (xmlSchemaElementPtr) particle->children; 12544 /* 12545 * Wrap the substitution group with a CHOICE. 12546 */ 12547 start = pctxt->state; 12548 if (end == NULL) 12549 end = xmlAutomataNewState(pctxt->am); 12550 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12551 if (substGroup == NULL) { 12552 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12553 XML_SCHEMAP_INTERNAL, 12554 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12555 "declaration is marked having a subst. group but none " 12556 "available.\n", elemDecl->name, NULL); 12557 return(0); 12558 } 12559 if (counter >= 0) { 12560 /* 12561 * NOTE that we put the declaration in, even if it's abstract. 12562 * However, an error will be raised during *validation* if an element 12563 * information item shall be validated against an abstract element 12564 * declaration. 12565 */ 12566 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12567 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12568 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12569 /* 12570 * Add subst. group members. 12571 */ 12572 for (i = 0; i < substGroup->members->nbItems; i++) { 12573 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12574 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12575 member->name, member->targetNamespace, member); 12576 } 12577 } else if (particle->maxOccurs == 1) { 12578 /* 12579 * NOTE that we put the declaration in, even if it's abstract, 12580 */ 12581 xmlAutomataNewEpsilon(pctxt->am, 12582 xmlAutomataNewTransition2(pctxt->am, 12583 start, NULL, 12584 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12585 /* 12586 * Add subst. group members. 12587 */ 12588 for (i = 0; i < substGroup->members->nbItems; i++) { 12589 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12590 /* 12591 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12592 * was incorrectly used instead of xmlAutomataNewTransition2() 12593 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12594 * section in xmlSchemaBuildAContentModel() ). 12595 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12596 * intended for the above "counter" section originally. I.e., 12597 * check xs:all with subst-groups. 12598 * 12599 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12600 * member->name, member->targetNamespace, 12601 * 1, 1, member); 12602 */ 12603 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12604 member->name, member->targetNamespace, member); 12605 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12606 } 12607 } else { 12608 xmlAutomataStatePtr hop; 12609 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12610 UNBOUNDED : particle->maxOccurs - 1; 12611 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12612 12613 counter = 12614 xmlAutomataNewCounter(pctxt->am, minOccurs, 12615 maxOccurs); 12616 hop = xmlAutomataNewState(pctxt->am); 12617 12618 xmlAutomataNewEpsilon(pctxt->am, 12619 xmlAutomataNewTransition2(pctxt->am, 12620 start, NULL, 12621 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12622 hop); 12623 /* 12624 * Add subst. group members. 12625 */ 12626 for (i = 0; i < substGroup->members->nbItems; i++) { 12627 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12628 xmlAutomataNewEpsilon(pctxt->am, 12629 xmlAutomataNewTransition2(pctxt->am, 12630 start, NULL, 12631 member->name, member->targetNamespace, member), 12632 hop); 12633 } 12634 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12635 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12636 } 12637 if (particle->minOccurs == 0) { 12638 xmlAutomataNewEpsilon(pctxt->am, start, end); 12639 ret = 1; 12640 } 12641 pctxt->state = end; 12642 return(ret); 12643 } 12644 12645 /** 12646 * xmlSchemaBuildContentModelForElement: 12647 * 12648 * Returns 1 if nillable, 0 otherwise 12649 */ 12650 static int 12651 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12652 xmlSchemaParticlePtr particle) 12653 { 12654 int ret = 0; 12655 12656 if (((xmlSchemaElementPtr) particle->children)->flags & 12657 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12658 /* 12659 * Substitution groups. 12660 */ 12661 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12662 } else { 12663 xmlSchemaElementPtr elemDecl; 12664 xmlAutomataStatePtr start; 12665 12666 elemDecl = (xmlSchemaElementPtr) particle->children; 12667 12668 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12669 return(0); 12670 if (particle->maxOccurs == 1) { 12671 start = ctxt->state; 12672 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12673 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12674 } else if ((particle->maxOccurs >= UNBOUNDED) && 12675 (particle->minOccurs < 2)) { 12676 /* Special case. */ 12677 start = ctxt->state; 12678 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12679 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12680 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12681 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12682 } else { 12683 int counter; 12684 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12685 UNBOUNDED : particle->maxOccurs - 1; 12686 int minOccurs = particle->minOccurs < 1 ? 12687 0 : particle->minOccurs - 1; 12688 12689 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12690 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12691 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12692 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12693 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12694 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12695 NULL, counter); 12696 } 12697 if (particle->minOccurs == 0) { 12698 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12699 ret = 1; 12700 } 12701 } 12702 return(ret); 12703 } 12704 12705 /** 12706 * xmlSchemaBuildAContentModel: 12707 * @ctxt: the schema parser context 12708 * @particle: the particle component 12709 * @name: the complex type's name whose content is being built 12710 * 12711 * Create the automaton for the {content type} of a complex type. 12712 * 12713 * Returns 1 if the content is nillable, 0 otherwise 12714 */ 12715 static int 12716 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12717 xmlSchemaParticlePtr particle) 12718 { 12719 int ret = 0, tmp2; 12720 12721 if (particle == NULL) { 12722 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12723 return(1); 12724 } 12725 if (particle->children == NULL) { 12726 /* 12727 * Just return in this case. A missing "term" of the particle 12728 * might arise due to an invalid "term" component. 12729 */ 12730 return(1); 12731 } 12732 12733 switch (particle->children->type) { 12734 case XML_SCHEMA_TYPE_ANY: { 12735 xmlAutomataStatePtr start, end; 12736 xmlSchemaWildcardPtr wild; 12737 xmlSchemaWildcardNsPtr ns; 12738 12739 wild = (xmlSchemaWildcardPtr) particle->children; 12740 12741 start = pctxt->state; 12742 end = xmlAutomataNewState(pctxt->am); 12743 12744 if (particle->maxOccurs == 1) { 12745 if (wild->any == 1) { 12746 /* 12747 * We need to add both transitions: 12748 * 12749 * 1. the {"*", "*"} for elements in a namespace. 12750 */ 12751 pctxt->state = 12752 xmlAutomataNewTransition2(pctxt->am, 12753 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12754 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12755 /* 12756 * 2. the {"*"} for elements in no namespace. 12757 */ 12758 pctxt->state = 12759 xmlAutomataNewTransition2(pctxt->am, 12760 start, NULL, BAD_CAST "*", NULL, wild); 12761 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12762 12763 } else if (wild->nsSet != NULL) { 12764 ns = wild->nsSet; 12765 do { 12766 pctxt->state = start; 12767 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12768 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12769 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12770 ns = ns->next; 12771 } while (ns != NULL); 12772 12773 } else if (wild->negNsSet != NULL) { 12774 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12775 start, end, BAD_CAST "*", wild->negNsSet->value, 12776 wild); 12777 } 12778 } else { 12779 int counter; 12780 xmlAutomataStatePtr hop; 12781 int maxOccurs = 12782 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12783 particle->maxOccurs - 1; 12784 int minOccurs = 12785 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12786 12787 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12788 hop = xmlAutomataNewState(pctxt->am); 12789 if (wild->any == 1) { 12790 pctxt->state = 12791 xmlAutomataNewTransition2(pctxt->am, 12792 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12793 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12794 pctxt->state = 12795 xmlAutomataNewTransition2(pctxt->am, 12796 start, NULL, BAD_CAST "*", NULL, wild); 12797 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12798 } else if (wild->nsSet != NULL) { 12799 ns = wild->nsSet; 12800 do { 12801 pctxt->state = 12802 xmlAutomataNewTransition2(pctxt->am, 12803 start, NULL, BAD_CAST "*", ns->value, wild); 12804 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12805 ns = ns->next; 12806 } while (ns != NULL); 12807 12808 } else if (wild->negNsSet != NULL) { 12809 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12810 start, hop, BAD_CAST "*", wild->negNsSet->value, 12811 wild); 12812 } 12813 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12814 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12815 } 12816 if (particle->minOccurs == 0) { 12817 xmlAutomataNewEpsilon(pctxt->am, start, end); 12818 ret = 1; 12819 } 12820 pctxt->state = end; 12821 break; 12822 } 12823 case XML_SCHEMA_TYPE_ELEMENT: 12824 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12825 break; 12826 case XML_SCHEMA_TYPE_SEQUENCE:{ 12827 xmlSchemaTreeItemPtr sub; 12828 12829 ret = 1; 12830 /* 12831 * If max and min occurances are default (1) then 12832 * simply iterate over the particles of the <sequence>. 12833 */ 12834 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12835 sub = particle->children->children; 12836 12837 while (sub != NULL) { 12838 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12839 (xmlSchemaParticlePtr) sub); 12840 if (tmp2 != 1) ret = 0; 12841 sub = sub->next; 12842 } 12843 } else { 12844 xmlAutomataStatePtr oldstate = pctxt->state; 12845 12846 if (particle->maxOccurs >= UNBOUNDED) { 12847 if (particle->minOccurs > 1) { 12848 xmlAutomataStatePtr tmp; 12849 int counter; 12850 12851 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12852 oldstate, NULL); 12853 oldstate = pctxt->state; 12854 12855 counter = xmlAutomataNewCounter(pctxt->am, 12856 particle->minOccurs - 1, UNBOUNDED); 12857 12858 sub = particle->children->children; 12859 while (sub != NULL) { 12860 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12861 (xmlSchemaParticlePtr) sub); 12862 if (tmp2 != 1) ret = 0; 12863 sub = sub->next; 12864 } 12865 tmp = pctxt->state; 12866 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12867 oldstate, counter); 12868 pctxt->state = 12869 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12870 NULL, counter); 12871 if (ret == 1) 12872 xmlAutomataNewEpsilon(pctxt->am, 12873 oldstate, pctxt->state); 12874 12875 } else { 12876 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12877 oldstate, NULL); 12878 oldstate = pctxt->state; 12879 12880 sub = particle->children->children; 12881 while (sub != NULL) { 12882 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12883 (xmlSchemaParticlePtr) sub); 12884 if (tmp2 != 1) ret = 0; 12885 sub = sub->next; 12886 } 12887 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12888 oldstate); 12889 /* 12890 * epsilon needed to block previous trans from 12891 * being allowed to enter back from another 12892 * construct 12893 */ 12894 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12895 pctxt->state, NULL); 12896 if (particle->minOccurs == 0) { 12897 xmlAutomataNewEpsilon(pctxt->am, 12898 oldstate, pctxt->state); 12899 ret = 1; 12900 } 12901 } 12902 } else if ((particle->maxOccurs > 1) 12903 || (particle->minOccurs > 1)) { 12904 xmlAutomataStatePtr tmp; 12905 int counter; 12906 12907 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12908 oldstate, NULL); 12909 oldstate = pctxt->state; 12910 12911 counter = xmlAutomataNewCounter(pctxt->am, 12912 particle->minOccurs - 1, 12913 particle->maxOccurs - 1); 12914 12915 sub = particle->children->children; 12916 while (sub != NULL) { 12917 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12918 (xmlSchemaParticlePtr) sub); 12919 if (tmp2 != 1) ret = 0; 12920 sub = sub->next; 12921 } 12922 tmp = pctxt->state; 12923 xmlAutomataNewCountedTrans(pctxt->am, 12924 tmp, oldstate, counter); 12925 pctxt->state = 12926 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12927 counter); 12928 if ((particle->minOccurs == 0) || (ret == 1)) { 12929 xmlAutomataNewEpsilon(pctxt->am, 12930 oldstate, pctxt->state); 12931 ret = 1; 12932 } 12933 } else { 12934 sub = particle->children->children; 12935 while (sub != NULL) { 12936 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12937 (xmlSchemaParticlePtr) sub); 12938 if (tmp2 != 1) ret = 0; 12939 sub = sub->next; 12940 } 12941 if (particle->minOccurs == 0) { 12942 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12943 pctxt->state); 12944 ret = 1; 12945 } 12946 } 12947 } 12948 break; 12949 } 12950 case XML_SCHEMA_TYPE_CHOICE:{ 12951 xmlSchemaTreeItemPtr sub; 12952 xmlAutomataStatePtr start, end; 12953 12954 ret = 0; 12955 start = pctxt->state; 12956 end = xmlAutomataNewState(pctxt->am); 12957 12958 /* 12959 * iterate over the subtypes and remerge the end with an 12960 * epsilon transition 12961 */ 12962 if (particle->maxOccurs == 1) { 12963 sub = particle->children->children; 12964 while (sub != NULL) { 12965 pctxt->state = start; 12966 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12967 (xmlSchemaParticlePtr) sub); 12968 if (tmp2 == 1) ret = 1; 12969 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12970 sub = sub->next; 12971 } 12972 } else { 12973 int counter; 12974 xmlAutomataStatePtr hop, base; 12975 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12976 UNBOUNDED : particle->maxOccurs - 1; 12977 int minOccurs = 12978 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12979 12980 /* 12981 * use a counter to keep track of the number of transtions 12982 * which went through the choice. 12983 */ 12984 counter = 12985 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12986 hop = xmlAutomataNewState(pctxt->am); 12987 base = xmlAutomataNewState(pctxt->am); 12988 12989 sub = particle->children->children; 12990 while (sub != NULL) { 12991 pctxt->state = base; 12992 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12993 (xmlSchemaParticlePtr) sub); 12994 if (tmp2 == 1) ret = 1; 12995 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12996 sub = sub->next; 12997 } 12998 xmlAutomataNewEpsilon(pctxt->am, start, base); 12999 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13000 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13001 if (ret == 1) 13002 xmlAutomataNewEpsilon(pctxt->am, base, end); 13003 } 13004 if (particle->minOccurs == 0) { 13005 xmlAutomataNewEpsilon(pctxt->am, start, end); 13006 ret = 1; 13007 } 13008 pctxt->state = end; 13009 break; 13010 } 13011 case XML_SCHEMA_TYPE_ALL:{ 13012 xmlAutomataStatePtr start, tmp; 13013 xmlSchemaParticlePtr sub; 13014 xmlSchemaElementPtr elemDecl; 13015 13016 ret = 1; 13017 13018 sub = (xmlSchemaParticlePtr) particle->children->children; 13019 if (sub == NULL) 13020 break; 13021 13022 ret = 0; 13023 13024 start = pctxt->state; 13025 tmp = xmlAutomataNewState(pctxt->am); 13026 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13027 pctxt->state = tmp; 13028 while (sub != NULL) { 13029 pctxt->state = tmp; 13030 13031 elemDecl = (xmlSchemaElementPtr) sub->children; 13032 if (elemDecl == NULL) { 13033 PERROR_INT("xmlSchemaBuildAContentModel", 13034 "<element> particle has no term"); 13035 return(ret); 13036 }; 13037 /* 13038 * NOTE: The {max occurs} of all the particles in the 13039 * {particles} of the group must be 0 or 1; this is 13040 * already ensured during the parse of the content of 13041 * <all>. 13042 */ 13043 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13044 int counter; 13045 13046 /* 13047 * This is an abstract group, we need to share 13048 * the same counter for all the element transitions 13049 * derived from the group 13050 */ 13051 counter = xmlAutomataNewCounter(pctxt->am, 13052 sub->minOccurs, sub->maxOccurs); 13053 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13054 sub, counter, pctxt->state); 13055 } else { 13056 if ((sub->minOccurs == 1) && 13057 (sub->maxOccurs == 1)) { 13058 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13059 pctxt->state, 13060 elemDecl->name, 13061 elemDecl->targetNamespace, 13062 1, 1, elemDecl); 13063 } else if ((sub->minOccurs == 0) && 13064 (sub->maxOccurs == 1)) { 13065 13066 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13067 pctxt->state, 13068 elemDecl->name, 13069 elemDecl->targetNamespace, 13070 0, 13071 1, 13072 elemDecl); 13073 } 13074 } 13075 sub = (xmlSchemaParticlePtr) sub->next; 13076 } 13077 pctxt->state = 13078 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13079 if (particle->minOccurs == 0) { 13080 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13081 ret = 1; 13082 } 13083 break; 13084 } 13085 case XML_SCHEMA_TYPE_GROUP: 13086 /* 13087 * If we hit a model group definition, then this means that 13088 * it was empty, thus was not substituted for the containing 13089 * model group. Just do nothing in this case. 13090 * TODO: But the group should be substituted and not occur at 13091 * all in the content model at this point. Fix this. 13092 */ 13093 ret = 1; 13094 break; 13095 default: 13096 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13097 "xmlSchemaBuildAContentModel", 13098 "found unexpected term of type '%s' in content model", 13099 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13100 return(ret); 13101 } 13102 return(ret); 13103 } 13104 13105 /** 13106 * xmlSchemaBuildContentModel: 13107 * @ctxt: the schema parser context 13108 * @type: the complex type definition 13109 * @name: the element name 13110 * 13111 * Builds the content model of the complex type. 13112 */ 13113 static void 13114 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13115 xmlSchemaParserCtxtPtr ctxt) 13116 { 13117 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13118 (type->contModel != NULL) || 13119 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13120 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13121 return; 13122 13123 #ifdef DEBUG_CONTENT 13124 xmlGenericError(xmlGenericErrorContext, 13125 "Building content model for %s\n", name); 13126 #endif 13127 ctxt->am = NULL; 13128 ctxt->am = xmlNewAutomata(); 13129 if (ctxt->am == NULL) { 13130 xmlGenericError(xmlGenericErrorContext, 13131 "Cannot create automata for complex type %s\n", type->name); 13132 return; 13133 } 13134 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13135 /* 13136 * Build the automaton. 13137 */ 13138 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13139 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13140 type->contModel = xmlAutomataCompile(ctxt->am); 13141 if (type->contModel == NULL) { 13142 xmlSchemaPCustomErr(ctxt, 13143 XML_SCHEMAP_INTERNAL, 13144 WXS_BASIC_CAST type, type->node, 13145 "Failed to compile the content model", NULL); 13146 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13147 xmlSchemaPCustomErr(ctxt, 13148 XML_SCHEMAP_NOT_DETERMINISTIC, 13149 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13150 WXS_BASIC_CAST type, type->node, 13151 "The content model is not determinist", NULL); 13152 } else { 13153 #ifdef DEBUG_CONTENT_REGEXP 13154 xmlGenericError(xmlGenericErrorContext, 13155 "Content model of %s:\n", type->name); 13156 xmlRegexpPrint(stderr, type->contModel); 13157 #endif 13158 } 13159 ctxt->state = NULL; 13160 xmlFreeAutomata(ctxt->am); 13161 ctxt->am = NULL; 13162 } 13163 13164 /** 13165 * xmlSchemaResolveElementReferences: 13166 * @elem: the schema element context 13167 * @ctxt: the schema parser context 13168 * 13169 * Resolves the references of an element declaration 13170 * or particle, which has an element declaration as it's 13171 * term. 13172 */ 13173 static void 13174 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13175 xmlSchemaParserCtxtPtr ctxt) 13176 { 13177 if ((ctxt == NULL) || (elemDecl == NULL) || 13178 ((elemDecl != NULL) && 13179 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13180 return; 13181 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13182 13183 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13184 xmlSchemaTypePtr type; 13185 13186 /* (type definition) ... otherwise the type definition resolved 13187 * to by the actual value of the type [attribute] ... 13188 */ 13189 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13190 elemDecl->namedTypeNs); 13191 if (type == NULL) { 13192 xmlSchemaPResCompAttrErr(ctxt, 13193 XML_SCHEMAP_SRC_RESOLVE, 13194 WXS_BASIC_CAST elemDecl, elemDecl->node, 13195 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13196 XML_SCHEMA_TYPE_BASIC, "type definition"); 13197 } else 13198 elemDecl->subtypes = type; 13199 } 13200 if (elemDecl->substGroup != NULL) { 13201 xmlSchemaElementPtr substHead; 13202 13203 /* 13204 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13205 * substitutionGroup? 13206 */ 13207 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13208 elemDecl->substGroupNs); 13209 if (substHead == NULL) { 13210 xmlSchemaPResCompAttrErr(ctxt, 13211 XML_SCHEMAP_SRC_RESOLVE, 13212 WXS_BASIC_CAST elemDecl, NULL, 13213 "substitutionGroup", elemDecl->substGroup, 13214 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13215 } else { 13216 xmlSchemaResolveElementReferences(substHead, ctxt); 13217 /* 13218 * Set the "substitution group affiliation". 13219 * NOTE that now we use the "refDecl" field for this. 13220 */ 13221 WXS_SUBST_HEAD(elemDecl) = substHead; 13222 /* 13223 * The type definitions is set to: 13224 * SPEC "...the {type definition} of the element 13225 * declaration resolved to by the actual value 13226 * of the substitutionGroup [attribute], if present" 13227 */ 13228 if (elemDecl->subtypes == NULL) 13229 elemDecl->subtypes = substHead->subtypes; 13230 } 13231 } 13232 /* 13233 * SPEC "The definition of anyType serves as the default type definition 13234 * for element declarations whose XML representation does not specify one." 13235 */ 13236 if ((elemDecl->subtypes == NULL) && 13237 (elemDecl->namedType == NULL) && 13238 (elemDecl->substGroup == NULL)) 13239 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13240 } 13241 13242 /** 13243 * xmlSchemaResolveUnionMemberTypes: 13244 * @ctxt: the schema parser context 13245 * @type: the schema simple type definition 13246 * 13247 * Checks and builds the "member type definitions" property of the union 13248 * simple type. This handles part (1), part (2) is done in 13249 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13250 * 13251 * Returns -1 in case of an internal error, 0 otherwise. 13252 */ 13253 static int 13254 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13255 xmlSchemaTypePtr type) 13256 { 13257 13258 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13259 xmlSchemaTypePtr memberType; 13260 13261 /* 13262 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13263 * define the explicit members as the type definitions resolved 13264 * to by the items in the actual value of the memberTypes [attribute], 13265 * if any, followed by the type definitions corresponding to the 13266 * <simpleType>s among the [children] of <union>, if any." 13267 */ 13268 /* 13269 * Resolve references. 13270 */ 13271 link = type->memberTypes; 13272 lastLink = NULL; 13273 while (link != NULL) { 13274 const xmlChar *name, *nsName; 13275 13276 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13277 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13278 13279 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13280 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13281 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13282 WXS_BASIC_CAST type, type->node, "memberTypes", 13283 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13284 /* 13285 * Remove the member type link. 13286 */ 13287 if (lastLink == NULL) 13288 type->memberTypes = link->next; 13289 else 13290 lastLink->next = link->next; 13291 newLink = link; 13292 link = link->next; 13293 xmlFree(newLink); 13294 } else { 13295 link->type = memberType; 13296 lastLink = link; 13297 link = link->next; 13298 } 13299 } 13300 /* 13301 * Add local simple types, 13302 */ 13303 memberType = type->subtypes; 13304 while (memberType != NULL) { 13305 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13306 if (link == NULL) { 13307 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13308 return (-1); 13309 } 13310 link->type = memberType; 13311 link->next = NULL; 13312 if (lastLink == NULL) 13313 type->memberTypes = link; 13314 else 13315 lastLink->next = link; 13316 lastLink = link; 13317 memberType = memberType->next; 13318 } 13319 return (0); 13320 } 13321 13322 /** 13323 * xmlSchemaIsDerivedFromBuiltInType: 13324 * @ctxt: the schema parser context 13325 * @type: the type definition 13326 * @valType: the value type 13327 * 13328 * 13329 * Returns 1 if the type has the given value type, or 13330 * is derived from such a type. 13331 */ 13332 static int 13333 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13334 { 13335 if (type == NULL) 13336 return (0); 13337 if (WXS_IS_COMPLEX(type)) 13338 return (0); 13339 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13340 if (type->builtInType == valType) 13341 return(1); 13342 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13343 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13344 return (0); 13345 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13346 } 13347 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13348 } 13349 13350 #if 0 13351 /** 13352 * xmlSchemaIsDerivedFromBuiltInType: 13353 * @ctxt: the schema parser context 13354 * @type: the type definition 13355 * @valType: the value type 13356 * 13357 * 13358 * Returns 1 if the type has the given value type, or 13359 * is derived from such a type. 13360 */ 13361 static int 13362 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13363 { 13364 if (type == NULL) 13365 return (0); 13366 if (WXS_IS_COMPLEX(type)) 13367 return (0); 13368 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13369 if (type->builtInType == valType) 13370 return(1); 13371 return (0); 13372 } else 13373 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13374 13375 return (0); 13376 } 13377 13378 static xmlSchemaTypePtr 13379 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13380 { 13381 if (type == NULL) 13382 return (NULL); 13383 if (WXS_IS_COMPLEX(type)) 13384 return (NULL); 13385 if (type->type == XML_SCHEMA_TYPE_BASIC) 13386 return(type); 13387 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13388 } 13389 #endif 13390 13391 /** 13392 * xmlSchemaGetPrimitiveType: 13393 * @type: the simpleType definition 13394 * 13395 * Returns the primitive type of the given type or 13396 * NULL in case of error. 13397 */ 13398 static xmlSchemaTypePtr 13399 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13400 { 13401 13402 while (type != NULL) { 13403 /* 13404 * Note that anySimpleType is actually not a primitive type 13405 * but we need that here. 13406 */ 13407 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13408 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13409 return (type); 13410 type = type->baseType; 13411 } 13412 13413 return (NULL); 13414 } 13415 13416 #if 0 13417 /** 13418 * xmlSchemaGetBuiltInTypeAncestor: 13419 * @type: the simpleType definition 13420 * 13421 * Returns the primitive type of the given type or 13422 * NULL in case of error. 13423 */ 13424 static xmlSchemaTypePtr 13425 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13426 { 13427 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13428 return (0); 13429 while (type != NULL) { 13430 if (type->type == XML_SCHEMA_TYPE_BASIC) 13431 return (type); 13432 type = type->baseType; 13433 } 13434 13435 return (NULL); 13436 } 13437 #endif 13438 13439 /** 13440 * xmlSchemaCloneWildcardNsConstraints: 13441 * @ctxt: the schema parser context 13442 * @dest: the destination wildcard 13443 * @source: the source wildcard 13444 * 13445 * Clones the namespace constraints of source 13446 * and assignes them to dest. 13447 * Returns -1 on internal error, 0 otherwise. 13448 */ 13449 static int 13450 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13451 xmlSchemaWildcardPtr dest, 13452 xmlSchemaWildcardPtr source) 13453 { 13454 xmlSchemaWildcardNsPtr cur, tmp, last; 13455 13456 if ((source == NULL) || (dest == NULL)) 13457 return(-1); 13458 dest->any = source->any; 13459 cur = source->nsSet; 13460 last = NULL; 13461 while (cur != NULL) { 13462 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13463 if (tmp == NULL) 13464 return(-1); 13465 tmp->value = cur->value; 13466 if (last == NULL) 13467 dest->nsSet = tmp; 13468 else 13469 last->next = tmp; 13470 last = tmp; 13471 cur = cur->next; 13472 } 13473 if (dest->negNsSet != NULL) 13474 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13475 if (source->negNsSet != NULL) { 13476 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13477 if (dest->negNsSet == NULL) 13478 return(-1); 13479 dest->negNsSet->value = source->negNsSet->value; 13480 } else 13481 dest->negNsSet = NULL; 13482 return(0); 13483 } 13484 13485 /** 13486 * xmlSchemaUnionWildcards: 13487 * @ctxt: the schema parser context 13488 * @completeWild: the first wildcard 13489 * @curWild: the second wildcard 13490 * 13491 * Unions the namespace constraints of the given wildcards. 13492 * @completeWild will hold the resulting union. 13493 * Returns a positive error code on failure, -1 in case of an 13494 * internal error, 0 otherwise. 13495 */ 13496 static int 13497 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13498 xmlSchemaWildcardPtr completeWild, 13499 xmlSchemaWildcardPtr curWild) 13500 { 13501 xmlSchemaWildcardNsPtr cur, curB, tmp; 13502 13503 /* 13504 * 1 If O1 and O2 are the same value, then that value must be the 13505 * value. 13506 */ 13507 if ((completeWild->any == curWild->any) && 13508 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13509 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13510 13511 if ((completeWild->negNsSet == NULL) || 13512 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13513 13514 if (completeWild->nsSet != NULL) { 13515 int found = 0; 13516 13517 /* 13518 * Check equality of sets. 13519 */ 13520 cur = completeWild->nsSet; 13521 while (cur != NULL) { 13522 found = 0; 13523 curB = curWild->nsSet; 13524 while (curB != NULL) { 13525 if (cur->value == curB->value) { 13526 found = 1; 13527 break; 13528 } 13529 curB = curB->next; 13530 } 13531 if (!found) 13532 break; 13533 cur = cur->next; 13534 } 13535 if (found) 13536 return(0); 13537 } else 13538 return(0); 13539 } 13540 } 13541 /* 13542 * 2 If either O1 or O2 is any, then any must be the value 13543 */ 13544 if (completeWild->any != curWild->any) { 13545 if (completeWild->any == 0) { 13546 completeWild->any = 1; 13547 if (completeWild->nsSet != NULL) { 13548 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13549 completeWild->nsSet = NULL; 13550 } 13551 if (completeWild->negNsSet != NULL) { 13552 xmlFree(completeWild->negNsSet); 13553 completeWild->negNsSet = NULL; 13554 } 13555 } 13556 return (0); 13557 } 13558 /* 13559 * 3 If both O1 and O2 are sets of (namespace names or absent), 13560 * then the union of those sets must be the value. 13561 */ 13562 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13563 int found; 13564 xmlSchemaWildcardNsPtr start; 13565 13566 cur = curWild->nsSet; 13567 start = completeWild->nsSet; 13568 while (cur != NULL) { 13569 found = 0; 13570 curB = start; 13571 while (curB != NULL) { 13572 if (cur->value == curB->value) { 13573 found = 1; 13574 break; 13575 } 13576 curB = curB->next; 13577 } 13578 if (!found) { 13579 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13580 if (tmp == NULL) 13581 return (-1); 13582 tmp->value = cur->value; 13583 tmp->next = completeWild->nsSet; 13584 completeWild->nsSet = tmp; 13585 } 13586 cur = cur->next; 13587 } 13588 13589 return(0); 13590 } 13591 /* 13592 * 4 If the two are negations of different values (namespace names 13593 * or absent), then a pair of not and absent must be the value. 13594 */ 13595 if ((completeWild->negNsSet != NULL) && 13596 (curWild->negNsSet != NULL) && 13597 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13598 completeWild->negNsSet->value = NULL; 13599 13600 return(0); 13601 } 13602 /* 13603 * 5. 13604 */ 13605 if (((completeWild->negNsSet != NULL) && 13606 (completeWild->negNsSet->value != NULL) && 13607 (curWild->nsSet != NULL)) || 13608 ((curWild->negNsSet != NULL) && 13609 (curWild->negNsSet->value != NULL) && 13610 (completeWild->nsSet != NULL))) { 13611 13612 int nsFound, absentFound = 0; 13613 13614 if (completeWild->nsSet != NULL) { 13615 cur = completeWild->nsSet; 13616 curB = curWild->negNsSet; 13617 } else { 13618 cur = curWild->nsSet; 13619 curB = completeWild->negNsSet; 13620 } 13621 nsFound = 0; 13622 while (cur != NULL) { 13623 if (cur->value == NULL) 13624 absentFound = 1; 13625 else if (cur->value == curB->value) 13626 nsFound = 1; 13627 if (nsFound && absentFound) 13628 break; 13629 cur = cur->next; 13630 } 13631 13632 if (nsFound && absentFound) { 13633 /* 13634 * 5.1 If the set S includes both the negated namespace 13635 * name and absent, then any must be the value. 13636 */ 13637 completeWild->any = 1; 13638 if (completeWild->nsSet != NULL) { 13639 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13640 completeWild->nsSet = NULL; 13641 } 13642 if (completeWild->negNsSet != NULL) { 13643 xmlFree(completeWild->negNsSet); 13644 completeWild->negNsSet = NULL; 13645 } 13646 } else if (nsFound && (!absentFound)) { 13647 /* 13648 * 5.2 If the set S includes the negated namespace name 13649 * but not absent, then a pair of not and absent must 13650 * be the value. 13651 */ 13652 if (completeWild->nsSet != NULL) { 13653 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13654 completeWild->nsSet = NULL; 13655 } 13656 if (completeWild->negNsSet == NULL) { 13657 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13658 if (completeWild->negNsSet == NULL) 13659 return (-1); 13660 } 13661 completeWild->negNsSet->value = NULL; 13662 } else if ((!nsFound) && absentFound) { 13663 /* 13664 * 5.3 If the set S includes absent but not the negated 13665 * namespace name, then the union is not expressible. 13666 */ 13667 xmlSchemaPErr(ctxt, completeWild->node, 13668 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13669 "The union of the wilcard is not expressible.\n", 13670 NULL, NULL); 13671 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13672 } else if ((!nsFound) && (!absentFound)) { 13673 /* 13674 * 5.4 If the set S does not include either the negated namespace 13675 * name or absent, then whichever of O1 or O2 is a pair of not 13676 * and a namespace name must be the value. 13677 */ 13678 if (completeWild->negNsSet == NULL) { 13679 if (completeWild->nsSet != NULL) { 13680 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13681 completeWild->nsSet = NULL; 13682 } 13683 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13684 if (completeWild->negNsSet == NULL) 13685 return (-1); 13686 completeWild->negNsSet->value = curWild->negNsSet->value; 13687 } 13688 } 13689 return (0); 13690 } 13691 /* 13692 * 6. 13693 */ 13694 if (((completeWild->negNsSet != NULL) && 13695 (completeWild->negNsSet->value == NULL) && 13696 (curWild->nsSet != NULL)) || 13697 ((curWild->negNsSet != NULL) && 13698 (curWild->negNsSet->value == NULL) && 13699 (completeWild->nsSet != NULL))) { 13700 13701 if (completeWild->nsSet != NULL) { 13702 cur = completeWild->nsSet; 13703 } else { 13704 cur = curWild->nsSet; 13705 } 13706 while (cur != NULL) { 13707 if (cur->value == NULL) { 13708 /* 13709 * 6.1 If the set S includes absent, then any must be the 13710 * value. 13711 */ 13712 completeWild->any = 1; 13713 if (completeWild->nsSet != NULL) { 13714 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13715 completeWild->nsSet = NULL; 13716 } 13717 if (completeWild->negNsSet != NULL) { 13718 xmlFree(completeWild->negNsSet); 13719 completeWild->negNsSet = NULL; 13720 } 13721 return (0); 13722 } 13723 cur = cur->next; 13724 } 13725 if (completeWild->negNsSet == NULL) { 13726 /* 13727 * 6.2 If the set S does not include absent, then a pair of not 13728 * and absent must be the value. 13729 */ 13730 if (completeWild->nsSet != NULL) { 13731 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13732 completeWild->nsSet = NULL; 13733 } 13734 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13735 if (completeWild->negNsSet == NULL) 13736 return (-1); 13737 completeWild->negNsSet->value = NULL; 13738 } 13739 return (0); 13740 } 13741 return (0); 13742 13743 } 13744 13745 /** 13746 * xmlSchemaIntersectWildcards: 13747 * @ctxt: the schema parser context 13748 * @completeWild: the first wildcard 13749 * @curWild: the second wildcard 13750 * 13751 * Intersects the namespace constraints of the given wildcards. 13752 * @completeWild will hold the resulting intersection. 13753 * Returns a positive error code on failure, -1 in case of an 13754 * internal error, 0 otherwise. 13755 */ 13756 static int 13757 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13758 xmlSchemaWildcardPtr completeWild, 13759 xmlSchemaWildcardPtr curWild) 13760 { 13761 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13762 13763 /* 13764 * 1 If O1 and O2 are the same value, then that value must be the 13765 * value. 13766 */ 13767 if ((completeWild->any == curWild->any) && 13768 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13769 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13770 13771 if ((completeWild->negNsSet == NULL) || 13772 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13773 13774 if (completeWild->nsSet != NULL) { 13775 int found = 0; 13776 13777 /* 13778 * Check equality of sets. 13779 */ 13780 cur = completeWild->nsSet; 13781 while (cur != NULL) { 13782 found = 0; 13783 curB = curWild->nsSet; 13784 while (curB != NULL) { 13785 if (cur->value == curB->value) { 13786 found = 1; 13787 break; 13788 } 13789 curB = curB->next; 13790 } 13791 if (!found) 13792 break; 13793 cur = cur->next; 13794 } 13795 if (found) 13796 return(0); 13797 } else 13798 return(0); 13799 } 13800 } 13801 /* 13802 * 2 If either O1 or O2 is any, then the other must be the value. 13803 */ 13804 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13805 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13806 return(-1); 13807 return(0); 13808 } 13809 /* 13810 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13811 * name or absent) and the other is a set of (namespace names or 13812 * absent), then that set, minus the negated value if it was in 13813 * the set, minus absent if it was in the set, must be the value. 13814 */ 13815 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13816 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13817 const xmlChar *neg; 13818 13819 if (completeWild->nsSet == NULL) { 13820 neg = completeWild->negNsSet->value; 13821 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13822 return(-1); 13823 } else 13824 neg = curWild->negNsSet->value; 13825 /* 13826 * Remove absent and negated. 13827 */ 13828 prev = NULL; 13829 cur = completeWild->nsSet; 13830 while (cur != NULL) { 13831 if (cur->value == NULL) { 13832 if (prev == NULL) 13833 completeWild->nsSet = cur->next; 13834 else 13835 prev->next = cur->next; 13836 xmlFree(cur); 13837 break; 13838 } 13839 prev = cur; 13840 cur = cur->next; 13841 } 13842 if (neg != NULL) { 13843 prev = NULL; 13844 cur = completeWild->nsSet; 13845 while (cur != NULL) { 13846 if (cur->value == neg) { 13847 if (prev == NULL) 13848 completeWild->nsSet = cur->next; 13849 else 13850 prev->next = cur->next; 13851 xmlFree(cur); 13852 break; 13853 } 13854 prev = cur; 13855 cur = cur->next; 13856 } 13857 } 13858 13859 return(0); 13860 } 13861 /* 13862 * 4 If both O1 and O2 are sets of (namespace names or absent), 13863 * then the intersection of those sets must be the value. 13864 */ 13865 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13866 int found; 13867 13868 cur = completeWild->nsSet; 13869 prev = NULL; 13870 while (cur != NULL) { 13871 found = 0; 13872 curB = curWild->nsSet; 13873 while (curB != NULL) { 13874 if (cur->value == curB->value) { 13875 found = 1; 13876 break; 13877 } 13878 curB = curB->next; 13879 } 13880 if (!found) { 13881 if (prev == NULL) 13882 completeWild->nsSet = cur->next; 13883 else 13884 prev->next = cur->next; 13885 tmp = cur->next; 13886 xmlFree(cur); 13887 cur = tmp; 13888 continue; 13889 } 13890 prev = cur; 13891 cur = cur->next; 13892 } 13893 13894 return(0); 13895 } 13896 /* 5 If the two are negations of different namespace names, 13897 * then the intersection is not expressible 13898 */ 13899 if ((completeWild->negNsSet != NULL) && 13900 (curWild->negNsSet != NULL) && 13901 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13902 (completeWild->negNsSet->value != NULL) && 13903 (curWild->negNsSet->value != NULL)) { 13904 13905 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13906 "The intersection of the wilcard is not expressible.\n", 13907 NULL, NULL); 13908 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13909 } 13910 /* 13911 * 6 If the one is a negation of a namespace name and the other 13912 * is a negation of absent, then the one which is the negation 13913 * of a namespace name must be the value. 13914 */ 13915 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13916 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13917 (completeWild->negNsSet->value == NULL)) { 13918 completeWild->negNsSet->value = curWild->negNsSet->value; 13919 } 13920 return(0); 13921 } 13922 13923 /** 13924 * xmlSchemaIsWildcardNsConstraintSubset: 13925 * @ctxt: the schema parser context 13926 * @sub: the first wildcard 13927 * @super: the second wildcard 13928 * 13929 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13930 * 13931 * Returns 0 if the namespace constraint of @sub is an intensional 13932 * subset of @super, 1 otherwise. 13933 */ 13934 static int 13935 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13936 xmlSchemaWildcardPtr super) 13937 { 13938 /* 13939 * 1 super must be any. 13940 */ 13941 if (super->any) 13942 return (0); 13943 /* 13944 * 2.1 sub must be a pair of not and a namespace name or absent. 13945 * 2.2 super must be a pair of not and the same value. 13946 */ 13947 if ((sub->negNsSet != NULL) && 13948 (super->negNsSet != NULL) && 13949 (sub->negNsSet->value == sub->negNsSet->value)) 13950 return (0); 13951 /* 13952 * 3.1 sub must be a set whose members are either namespace names or absent. 13953 */ 13954 if (sub->nsSet != NULL) { 13955 /* 13956 * 3.2.1 super must be the same set or a superset thereof. 13957 */ 13958 if (super->nsSet != NULL) { 13959 xmlSchemaWildcardNsPtr cur, curB; 13960 int found = 0; 13961 13962 cur = sub->nsSet; 13963 while (cur != NULL) { 13964 found = 0; 13965 curB = super->nsSet; 13966 while (curB != NULL) { 13967 if (cur->value == curB->value) { 13968 found = 1; 13969 break; 13970 } 13971 curB = curB->next; 13972 } 13973 if (!found) 13974 return (1); 13975 cur = cur->next; 13976 } 13977 if (found) 13978 return (0); 13979 } else if (super->negNsSet != NULL) { 13980 xmlSchemaWildcardNsPtr cur; 13981 /* 13982 * 3.2.2 super must be a pair of not and a namespace name or 13983 * absent and that value must not be in sub's set. 13984 */ 13985 cur = sub->nsSet; 13986 while (cur != NULL) { 13987 if (cur->value == super->negNsSet->value) 13988 return (1); 13989 cur = cur->next; 13990 } 13991 return (0); 13992 } 13993 } 13994 return (1); 13995 } 13996 13997 static int 13998 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 13999 int *fixed, 14000 const xmlChar **value, 14001 xmlSchemaValPtr *val) 14002 { 14003 *fixed = 0; 14004 *value = NULL; 14005 if (val != 0) 14006 *val = NULL; 14007 14008 if (attruse->defValue != NULL) { 14009 *value = attruse->defValue; 14010 if (val != NULL) 14011 *val = attruse->defVal; 14012 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14013 *fixed = 1; 14014 return(1); 14015 } else if ((attruse->attrDecl != NULL) && 14016 (attruse->attrDecl->defValue != NULL)) { 14017 *value = attruse->attrDecl->defValue; 14018 if (val != NULL) 14019 *val = attruse->attrDecl->defVal; 14020 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14021 *fixed = 1; 14022 return(1); 14023 } 14024 return(0); 14025 } 14026 /** 14027 * xmlSchemaCheckCVCWildcardNamespace: 14028 * @wild: the wildcard 14029 * @ns: the namespace 14030 * 14031 * Validation Rule: Wildcard allows Namespace Name 14032 * (cvc-wildcard-namespace) 14033 * 14034 * Returns 0 if the given namespace matches the wildcard, 14035 * 1 otherwise and -1 on API errors. 14036 */ 14037 static int 14038 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14039 const xmlChar* ns) 14040 { 14041 if (wild == NULL) 14042 return(-1); 14043 14044 if (wild->any) 14045 return(0); 14046 else if (wild->nsSet != NULL) { 14047 xmlSchemaWildcardNsPtr cur; 14048 14049 cur = wild->nsSet; 14050 while (cur != NULL) { 14051 if (xmlStrEqual(cur->value, ns)) 14052 return(0); 14053 cur = cur->next; 14054 } 14055 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14056 (!xmlStrEqual(wild->negNsSet->value, ns))) 14057 return(0); 14058 14059 return(1); 14060 } 14061 14062 #define XML_SCHEMA_ACTION_DERIVE 0 14063 #define XML_SCHEMA_ACTION_REDEFINE 1 14064 14065 #define WXS_ACTION_STR(a) \ 14066 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14067 14068 /* 14069 * Schema Component Constraint: 14070 * Derivation Valid (Restriction, Complex) 14071 * derivation-ok-restriction (2) - (4) 14072 * 14073 * ATTENTION: 14074 * In XML Schema 1.1 this will be: 14075 * Validation Rule: 14076 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14077 * 14078 */ 14079 static int 14080 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14081 int action, 14082 xmlSchemaBasicItemPtr item, 14083 xmlSchemaBasicItemPtr baseItem, 14084 xmlSchemaItemListPtr uses, 14085 xmlSchemaItemListPtr baseUses, 14086 xmlSchemaWildcardPtr wild, 14087 xmlSchemaWildcardPtr baseWild) 14088 { 14089 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14090 int i, j, found; /* err = 0; */ 14091 const xmlChar *bEffValue; 14092 int effFixed; 14093 14094 if (uses != NULL) { 14095 for (i = 0; i < uses->nbItems; i++) { 14096 cur = uses->items[i]; 14097 found = 0; 14098 if (baseUses == NULL) 14099 goto not_found; 14100 for (j = 0; j < baseUses->nbItems; j++) { 14101 bcur = baseUses->items[j]; 14102 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14103 WXS_ATTRUSE_DECL_NAME(bcur)) && 14104 (WXS_ATTRUSE_DECL_TNS(cur) == 14105 WXS_ATTRUSE_DECL_TNS(bcur))) 14106 { 14107 /* 14108 * (2.1) "If there is an attribute use in the {attribute 14109 * uses} of the {base type definition} (call this B) whose 14110 * {attribute declaration} has the same {name} and {target 14111 * namespace}, then all of the following must be true:" 14112 */ 14113 found = 1; 14114 14115 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14116 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14117 { 14118 xmlChar *str = NULL; 14119 /* 14120 * (2.1.1) "one of the following must be true:" 14121 * (2.1.1.1) "B's {required} is false." 14122 * (2.1.1.2) "R's {required} is true." 14123 */ 14124 xmlSchemaPAttrUseErr4(pctxt, 14125 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14126 WXS_ITEM_NODE(item), item, cur, 14127 "The 'optional' attribute use is inconsistent " 14128 "with the corresponding 'required' attribute use of " 14129 "the %s %s", 14130 WXS_ACTION_STR(action), 14131 xmlSchemaGetComponentDesignation(&str, baseItem), 14132 NULL, NULL); 14133 FREE_AND_NULL(str); 14134 /* err = pctxt->err; */ 14135 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14136 WXS_ATTRUSE_TYPEDEF(cur), 14137 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14138 { 14139 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14140 14141 /* 14142 * SPEC (2.1.2) "R's {attribute declaration}'s 14143 * {type definition} must be validly derived from 14144 * B's {type definition} given the empty set as 14145 * defined in Type Derivation OK (Simple) (3.14.6)." 14146 */ 14147 xmlSchemaPAttrUseErr4(pctxt, 14148 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14149 WXS_ITEM_NODE(item), item, cur, 14150 "The attribute declaration's %s " 14151 "is not validly derived from " 14152 "the corresponding %s of the " 14153 "attribute declaration in the %s %s", 14154 xmlSchemaGetComponentDesignation(&strA, 14155 WXS_ATTRUSE_TYPEDEF(cur)), 14156 xmlSchemaGetComponentDesignation(&strB, 14157 WXS_ATTRUSE_TYPEDEF(bcur)), 14158 WXS_ACTION_STR(action), 14159 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14160 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14161 FREE_AND_NULL(strA); 14162 FREE_AND_NULL(strB); 14163 FREE_AND_NULL(strC); 14164 /* err = pctxt->err; */ 14165 } else { 14166 /* 14167 * 2.1.3 [Definition:] Let the effective value 14168 * constraint of an attribute use be its {value 14169 * constraint}, if present, otherwise its {attribute 14170 * declaration}'s {value constraint} . 14171 */ 14172 xmlSchemaGetEffectiveValueConstraint(bcur, 14173 &effFixed, &bEffValue, NULL); 14174 /* 14175 * 2.1.3 ... one of the following must be true 14176 * 14177 * 2.1.3.1 B's effective value constraint is 14178 * absent or default. 14179 */ 14180 if ((bEffValue != NULL) && 14181 (effFixed == 1)) { 14182 const xmlChar *rEffValue = NULL; 14183 14184 xmlSchemaGetEffectiveValueConstraint(bcur, 14185 &effFixed, &rEffValue, NULL); 14186 /* 14187 * 2.1.3.2 R's effective value constraint is 14188 * fixed with the same string as B's. 14189 * MAYBE TODO: Compare the computed values. 14190 * Hmm, it says "same string" so 14191 * string-equality might really be sufficient. 14192 */ 14193 if ((effFixed == 0) || 14194 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14195 { 14196 xmlChar *str = NULL; 14197 14198 xmlSchemaPAttrUseErr4(pctxt, 14199 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14200 WXS_ITEM_NODE(item), item, cur, 14201 "The effective value constraint of the " 14202 "attribute use is inconsistent with " 14203 "its correspondent in the %s %s", 14204 WXS_ACTION_STR(action), 14205 xmlSchemaGetComponentDesignation(&str, 14206 baseItem), 14207 NULL, NULL); 14208 FREE_AND_NULL(str); 14209 /* err = pctxt->err; */ 14210 } 14211 } 14212 } 14213 break; 14214 } 14215 } 14216 not_found: 14217 if (!found) { 14218 /* 14219 * (2.2) "otherwise the {base type definition} must have an 14220 * {attribute wildcard} and the {target namespace} of the 14221 * R's {attribute declaration} must be valid with respect 14222 * to that wildcard, as defined in Wildcard allows Namespace 14223 * Name (3.10.4)." 14224 */ 14225 if ((baseWild == NULL) || 14226 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14227 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14228 { 14229 xmlChar *str = NULL; 14230 14231 xmlSchemaPAttrUseErr4(pctxt, 14232 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14233 WXS_ITEM_NODE(item), item, cur, 14234 "Neither a matching attribute use, " 14235 "nor a matching wildcard exists in the %s %s", 14236 WXS_ACTION_STR(action), 14237 xmlSchemaGetComponentDesignation(&str, baseItem), 14238 NULL, NULL); 14239 FREE_AND_NULL(str); 14240 /* err = pctxt->err; */ 14241 } 14242 } 14243 } 14244 } 14245 /* 14246 * SPEC derivation-ok-restriction (3): 14247 * (3) "For each attribute use in the {attribute uses} of the {base type 14248 * definition} whose {required} is true, there must be an attribute 14249 * use with an {attribute declaration} with the same {name} and 14250 * {target namespace} as its {attribute declaration} in the {attribute 14251 * uses} of the complex type definition itself whose {required} is true. 14252 */ 14253 if (baseUses != NULL) { 14254 for (j = 0; j < baseUses->nbItems; j++) { 14255 bcur = baseUses->items[j]; 14256 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14257 continue; 14258 found = 0; 14259 if (uses != NULL) { 14260 for (i = 0; i < uses->nbItems; i++) { 14261 cur = uses->items[i]; 14262 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14263 WXS_ATTRUSE_DECL_NAME(bcur)) && 14264 (WXS_ATTRUSE_DECL_TNS(cur) == 14265 WXS_ATTRUSE_DECL_TNS(bcur))) { 14266 found = 1; 14267 break; 14268 } 14269 } 14270 } 14271 if (!found) { 14272 xmlChar *strA = NULL, *strB = NULL; 14273 14274 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14275 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14276 NULL, item, 14277 "A matching attribute use for the " 14278 "'required' %s of the %s %s is missing", 14279 xmlSchemaGetComponentDesignation(&strA, bcur), 14280 WXS_ACTION_STR(action), 14281 xmlSchemaGetComponentDesignation(&strB, baseItem), 14282 NULL); 14283 FREE_AND_NULL(strA); 14284 FREE_AND_NULL(strB); 14285 } 14286 } 14287 } 14288 /* 14289 * derivation-ok-restriction (4) 14290 */ 14291 if (wild != NULL) { 14292 /* 14293 * (4) "If there is an {attribute wildcard}, all of the 14294 * following must be true:" 14295 */ 14296 if (baseWild == NULL) { 14297 xmlChar *str = NULL; 14298 14299 /* 14300 * (4.1) "The {base type definition} must also have one." 14301 */ 14302 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14303 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14304 NULL, item, 14305 "The %s has an attribute wildcard, " 14306 "but the %s %s '%s' does not have one", 14307 WXS_ITEM_TYPE_NAME(item), 14308 WXS_ACTION_STR(action), 14309 WXS_ITEM_TYPE_NAME(baseItem), 14310 xmlSchemaGetComponentQName(&str, baseItem)); 14311 FREE_AND_NULL(str); 14312 return(pctxt->err); 14313 } else if ((baseWild->any == 0) && 14314 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14315 { 14316 xmlChar *str = NULL; 14317 /* 14318 * (4.2) "The complex type definition's {attribute wildcard}'s 14319 * {namespace constraint} must be a subset of the {base type 14320 * definition}'s {attribute wildcard}'s {namespace constraint}, 14321 * as defined by Wildcard Subset (3.10.6)." 14322 */ 14323 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14324 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14325 NULL, item, 14326 "The attribute wildcard is not a valid " 14327 "subset of the wildcard in the %s %s '%s'", 14328 WXS_ACTION_STR(action), 14329 WXS_ITEM_TYPE_NAME(baseItem), 14330 xmlSchemaGetComponentQName(&str, baseItem), 14331 NULL); 14332 FREE_AND_NULL(str); 14333 return(pctxt->err); 14334 } 14335 /* 4.3 Unless the {base type definition} is the ur-type 14336 * definition, the complex type definition's {attribute 14337 * wildcard}'s {process contents} must be identical to or 14338 * stronger than the {base type definition}'s {attribute 14339 * wildcard}'s {process contents}, where strict is stronger 14340 * than lax is stronger than skip. 14341 */ 14342 if ((! WXS_IS_ANYTYPE(baseItem)) && 14343 (wild->processContents < baseWild->processContents)) { 14344 xmlChar *str = NULL; 14345 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14346 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14347 NULL, baseItem, 14348 "The {process contents} of the attribute wildcard is " 14349 "weaker than the one in the %s %s '%s'", 14350 WXS_ACTION_STR(action), 14351 WXS_ITEM_TYPE_NAME(baseItem), 14352 xmlSchemaGetComponentQName(&str, baseItem), 14353 NULL); 14354 FREE_AND_NULL(str) 14355 return(pctxt->err); 14356 } 14357 } 14358 return(0); 14359 } 14360 14361 14362 static int 14363 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14364 xmlSchemaBasicItemPtr item, 14365 xmlSchemaWildcardPtr *completeWild, 14366 xmlSchemaItemListPtr list, 14367 xmlSchemaItemListPtr prohibs); 14368 /** 14369 * xmlSchemaFixupTypeAttributeUses: 14370 * @ctxt: the schema parser context 14371 * @type: the complex type definition 14372 * 14373 * 14374 * Builds the wildcard and the attribute uses on the given complex type. 14375 * Returns -1 if an internal error occurs, 0 otherwise. 14376 * 14377 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14378 * strings, so recheck this if we start to hardcode some schemata, since 14379 * they might not be in the same dict. 14380 * NOTE: It is allowed to "extend" the xs:anyType type. 14381 */ 14382 static int 14383 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14384 xmlSchemaTypePtr type) 14385 { 14386 xmlSchemaTypePtr baseType = NULL; 14387 xmlSchemaAttributeUsePtr use; 14388 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14389 14390 if (type->baseType == NULL) { 14391 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14392 "no base type"); 14393 return (-1); 14394 } 14395 baseType = type->baseType; 14396 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14397 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14398 return(-1); 14399 14400 uses = type->attrUses; 14401 baseUses = baseType->attrUses; 14402 /* 14403 * Expand attribute group references. And build the 'complete' 14404 * wildcard, i.e. intersect multiple wildcards. 14405 * Move attribute prohibitions into a separate list. 14406 */ 14407 if (uses != NULL) { 14408 if (WXS_IS_RESTRICTION(type)) { 14409 /* 14410 * This one will transfer all attr. prohibitions 14411 * into pctxt->attrProhibs. 14412 */ 14413 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14414 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14415 pctxt->attrProhibs) == -1) 14416 { 14417 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14418 "failed to expand attributes"); 14419 } 14420 if (pctxt->attrProhibs->nbItems != 0) 14421 prohibs = pctxt->attrProhibs; 14422 } else { 14423 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14424 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14425 NULL) == -1) 14426 { 14427 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14428 "failed to expand attributes"); 14429 } 14430 } 14431 } 14432 /* 14433 * Inherit the attribute uses of the base type. 14434 */ 14435 if (baseUses != NULL) { 14436 int i, j; 14437 xmlSchemaAttributeUseProhibPtr pro; 14438 14439 if (WXS_IS_RESTRICTION(type)) { 14440 int usesCount; 14441 xmlSchemaAttributeUsePtr tmp; 14442 14443 if (uses != NULL) 14444 usesCount = uses->nbItems; 14445 else 14446 usesCount = 0; 14447 14448 /* Restriction. */ 14449 for (i = 0; i < baseUses->nbItems; i++) { 14450 use = baseUses->items[i]; 14451 if (prohibs) { 14452 /* 14453 * Filter out prohibited uses. 14454 */ 14455 for (j = 0; j < prohibs->nbItems; j++) { 14456 pro = prohibs->items[j]; 14457 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14458 (WXS_ATTRUSE_DECL_TNS(use) == 14459 pro->targetNamespace)) 14460 { 14461 goto inherit_next; 14462 } 14463 } 14464 } 14465 if (usesCount) { 14466 /* 14467 * Filter out existing uses. 14468 */ 14469 for (j = 0; j < usesCount; j++) { 14470 tmp = uses->items[j]; 14471 if ((WXS_ATTRUSE_DECL_NAME(use) == 14472 WXS_ATTRUSE_DECL_NAME(tmp)) && 14473 (WXS_ATTRUSE_DECL_TNS(use) == 14474 WXS_ATTRUSE_DECL_TNS(tmp))) 14475 { 14476 goto inherit_next; 14477 } 14478 } 14479 } 14480 if (uses == NULL) { 14481 type->attrUses = xmlSchemaItemListCreate(); 14482 if (type->attrUses == NULL) 14483 goto exit_failure; 14484 uses = type->attrUses; 14485 } 14486 xmlSchemaItemListAddSize(uses, 2, use); 14487 inherit_next: {} 14488 } 14489 } else { 14490 /* Extension. */ 14491 for (i = 0; i < baseUses->nbItems; i++) { 14492 use = baseUses->items[i]; 14493 if (uses == NULL) { 14494 type->attrUses = xmlSchemaItemListCreate(); 14495 if (type->attrUses == NULL) 14496 goto exit_failure; 14497 uses = type->attrUses; 14498 } 14499 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14500 } 14501 } 14502 } 14503 /* 14504 * Shrink attr. uses. 14505 */ 14506 if (uses) { 14507 if (uses->nbItems == 0) { 14508 xmlSchemaItemListFree(uses); 14509 type->attrUses = NULL; 14510 } 14511 /* 14512 * TODO: We could shrink the size of the array 14513 * to fit the actual number of items. 14514 */ 14515 } 14516 /* 14517 * Compute the complete wildcard. 14518 */ 14519 if (WXS_IS_EXTENSION(type)) { 14520 if (baseType->attributeWildcard != NULL) { 14521 /* 14522 * (3.2.2.1) "If the base wildcard is non-absent, then 14523 * the appropriate case among the following:" 14524 */ 14525 if (type->attributeWildcard != NULL) { 14526 /* 14527 * Union the complete wildcard with the base wildcard. 14528 * SPEC {attribute wildcard} 14529 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14530 * and {annotation} are those of the complete wildcard, 14531 * and whose {namespace constraint} is the intensional union 14532 * of the {namespace constraint} of the complete wildcard 14533 * and of the base wildcard, as defined in Attribute 14534 * Wildcard Union (3.10.6)." 14535 */ 14536 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14537 baseType->attributeWildcard) == -1) 14538 goto exit_failure; 14539 } else { 14540 /* 14541 * (3.2.2.1.1) "If the complete wildcard is absent, 14542 * then the base wildcard." 14543 */ 14544 type->attributeWildcard = baseType->attributeWildcard; 14545 } 14546 } else { 14547 /* 14548 * (3.2.2.2) "otherwise (the base wildcard is absent) the 14549 * complete wildcard" 14550 * NOOP 14551 */ 14552 } 14553 } else { 14554 /* 14555 * SPEC {attribute wildcard} 14556 * (3.1) "If the <restriction> alternative is chosen, then the 14557 * complete wildcard;" 14558 * NOOP 14559 */ 14560 } 14561 14562 return (0); 14563 14564 exit_failure: 14565 return(-1); 14566 } 14567 14568 /** 14569 * xmlSchemaTypeFinalContains: 14570 * @schema: the schema 14571 * @type: the type definition 14572 * @final: the final 14573 * 14574 * Evaluates if a type definition contains the given "final". 14575 * This does take "finalDefault" into account as well. 14576 * 14577 * Returns 1 if the type does containt the given "final", 14578 * 0 otherwise. 14579 */ 14580 static int 14581 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14582 { 14583 if (type == NULL) 14584 return (0); 14585 if (type->flags & final) 14586 return (1); 14587 else 14588 return (0); 14589 } 14590 14591 /** 14592 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14593 * @type: the Union Simple Type 14594 * 14595 * Returns a list of member types of @type if existing, 14596 * returns NULL otherwise. 14597 */ 14598 static xmlSchemaTypeLinkPtr 14599 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14600 { 14601 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14602 if (type->memberTypes != NULL) 14603 return (type->memberTypes); 14604 else 14605 type = type->baseType; 14606 } 14607 return (NULL); 14608 } 14609 14610 /** 14611 * xmlSchemaGetParticleTotalRangeMin: 14612 * @particle: the particle 14613 * 14614 * Schema Component Constraint: Effective Total Range 14615 * (all and sequence) + (choice) 14616 * 14617 * Returns the minimun Effective Total Range. 14618 */ 14619 static int 14620 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14621 { 14622 if ((particle->children == NULL) || 14623 (particle->minOccurs == 0)) 14624 return (0); 14625 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14626 int min = -1, cur; 14627 xmlSchemaParticlePtr part = 14628 (xmlSchemaParticlePtr) particle->children->children; 14629 14630 if (part == NULL) 14631 return (0); 14632 while (part != NULL) { 14633 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14634 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14635 cur = part->minOccurs; 14636 else 14637 cur = xmlSchemaGetParticleTotalRangeMin(part); 14638 if (cur == 0) 14639 return (0); 14640 if ((min > cur) || (min == -1)) 14641 min = cur; 14642 part = (xmlSchemaParticlePtr) part->next; 14643 } 14644 return (particle->minOccurs * min); 14645 } else { 14646 /* <all> and <sequence> */ 14647 int sum = 0; 14648 xmlSchemaParticlePtr part = 14649 (xmlSchemaParticlePtr) particle->children->children; 14650 14651 if (part == NULL) 14652 return (0); 14653 do { 14654 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14655 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14656 sum += part->minOccurs; 14657 else 14658 sum += xmlSchemaGetParticleTotalRangeMin(part); 14659 part = (xmlSchemaParticlePtr) part->next; 14660 } while (part != NULL); 14661 return (particle->minOccurs * sum); 14662 } 14663 } 14664 14665 #if 0 14666 /** 14667 * xmlSchemaGetParticleTotalRangeMax: 14668 * @particle: the particle 14669 * 14670 * Schema Component Constraint: Effective Total Range 14671 * (all and sequence) + (choice) 14672 * 14673 * Returns the maximum Effective Total Range. 14674 */ 14675 static int 14676 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14677 { 14678 if ((particle->children == NULL) || 14679 (particle->children->children == NULL)) 14680 return (0); 14681 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14682 int max = -1, cur; 14683 xmlSchemaParticlePtr part = 14684 (xmlSchemaParticlePtr) particle->children->children; 14685 14686 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14687 if (part->children == NULL) 14688 continue; 14689 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14690 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14691 cur = part->maxOccurs; 14692 else 14693 cur = xmlSchemaGetParticleTotalRangeMax(part); 14694 if (cur == UNBOUNDED) 14695 return (UNBOUNDED); 14696 if ((max < cur) || (max == -1)) 14697 max = cur; 14698 } 14699 /* TODO: Handle overflows? */ 14700 return (particle->maxOccurs * max); 14701 } else { 14702 /* <all> and <sequence> */ 14703 int sum = 0, cur; 14704 xmlSchemaParticlePtr part = 14705 (xmlSchemaParticlePtr) particle->children->children; 14706 14707 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14708 if (part->children == NULL) 14709 continue; 14710 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14711 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14712 cur = part->maxOccurs; 14713 else 14714 cur = xmlSchemaGetParticleTotalRangeMax(part); 14715 if (cur == UNBOUNDED) 14716 return (UNBOUNDED); 14717 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14718 return (UNBOUNDED); 14719 sum += cur; 14720 } 14721 /* TODO: Handle overflows? */ 14722 return (particle->maxOccurs * sum); 14723 } 14724 } 14725 #endif 14726 14727 /** 14728 * xmlSchemaIsParticleEmptiable: 14729 * @particle: the particle 14730 * 14731 * Schema Component Constraint: Particle Emptiable 14732 * Checks whether the given particle is emptiable. 14733 * 14734 * Returns 1 if emptiable, 0 otherwise. 14735 */ 14736 static int 14737 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14738 { 14739 /* 14740 * SPEC (1) "Its {min occurs} is 0." 14741 */ 14742 if ((particle == NULL) || (particle->minOccurs == 0) || 14743 (particle->children == NULL)) 14744 return (1); 14745 /* 14746 * SPEC (2) "Its {term} is a group and the minimum part of the 14747 * effective total range of that group, [...] is 0." 14748 */ 14749 if (WXS_IS_MODEL_GROUP(particle->children)) { 14750 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14751 return (1); 14752 } 14753 return (0); 14754 } 14755 14756 /** 14757 * xmlSchemaCheckCOSSTDerivedOK: 14758 * @actxt: a context 14759 * @type: the derived simple type definition 14760 * @baseType: the base type definition 14761 * @subset: the subset of ('restriction', ect.) 14762 * 14763 * Schema Component Constraint: 14764 * Type Derivation OK (Simple) (cos-st-derived-OK) 14765 * 14766 * Checks wheter @type can be validly 14767 * derived from @baseType. 14768 * 14769 * Returns 0 on success, an positive error code otherwise. 14770 */ 14771 static int 14772 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14773 xmlSchemaTypePtr type, 14774 xmlSchemaTypePtr baseType, 14775 int subset) 14776 { 14777 /* 14778 * 1 They are the same type definition. 14779 * TODO: The identy check might have to be more complex than this. 14780 */ 14781 if (type == baseType) 14782 return (0); 14783 /* 14784 * 2.1 restriction is not in the subset, or in the {final} 14785 * of its own {base type definition}; 14786 * 14787 * NOTE that this will be used also via "xsi:type". 14788 * 14789 * TODO: Revise this, it looks strange. How can the "type" 14790 * not be fixed or *in* fixing? 14791 */ 14792 if (WXS_IS_TYPE_NOT_FIXED(type)) 14793 if (xmlSchemaTypeFixup(type, actxt) == -1) 14794 return(-1); 14795 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14796 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14797 return(-1); 14798 if ((subset & SUBSET_RESTRICTION) || 14799 (xmlSchemaTypeFinalContains(type->baseType, 14800 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14801 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14802 } 14803 /* 2.2 */ 14804 if (type->baseType == baseType) { 14805 /* 14806 * 2.2.1 D's base type definition is B. 14807 */ 14808 return (0); 14809 } 14810 /* 14811 * 2.2.2 D's base type definition is not the ur-type definition 14812 * and is validly derived from B given the subset, as defined by this 14813 * constraint. 14814 */ 14815 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14816 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14817 baseType, subset) == 0)) { 14818 return (0); 14819 } 14820 /* 14821 * 2.2.3 D's {variety} is list or union and B is the simple ur-type 14822 * definition. 14823 */ 14824 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14825 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14826 return (0); 14827 } 14828 /* 14829 * 2.2.4 B's {variety} is union and D is validly derived from a type 14830 * definition in B's {member type definitions} given the subset, as 14831 * defined by this constraint. 14832 * 14833 * NOTE: This seems not to involve built-in types, since there is no 14834 * built-in Union Simple Type. 14835 */ 14836 if (WXS_IS_UNION(baseType)) { 14837 xmlSchemaTypeLinkPtr cur; 14838 14839 cur = baseType->memberTypes; 14840 while (cur != NULL) { 14841 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14842 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14843 return(-1); 14844 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14845 type, cur->type, subset) == 0) 14846 { 14847 /* 14848 * It just has to be validly derived from at least one 14849 * member-type. 14850 */ 14851 return (0); 14852 } 14853 cur = cur->next; 14854 } 14855 } 14856 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14857 } 14858 14859 /** 14860 * xmlSchemaCheckTypeDefCircularInternal: 14861 * @pctxt: the schema parser context 14862 * @ctxtType: the type definition 14863 * @ancestor: an ancestor of @ctxtType 14864 * 14865 * Checks st-props-correct (2) + ct-props-correct (3). 14866 * Circular type definitions are not allowed. 14867 * 14868 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14869 * circular, 0 otherwise. 14870 */ 14871 static int 14872 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14873 xmlSchemaTypePtr ctxtType, 14874 xmlSchemaTypePtr ancestor) 14875 { 14876 int ret; 14877 14878 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14879 return (0); 14880 14881 if (ctxtType == ancestor) { 14882 xmlSchemaPCustomErr(pctxt, 14883 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14884 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14885 "The definition is circular", NULL); 14886 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14887 } 14888 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14889 /* 14890 * Avoid inifinite recursion on circular types not yet checked. 14891 */ 14892 return (0); 14893 } 14894 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14895 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14896 ancestor->baseType); 14897 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14898 return (ret); 14899 } 14900 14901 /** 14902 * xmlSchemaCheckTypeDefCircular: 14903 * @item: the complex/simple type definition 14904 * @ctxt: the parser context 14905 * @name: the name 14906 * 14907 * Checks for circular type definitions. 14908 */ 14909 static void 14910 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14911 xmlSchemaParserCtxtPtr ctxt) 14912 { 14913 if ((item == NULL) || 14914 (item->type == XML_SCHEMA_TYPE_BASIC) || 14915 (item->baseType == NULL)) 14916 return; 14917 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14918 item->baseType); 14919 } 14920 14921 /* 14922 * Simple Type Definition Representation OK (src-simple-type) 4 14923 * 14924 * "4 Circular union type definition is disallowed. That is, if the 14925 * <union> alternative is chosen, there must not be any entries in the 14926 * memberTypes [attribute] at any depth which resolve to the component 14927 * corresponding to the <simpleType>." 14928 * 14929 * Note that this should work on the *representation* of a component, 14930 * thus assumes any union types in the member types not being yet 14931 * substituted. At this stage we need the variety of the types 14932 * to be already computed. 14933 */ 14934 static int 14935 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14936 xmlSchemaTypePtr ctxType, 14937 xmlSchemaTypeLinkPtr members) 14938 { 14939 xmlSchemaTypeLinkPtr member; 14940 xmlSchemaTypePtr memberType; 14941 14942 member = members; 14943 while (member != NULL) { 14944 memberType = member->type; 14945 while ((memberType != NULL) && 14946 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14947 if (memberType == ctxType) { 14948 xmlSchemaPCustomErr(pctxt, 14949 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14950 WXS_BASIC_CAST ctxType, NULL, 14951 "The union type definition is circular", NULL); 14952 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14953 } 14954 if ((WXS_IS_UNION(memberType)) && 14955 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14956 { 14957 int res; 14958 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 14959 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 14960 ctxType, 14961 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 14962 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 14963 if (res != 0) 14964 return(res); 14965 } 14966 memberType = memberType->baseType; 14967 } 14968 member = member->next; 14969 } 14970 return(0); 14971 } 14972 14973 static int 14974 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 14975 xmlSchemaTypePtr type) 14976 { 14977 if (! WXS_IS_UNION(type)) 14978 return(0); 14979 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 14980 type->memberTypes)); 14981 } 14982 14983 /** 14984 * xmlSchemaResolveTypeReferences: 14985 * @item: the complex/simple type definition 14986 * @ctxt: the parser context 14987 * @name: the name 14988 * 14989 * Resolvese type definition references 14990 */ 14991 static void 14992 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 14993 xmlSchemaParserCtxtPtr ctxt) 14994 { 14995 if (typeDef == NULL) 14996 return; 14997 14998 /* 14999 * Resolve the base type. 15000 */ 15001 if (typeDef->baseType == NULL) { 15002 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15003 typeDef->base, typeDef->baseNs); 15004 if (typeDef->baseType == NULL) { 15005 xmlSchemaPResCompAttrErr(ctxt, 15006 XML_SCHEMAP_SRC_RESOLVE, 15007 WXS_BASIC_CAST typeDef, typeDef->node, 15008 "base", typeDef->base, typeDef->baseNs, 15009 XML_SCHEMA_TYPE_SIMPLE, NULL); 15010 return; 15011 } 15012 } 15013 if (WXS_IS_SIMPLE(typeDef)) { 15014 if (WXS_IS_UNION(typeDef)) { 15015 /* 15016 * Resolve the memberTypes. 15017 */ 15018 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15019 return; 15020 } else if (WXS_IS_LIST(typeDef)) { 15021 /* 15022 * Resolve the itemType. 15023 */ 15024 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15025 15026 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15027 typeDef->base, typeDef->baseNs); 15028 15029 if ((typeDef->subtypes == NULL) || 15030 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15031 { 15032 typeDef->subtypes = NULL; 15033 xmlSchemaPResCompAttrErr(ctxt, 15034 XML_SCHEMAP_SRC_RESOLVE, 15035 WXS_BASIC_CAST typeDef, typeDef->node, 15036 "itemType", typeDef->base, typeDef->baseNs, 15037 XML_SCHEMA_TYPE_SIMPLE, NULL); 15038 } 15039 } 15040 return; 15041 } 15042 } 15043 /* 15044 * The ball of letters below means, that if we have a particle 15045 * which has a QName-helper component as its {term}, we want 15046 * to resolve it... 15047 */ 15048 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15049 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15050 XML_SCHEMA_TYPE_PARTICLE) && 15051 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15052 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15053 XML_SCHEMA_EXTRA_QNAMEREF)) 15054 { 15055 xmlSchemaQNameRefPtr ref = 15056 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15057 xmlSchemaModelGroupDefPtr groupDef; 15058 15059 /* 15060 * URGENT TODO: Test this. 15061 */ 15062 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15063 /* 15064 * Resolve the MG definition reference. 15065 */ 15066 groupDef = 15067 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15068 ref->itemType, ref->name, ref->targetNamespace); 15069 if (groupDef == NULL) { 15070 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15071 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15072 "ref", ref->name, ref->targetNamespace, ref->itemType, 15073 NULL); 15074 /* Remove the particle. */ 15075 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15076 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15077 /* Remove the particle. */ 15078 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15079 else { 15080 /* 15081 * Assign the MG definition's {model group} to the 15082 * particle's {term}. 15083 */ 15084 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15085 15086 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15087 /* 15088 * SPEC cos-all-limited (1.2) 15089 * "1.2 the {term} property of a particle with 15090 * {max occurs}=1 which is part of a pair which constitutes 15091 * the {content type} of a complex type definition." 15092 */ 15093 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15094 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15095 /* TODO: error code */ 15096 XML_SCHEMAP_COS_ALL_LIMITED, 15097 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15098 "The particle's {max occurs} must be 1, since the " 15099 "reference resolves to an 'all' model group", 15100 NULL, NULL); 15101 } 15102 } 15103 } 15104 } 15105 } 15106 15107 15108 15109 /** 15110 * xmlSchemaCheckSTPropsCorrect: 15111 * @ctxt: the schema parser context 15112 * @type: the simple type definition 15113 * 15114 * Checks st-props-correct. 15115 * 15116 * Returns 0 if the properties are correct, 15117 * if not, a positive error code and -1 on internal 15118 * errors. 15119 */ 15120 static int 15121 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15122 xmlSchemaTypePtr type) 15123 { 15124 xmlSchemaTypePtr baseType = type->baseType; 15125 xmlChar *str = NULL; 15126 15127 /* STATE: error funcs converted. */ 15128 /* 15129 * Schema Component Constraint: Simple Type Definition Properties Correct 15130 * 15131 * NOTE: This is somehow redundant, since we actually built a simple type 15132 * to have all the needed information; this acts as an self test. 15133 */ 15134 /* Base type: If the datatype has been derived by restriction 15135 * then the Simple Type Definition component from which it is derived, 15136 * otherwise the Simple Type Definition for anySimpleType (4.1.6). 15137 */ 15138 if (baseType == NULL) { 15139 /* 15140 * TODO: Think about: "modulo the impact of Missing 15141 * Sub-components (5.3)." 15142 */ 15143 xmlSchemaPCustomErr(ctxt, 15144 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15145 WXS_BASIC_CAST type, NULL, 15146 "No base type existent", NULL); 15147 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15148 15149 } 15150 if (! WXS_IS_SIMPLE(baseType)) { 15151 xmlSchemaPCustomErr(ctxt, 15152 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15153 WXS_BASIC_CAST type, NULL, 15154 "The base type '%s' is not a simple type", 15155 xmlSchemaGetComponentQName(&str, baseType)); 15156 FREE_AND_NULL(str) 15157 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15158 } 15159 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15160 (WXS_IS_RESTRICTION(type) == 0) && 15161 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15162 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15163 xmlSchemaPCustomErr(ctxt, 15164 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15165 WXS_BASIC_CAST type, NULL, 15166 "A type, derived by list or union, must have " 15167 "the simple ur-type definition as base type, not '%s'", 15168 xmlSchemaGetComponentQName(&str, baseType)); 15169 FREE_AND_NULL(str) 15170 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15171 } 15172 /* 15173 * Variety: One of {atomic, list, union}. 15174 */ 15175 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15176 (! WXS_IS_LIST(type))) { 15177 xmlSchemaPCustomErr(ctxt, 15178 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15179 WXS_BASIC_CAST type, NULL, 15180 "The variety is absent", NULL); 15181 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15182 } 15183 /* TODO: Finish this. Hmm, is this finished? */ 15184 15185 /* 15186 * 3 The {final} of the {base type definition} must not contain restriction. 15187 */ 15188 if (xmlSchemaTypeFinalContains(baseType, 15189 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15190 xmlSchemaPCustomErr(ctxt, 15191 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15192 WXS_BASIC_CAST type, NULL, 15193 "The 'final' of its base type '%s' must not contain " 15194 "'restriction'", 15195 xmlSchemaGetComponentQName(&str, baseType)); 15196 FREE_AND_NULL(str) 15197 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15198 } 15199 15200 /* 15201 * 2 All simple type definitions must be derived ultimately from the simple 15202 * ur-type definition (so circular definitions are disallowed). That is, it 15203 * must be possible to reach a built-in primitive datatype or the simple 15204 * ur-type definition by repeatedly following the {base type definition}. 15205 * 15206 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15207 */ 15208 return (0); 15209 } 15210 15211 /** 15212 * xmlSchemaCheckCOSSTRestricts: 15213 * @ctxt: the schema parser context 15214 * @type: the simple type definition 15215 * 15216 * Schema Component Constraint: 15217 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15218 15219 * Checks if the given @type (simpleType) is derived validly by restriction. 15220 * STATUS: 15221 * 15222 * Returns -1 on internal errors, 0 if the type is validly derived, 15223 * a positive error code otherwise. 15224 */ 15225 static int 15226 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15227 xmlSchemaTypePtr type) 15228 { 15229 xmlChar *str = NULL; 15230 15231 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15232 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15233 "given type is not a user-derived simpleType"); 15234 return (-1); 15235 } 15236 15237 if (WXS_IS_ATOMIC(type)) { 15238 xmlSchemaTypePtr primitive; 15239 /* 15240 * 1.1 The {base type definition} must be an atomic simple 15241 * type definition or a built-in primitive datatype. 15242 */ 15243 if (! WXS_IS_ATOMIC(type->baseType)) { 15244 xmlSchemaPCustomErr(pctxt, 15245 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15246 WXS_BASIC_CAST type, NULL, 15247 "The base type '%s' is not an atomic simple type", 15248 xmlSchemaGetComponentQName(&str, type->baseType)); 15249 FREE_AND_NULL(str) 15250 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15251 } 15252 /* 1.2 The {final} of the {base type definition} must not contain 15253 * restriction. 15254 */ 15255 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15256 if (xmlSchemaTypeFinalContains(type->baseType, 15257 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15258 xmlSchemaPCustomErr(pctxt, 15259 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15260 WXS_BASIC_CAST type, NULL, 15261 "The final of its base type '%s' must not contain 'restriction'", 15262 xmlSchemaGetComponentQName(&str, type->baseType)); 15263 FREE_AND_NULL(str) 15264 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15265 } 15266 15267 /* 15268 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15269 * type definition}, as specified in the appropriate subsection of 3.2 15270 * Primitive datatypes. 15271 */ 15272 if (type->facets != NULL) { 15273 xmlSchemaFacetPtr facet; 15274 int ok = 1; 15275 15276 primitive = xmlSchemaGetPrimitiveType(type); 15277 if (primitive == NULL) { 15278 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15279 "failed to get primitive type"); 15280 return (-1); 15281 } 15282 facet = type->facets; 15283 do { 15284 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15285 ok = 0; 15286 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15287 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15288 type, primitive, facet); 15289 } 15290 facet = facet->next; 15291 } while (facet != NULL); 15292 if (ok == 0) 15293 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15294 } 15295 /* 15296 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15297 * of the {base type definition} (call this BF),then the DF's {value} 15298 * must be a valid restriction of BF's {value} as defined in 15299 * [XML Schemas: Datatypes]." 15300 * 15301 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15302 * xmlSchemaDeriveAndValidateFacets() 15303 */ 15304 } else if (WXS_IS_LIST(type)) { 15305 xmlSchemaTypePtr itemType = NULL; 15306 15307 itemType = type->subtypes; 15308 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15309 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15310 "failed to evaluate the item type"); 15311 return (-1); 15312 } 15313 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15314 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15315 /* 15316 * 2.1 The {item type definition} must have a {variety} of atomic or 15317 * union (in which case all the {member type definitions} 15318 * must be atomic). 15319 */ 15320 if ((! WXS_IS_ATOMIC(itemType)) && 15321 (! WXS_IS_UNION(itemType))) { 15322 xmlSchemaPCustomErr(pctxt, 15323 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15324 WXS_BASIC_CAST type, NULL, 15325 "The item type '%s' does not have a variety of atomic or union", 15326 xmlSchemaGetComponentQName(&str, itemType)); 15327 FREE_AND_NULL(str) 15328 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15329 } else if (WXS_IS_UNION(itemType)) { 15330 xmlSchemaTypeLinkPtr member; 15331 15332 member = itemType->memberTypes; 15333 while (member != NULL) { 15334 if (! WXS_IS_ATOMIC(member->type)) { 15335 xmlSchemaPCustomErr(pctxt, 15336 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15337 WXS_BASIC_CAST type, NULL, 15338 "The item type is a union type, but the " 15339 "member type '%s' of this item type is not atomic", 15340 xmlSchemaGetComponentQName(&str, member->type)); 15341 FREE_AND_NULL(str) 15342 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15343 } 15344 member = member->next; 15345 } 15346 } 15347 15348 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15349 xmlSchemaFacetPtr facet; 15350 /* 15351 * This is the case if we have: <simpleType><list .. 15352 */ 15353 /* 15354 * 2.3.1 15355 * 2.3.1.1 The {final} of the {item type definition} must not 15356 * contain list. 15357 */ 15358 if (xmlSchemaTypeFinalContains(itemType, 15359 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15360 xmlSchemaPCustomErr(pctxt, 15361 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15362 WXS_BASIC_CAST type, NULL, 15363 "The final of its item type '%s' must not contain 'list'", 15364 xmlSchemaGetComponentQName(&str, itemType)); 15365 FREE_AND_NULL(str) 15366 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15367 } 15368 /* 15369 * 2.3.1.2 The {facets} must only contain the whiteSpace 15370 * facet component. 15371 * OPTIMIZE TODO: the S4S already disallows any facet 15372 * to be specified. 15373 */ 15374 if (type->facets != NULL) { 15375 facet = type->facets; 15376 do { 15377 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15378 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15379 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15380 type, facet); 15381 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15382 } 15383 facet = facet->next; 15384 } while (facet != NULL); 15385 } 15386 /* 15387 * MAYBE TODO: (Hmm, not really) Datatypes states: 15388 * A list datatype can be derived from an atomic datatype 15389 * whose lexical space allows space (such as string or anyURI)or 15390 * a union datatype any of whose {member type definitions}'s 15391 * lexical space allows space. 15392 */ 15393 } else { 15394 /* 15395 * This is the case if we have: <simpleType><restriction ... 15396 * I.e. the variety of "list" is inherited. 15397 */ 15398 /* 15399 * 2.3.2 15400 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15401 */ 15402 if (! WXS_IS_LIST(type->baseType)) { 15403 xmlSchemaPCustomErr(pctxt, 15404 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15405 WXS_BASIC_CAST type, NULL, 15406 "The base type '%s' must be a list type", 15407 xmlSchemaGetComponentQName(&str, type->baseType)); 15408 FREE_AND_NULL(str) 15409 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15410 } 15411 /* 15412 * 2.3.2.2 The {final} of the {base type definition} must not 15413 * contain restriction. 15414 */ 15415 if (xmlSchemaTypeFinalContains(type->baseType, 15416 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15417 xmlSchemaPCustomErr(pctxt, 15418 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15419 WXS_BASIC_CAST type, NULL, 15420 "The 'final' of the base type '%s' must not contain 'restriction'", 15421 xmlSchemaGetComponentQName(&str, type->baseType)); 15422 FREE_AND_NULL(str) 15423 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15424 } 15425 /* 15426 * 2.3.2.3 The {item type definition} must be validly derived 15427 * from the {base type definition}'s {item type definition} given 15428 * the empty set, as defined in Type Derivation OK (Simple) (3.14.6). 15429 */ 15430 { 15431 xmlSchemaTypePtr baseItemType; 15432 15433 baseItemType = type->baseType->subtypes; 15434 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15435 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15436 "failed to eval the item type of a base type"); 15437 return (-1); 15438 } 15439 if ((itemType != baseItemType) && 15440 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15441 baseItemType, 0) != 0)) { 15442 xmlChar *strBIT = NULL, *strBT = NULL; 15443 xmlSchemaPCustomErrExt(pctxt, 15444 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15445 WXS_BASIC_CAST type, NULL, 15446 "The item type '%s' is not validly derived from " 15447 "the item type '%s' of the base type '%s'", 15448 xmlSchemaGetComponentQName(&str, itemType), 15449 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15450 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15451 15452 FREE_AND_NULL(str) 15453 FREE_AND_NULL(strBIT) 15454 FREE_AND_NULL(strBT) 15455 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15456 } 15457 } 15458 15459 if (type->facets != NULL) { 15460 xmlSchemaFacetPtr facet; 15461 int ok = 1; 15462 /* 15463 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15464 * and enumeration facet components are allowed among the {facets}. 15465 */ 15466 facet = type->facets; 15467 do { 15468 switch (facet->type) { 15469 case XML_SCHEMA_FACET_LENGTH: 15470 case XML_SCHEMA_FACET_MINLENGTH: 15471 case XML_SCHEMA_FACET_MAXLENGTH: 15472 case XML_SCHEMA_FACET_WHITESPACE: 15473 /* 15474 * TODO: 2.5.1.2 List datatypes 15475 * The value of whiteSpace is fixed to the value collapse. 15476 */ 15477 case XML_SCHEMA_FACET_PATTERN: 15478 case XML_SCHEMA_FACET_ENUMERATION: 15479 break; 15480 default: { 15481 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15482 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15483 type, facet); 15484 /* 15485 * We could return, but it's nicer to report all 15486 * invalid facets. 15487 */ 15488 ok = 0; 15489 } 15490 } 15491 facet = facet->next; 15492 } while (facet != NULL); 15493 if (ok == 0) 15494 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15495 /* 15496 * SPEC (2.3.2.5) (same as 1.3.2) 15497 * 15498 * NOTE (2.3.2.5) This is currently done in 15499 * xmlSchemaDeriveAndValidateFacets() 15500 */ 15501 } 15502 } 15503 } else if (WXS_IS_UNION(type)) { 15504 /* 15505 * 3.1 The {member type definitions} must all have {variety} of 15506 * atomic or list. 15507 */ 15508 xmlSchemaTypeLinkPtr member; 15509 15510 member = type->memberTypes; 15511 while (member != NULL) { 15512 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15513 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15514 15515 if ((! WXS_IS_ATOMIC(member->type)) && 15516 (! WXS_IS_LIST(member->type))) { 15517 xmlSchemaPCustomErr(pctxt, 15518 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15519 WXS_BASIC_CAST type, NULL, 15520 "The member type '%s' is neither an atomic, nor a list type", 15521 xmlSchemaGetComponentQName(&str, member->type)); 15522 FREE_AND_NULL(str) 15523 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15524 } 15525 member = member->next; 15526 } 15527 /* 15528 * 3.3.1 If the {base type definition} is the simple ur-type 15529 * definition 15530 */ 15531 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15532 /* 15533 * 3.3.1.1 All of the {member type definitions} must have a 15534 * {final} which does not contain union. 15535 */ 15536 member = type->memberTypes; 15537 while (member != NULL) { 15538 if (xmlSchemaTypeFinalContains(member->type, 15539 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15540 xmlSchemaPCustomErr(pctxt, 15541 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15542 WXS_BASIC_CAST type, NULL, 15543 "The 'final' of member type '%s' contains 'union'", 15544 xmlSchemaGetComponentQName(&str, member->type)); 15545 FREE_AND_NULL(str) 15546 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15547 } 15548 member = member->next; 15549 } 15550 /* 15551 * 3.3.1.2 The {facets} must be empty. 15552 */ 15553 if (type->facetSet != NULL) { 15554 xmlSchemaPCustomErr(pctxt, 15555 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15556 WXS_BASIC_CAST type, NULL, 15557 "No facets allowed", NULL); 15558 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15559 } 15560 } else { 15561 /* 15562 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15563 * I.e. the variety of "list" is inherited. 15564 */ 15565 if (! WXS_IS_UNION(type->baseType)) { 15566 xmlSchemaPCustomErr(pctxt, 15567 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15568 WXS_BASIC_CAST type, NULL, 15569 "The base type '%s' is not a union type", 15570 xmlSchemaGetComponentQName(&str, type->baseType)); 15571 FREE_AND_NULL(str) 15572 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15573 } 15574 /* 15575 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15576 */ 15577 if (xmlSchemaTypeFinalContains(type->baseType, 15578 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15579 xmlSchemaPCustomErr(pctxt, 15580 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15581 WXS_BASIC_CAST type, NULL, 15582 "The 'final' of its base type '%s' must not contain 'restriction'", 15583 xmlSchemaGetComponentQName(&str, type->baseType)); 15584 FREE_AND_NULL(str) 15585 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15586 } 15587 /* 15588 * 3.3.2.3 The {member type definitions}, in order, must be validly 15589 * derived from the corresponding type definitions in the {base 15590 * type definition}'s {member type definitions} given the empty set, 15591 * as defined in Type Derivation OK (Simple) (3.14.6). 15592 */ 15593 { 15594 xmlSchemaTypeLinkPtr baseMember; 15595 15596 /* 15597 * OPTIMIZE: if the type is restricting, it has no local defined 15598 * member types and inherits the member types of the base type; 15599 * thus a check for equality can be skipped. 15600 */ 15601 /* 15602 * Even worse: I cannot see a scenario where a restricting 15603 * union simple type can have other member types as the member 15604 * types of it's base type. This check seems not necessary with 15605 * respect to the derivation process in libxml2. 15606 * But necessary if constructing types with an API. 15607 */ 15608 if (type->memberTypes != NULL) { 15609 member = type->memberTypes; 15610 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15611 if ((member == NULL) && (baseMember != NULL)) { 15612 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15613 "different number of member types in base"); 15614 } 15615 while (member != NULL) { 15616 if (baseMember == NULL) { 15617 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15618 "different number of member types in base"); 15619 } else if ((member->type != baseMember->type) && 15620 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15621 member->type, baseMember->type, 0) != 0)) { 15622 xmlChar *strBMT = NULL, *strBT = NULL; 15623 15624 xmlSchemaPCustomErrExt(pctxt, 15625 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15626 WXS_BASIC_CAST type, NULL, 15627 "The member type %s is not validly " 15628 "derived from its corresponding member " 15629 "type %s of the base type %s", 15630 xmlSchemaGetComponentQName(&str, member->type), 15631 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15632 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15633 FREE_AND_NULL(str) 15634 FREE_AND_NULL(strBMT) 15635 FREE_AND_NULL(strBT) 15636 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15637 } 15638 member = member->next; 15639 if (baseMember != NULL) 15640 baseMember = baseMember->next; 15641 } 15642 } 15643 } 15644 /* 15645 * 3.3.2.4 Only pattern and enumeration facet components are 15646 * allowed among the {facets}. 15647 */ 15648 if (type->facets != NULL) { 15649 xmlSchemaFacetPtr facet; 15650 int ok = 1; 15651 15652 facet = type->facets; 15653 do { 15654 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15655 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15656 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15657 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15658 type, facet); 15659 ok = 0; 15660 } 15661 facet = facet->next; 15662 } while (facet != NULL); 15663 if (ok == 0) 15664 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15665 15666 } 15667 /* 15668 * SPEC (3.3.2.5) (same as 1.3.2) 15669 * 15670 * NOTE (3.3.2.5) This is currently done in 15671 * xmlSchemaDeriveAndValidateFacets() 15672 */ 15673 } 15674 } 15675 15676 return (0); 15677 } 15678 15679 /** 15680 * xmlSchemaCheckSRCSimpleType: 15681 * @ctxt: the schema parser context 15682 * @type: the simple type definition 15683 * 15684 * Checks crc-simple-type constraints. 15685 * 15686 * Returns 0 if the constraints are satisfied, 15687 * if not a positive error code and -1 on internal 15688 * errors. 15689 */ 15690 #if 0 15691 static int 15692 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15693 xmlSchemaTypePtr type) 15694 { 15695 /* 15696 * src-simple-type.1 The corresponding simple type definition, if any, 15697 * must satisfy the conditions set out in Constraints on Simple Type 15698 * Definition Schema Components (3.14.6). 15699 */ 15700 if (WXS_IS_RESTRICTION(type)) { 15701 /* 15702 * src-simple-type.2 "If the <restriction> alternative is chosen, 15703 * either it must have a base [attribute] or a <simpleType> among its 15704 * [children], but not both." 15705 * NOTE: This is checked in the parse function of <restriction>. 15706 */ 15707 /* 15708 * 15709 */ 15710 } else if (WXS_IS_LIST(type)) { 15711 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15712 * an itemType [attribute] or a <simpleType> among its [children], 15713 * but not both." 15714 * 15715 * NOTE: This is checked in the parse function of <list>. 15716 */ 15717 } else if (WXS_IS_UNION(type)) { 15718 /* 15719 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15720 */ 15721 } 15722 return (0); 15723 } 15724 #endif 15725 15726 static int 15727 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15728 { 15729 if (ctxt->vctxt == NULL) { 15730 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15731 if (ctxt->vctxt == NULL) { 15732 xmlSchemaPErr(ctxt, NULL, 15733 XML_SCHEMAP_INTERNAL, 15734 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15735 "failed to create a temp. validation context.\n", 15736 NULL, NULL); 15737 return (-1); 15738 } 15739 /* TODO: Pass user data. */ 15740 xmlSchemaSetValidErrors(ctxt->vctxt, 15741 ctxt->error, ctxt->warning, ctxt->errCtxt); 15742 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15743 ctxt->serror, ctxt->errCtxt); 15744 } 15745 return (0); 15746 } 15747 15748 static int 15749 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15750 xmlNodePtr node, 15751 xmlSchemaTypePtr type, 15752 const xmlChar *value, 15753 xmlSchemaValPtr *retVal, 15754 int fireErrors, 15755 int normalize, 15756 int isNormalized); 15757 15758 /** 15759 * xmlSchemaParseCheckCOSValidDefault: 15760 * @pctxt: the schema parser context 15761 * @type: the simple type definition 15762 * @value: the default value 15763 * @node: an optional node (the holder of the value) 15764 * 15765 * Schema Component Constraint: Element Default Valid (Immediate) 15766 * (cos-valid-default) 15767 * This will be used by the parser only. For the validator there's 15768 * an other version. 15769 * 15770 * Returns 0 if the constraints are satisfied, 15771 * if not, a positive error code and -1 on internal 15772 * errors. 15773 */ 15774 static int 15775 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15776 xmlNodePtr node, 15777 xmlSchemaTypePtr type, 15778 const xmlChar *value, 15779 xmlSchemaValPtr *val) 15780 { 15781 int ret = 0; 15782 15783 /* 15784 * cos-valid-default: 15785 * Schema Component Constraint: Element Default Valid (Immediate) 15786 * For a string to be a valid default with respect to a type 15787 * definition the appropriate case among the following must be true: 15788 */ 15789 if WXS_IS_COMPLEX(type) { 15790 /* 15791 * Complex type. 15792 * 15793 * SPEC (2.1) "its {content type} must be a simple type definition 15794 * or mixed." 15795 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15796 * type}'s particle must be emptiable as defined by 15797 * Particle Emptiable (3.9.6)." 15798 */ 15799 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15800 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15801 /* NOTE that this covers (2.2.2) as well. */ 15802 xmlSchemaPCustomErr(pctxt, 15803 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15804 WXS_BASIC_CAST type, type->node, 15805 "For a string to be a valid default, the type definition " 15806 "must be a simple type or a complex type with mixed content " 15807 "and a particle emptiable", NULL); 15808 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15809 } 15810 } 15811 /* 15812 * 1 If the type definition is a simple type definition, then the string 15813 * must be valid with respect to that definition as defined by String 15814 * Valid (3.14.4). 15815 * 15816 * AND 15817 * 15818 * 2.2.1 If the {content type} is a simple type definition, then the 15819 * string must be valid with respect to that simple type definition 15820 * as defined by String Valid (3.14.4). 15821 */ 15822 if (WXS_IS_SIMPLE(type)) 15823 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15824 type, value, val, 1, 1, 0); 15825 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15826 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15827 type->contentTypeDef, value, val, 1, 1, 0); 15828 else 15829 return (ret); 15830 15831 if (ret < 0) { 15832 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15833 "calling xmlSchemaVCheckCVCSimpleType()"); 15834 } 15835 15836 return (ret); 15837 } 15838 15839 /** 15840 * xmlSchemaCheckCTPropsCorrect: 15841 * @ctxt: the schema parser context 15842 * @type: the complex type definition 15843 * 15844 *.(4.6) Constraints on Complex Type Definition Schema Components 15845 * Schema Component Constraint: 15846 * Complex Type Definition Properties Correct (ct-props-correct) 15847 * STATUS: (seems) complete 15848 * 15849 * Returns 0 if the constraints are satisfied, a positive 15850 * error code if not and -1 if an internal error occured. 15851 */ 15852 static int 15853 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15854 xmlSchemaTypePtr type) 15855 { 15856 /* 15857 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15858 * 15859 * SPEC (1) "The values of the properties of a complex type definition must 15860 * be as described in the property tableau in The Complex Type Definition 15861 * Schema Component (3.4.1), modulo the impact of Missing 15862 * Sub-components (5.3)." 15863 */ 15864 if ((type->baseType != NULL) && 15865 (WXS_IS_SIMPLE(type->baseType)) && 15866 (WXS_IS_EXTENSION(type) == 0)) { 15867 /* 15868 * SPEC (2) "If the {base type definition} is a simple type definition, 15869 * the {derivation method} must be extension." 15870 */ 15871 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15872 XML_SCHEMAP_SRC_CT_1, 15873 NULL, WXS_BASIC_CAST type, 15874 "If the base type is a simple type, the derivation method must be " 15875 "'extension'", NULL, NULL); 15876 return (XML_SCHEMAP_SRC_CT_1); 15877 } 15878 /* 15879 * SPEC (3) "Circular definitions are disallowed, except for the ur-type 15880 * definition. That is, it must be possible to reach the ur-type 15881 * definition by repeatedly following the {base type definition}." 15882 * 15883 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15884 */ 15885 /* 15886 * NOTE that (4) and (5) need the following: 15887 * - attribute uses need to be already inherited (apply attr. prohibitions) 15888 * - attribute group references need to be expanded already 15889 * - simple types need to be typefixed already 15890 */ 15891 if (type->attrUses && 15892 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15893 { 15894 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15895 xmlSchemaAttributeUsePtr use, tmp; 15896 int i, j, hasId = 0; 15897 15898 for (i = uses->nbItems -1; i >= 0; i--) { 15899 use = uses->items[i]; 15900 15901 /* 15902 * SPEC ct-props-correct 15903 * (4) "Two distinct attribute declarations in the 15904 * {attribute uses} must not have identical {name}s and 15905 * {target namespace}s." 15906 */ 15907 if (i > 0) { 15908 for (j = i -1; j >= 0; j--) { 15909 tmp = uses->items[j]; 15910 if ((WXS_ATTRUSE_DECL_NAME(use) == 15911 WXS_ATTRUSE_DECL_NAME(tmp)) && 15912 (WXS_ATTRUSE_DECL_TNS(use) == 15913 WXS_ATTRUSE_DECL_TNS(tmp))) 15914 { 15915 xmlChar *str = NULL; 15916 15917 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15918 XML_SCHEMAP_AG_PROPS_CORRECT, 15919 NULL, WXS_BASIC_CAST type, 15920 "Duplicate %s", 15921 xmlSchemaGetComponentDesignation(&str, use), 15922 NULL); 15923 FREE_AND_NULL(str); 15924 /* 15925 * Remove the duplicate. 15926 */ 15927 if (xmlSchemaItemListRemove(uses, i) == -1) 15928 goto exit_failure; 15929 goto next_use; 15930 } 15931 } 15932 } 15933 /* 15934 * SPEC ct-props-correct 15935 * (5) "Two distinct attribute declarations in the 15936 * {attribute uses} must not have {type definition}s which 15937 * are or are derived from ID." 15938 */ 15939 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15940 if (xmlSchemaIsDerivedFromBuiltInType( 15941 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15942 { 15943 if (hasId) { 15944 xmlChar *str = NULL; 15945 15946 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15947 XML_SCHEMAP_AG_PROPS_CORRECT, 15948 NULL, WXS_BASIC_CAST type, 15949 "There must not exist more than one attribute " 15950 "declaration of type 'xs:ID' " 15951 "(or derived from 'xs:ID'). The %s violates this " 15952 "constraint", 15953 xmlSchemaGetComponentDesignation(&str, use), 15954 NULL); 15955 FREE_AND_NULL(str); 15956 if (xmlSchemaItemListRemove(uses, i) == -1) 15957 goto exit_failure; 15958 } 15959 15960 hasId = 1; 15961 } 15962 } 15963 next_use: {} 15964 } 15965 } 15966 return (0); 15967 exit_failure: 15968 return(-1); 15969 } 15970 15971 static int 15972 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 15973 xmlSchemaTypePtr typeB) 15974 { 15975 /* 15976 * TODO: This should implement component-identity 15977 * in the future. 15978 */ 15979 if ((typeA == NULL) || (typeB == NULL)) 15980 return (0); 15981 return (typeA == typeB); 15982 } 15983 15984 /** 15985 * xmlSchemaCheckCOSCTDerivedOK: 15986 * @ctxt: the schema parser context 15987 * @type: the to-be derived complex type definition 15988 * @baseType: the base complex type definition 15989 * @set: the given set 15990 * 15991 * Schema Component Constraint: 15992 * Type Derivation OK (Complex) (cos-ct-derived-ok) 15993 * 15994 * STATUS: completed 15995 * 15996 * Returns 0 if the constraints are satisfied, or 1 15997 * if not. 15998 */ 15999 static int 16000 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16001 xmlSchemaTypePtr type, 16002 xmlSchemaTypePtr baseType, 16003 int set) 16004 { 16005 int equal = xmlSchemaAreEqualTypes(type, baseType); 16006 /* TODO: Error codes. */ 16007 /* 16008 * SPEC "For a complex type definition (call it D, for derived) 16009 * to be validly derived from a type definition (call this 16010 * B, for base) given a subset of {extension, restriction} 16011 * all of the following must be true:" 16012 */ 16013 if (! equal) { 16014 /* 16015 * SPEC (1) "If B and D are not the same type definition, then the 16016 * {derivation method} of D must not be in the subset." 16017 */ 16018 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16019 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16020 return (1); 16021 } else { 16022 /* 16023 * SPEC (2.1) "B and D must be the same type definition." 16024 */ 16025 return (0); 16026 } 16027 /* 16028 * SPEC (2.2) "B must be D's {base type definition}." 16029 */ 16030 if (type->baseType == baseType) 16031 return (0); 16032 /* 16033 * SPEC (2.3.1) "D's {base type definition} must not be the ur-type 16034 * definition." 16035 */ 16036 if (WXS_IS_ANYTYPE(type->baseType)) 16037 return (1); 16038 16039 if (WXS_IS_COMPLEX(type->baseType)) { 16040 /* 16041 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16042 * must be validly derived from B given the subset as defined by this 16043 * constraint." 16044 */ 16045 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16046 baseType, set)); 16047 } else { 16048 /* 16049 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16050 * must be validly derived from B given the subset as defined in Type 16051 * Derivation OK (Simple) (3.14.6). 16052 */ 16053 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16054 baseType, set)); 16055 } 16056 } 16057 16058 /** 16059 * xmlSchemaCheckCOSDerivedOK: 16060 * @type: the derived simple type definition 16061 * @baseType: the base type definition 16062 * 16063 * Calls: 16064 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16065 * 16066 * Checks wheter @type can be validly derived from @baseType. 16067 * 16068 * Returns 0 on success, an positive error code otherwise. 16069 */ 16070 static int 16071 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16072 xmlSchemaTypePtr type, 16073 xmlSchemaTypePtr baseType, 16074 int set) 16075 { 16076 if (WXS_IS_SIMPLE(type)) 16077 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16078 else 16079 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16080 } 16081 16082 /** 16083 * xmlSchemaCheckCOSCTExtends: 16084 * @ctxt: the schema parser context 16085 * @type: the complex type definition 16086 * 16087 * (3.4.6) Constraints on Complex Type Definition Schema Components 16088 * Schema Component Constraint: 16089 * Derivation Valid (Extension) (cos-ct-extends) 16090 * 16091 * STATUS: 16092 * missing: 16093 * (1.5) 16094 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16095 * 16096 * Returns 0 if the constraints are satisfied, a positive 16097 * error code if not and -1 if an internal error occured. 16098 */ 16099 static int 16100 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16101 xmlSchemaTypePtr type) 16102 { 16103 xmlSchemaTypePtr base = type->baseType; 16104 /* 16105 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16106 * temporarily only. 16107 */ 16108 /* 16109 * SPEC (1) "If the {base type definition} is a complex type definition, 16110 * then all of the following must be true:" 16111 */ 16112 if (WXS_IS_COMPLEX(base)) { 16113 /* 16114 * SPEC (1.1) "The {final} of the {base type definition} must not 16115 * contain extension." 16116 */ 16117 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16118 xmlSchemaPCustomErr(ctxt, 16119 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16120 WXS_BASIC_CAST type, NULL, 16121 "The 'final' of the base type definition " 16122 "contains 'extension'", NULL); 16123 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16124 } 16125 16126 /* 16127 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16128 * since they are automatically satisfied through the 16129 * inheriting mechanism. 16130 * Note that even if redefining components, the inheriting mechanism 16131 * is used. 16132 */ 16133 #if 0 16134 /* 16135 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16136 * uses} 16137 * of the complex type definition itself, that is, for every attribute 16138 * use in the {attribute uses} of the {base type definition}, there 16139 * must be an attribute use in the {attribute uses} of the complex 16140 * type definition itself whose {attribute declaration} has the same 16141 * {name}, {target namespace} and {type definition} as its attribute 16142 * declaration" 16143 */ 16144 if (base->attrUses != NULL) { 16145 int i, j, found; 16146 xmlSchemaAttributeUsePtr use, buse; 16147 16148 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16149 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16150 found = 0; 16151 if (type->attrUses != NULL) { 16152 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16153 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16154 { 16155 if ((WXS_ATTRUSE_DECL_NAME(use) == 16156 WXS_ATTRUSE_DECL_NAME(buse)) && 16157 (WXS_ATTRUSE_DECL_TNS(use) == 16158 WXS_ATTRUSE_DECL_TNS(buse)) && 16159 (WXS_ATTRUSE_TYPEDEF(use) == 16160 WXS_ATTRUSE_TYPEDEF(buse)) 16161 { 16162 found = 1; 16163 break; 16164 } 16165 } 16166 } 16167 if (! found) { 16168 xmlChar *str = NULL; 16169 16170 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16171 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16172 NULL, WXS_BASIC_CAST type, 16173 /* 16174 * TODO: The report does not indicate that also the 16175 * type needs to be the same. 16176 */ 16177 "This type is missing a matching correspondent " 16178 "for its {base type}'s %s in its {attribute uses}", 16179 xmlSchemaGetComponentDesignation(&str, 16180 buse->children), 16181 NULL); 16182 FREE_AND_NULL(str) 16183 } 16184 } 16185 } 16186 /* 16187 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16188 * definition must also have one, and the base type definition's 16189 * {attribute wildcard}'s {namespace constraint} must be a subset 16190 * of the complex type definition's {attribute wildcard}'s {namespace 16191 * constraint}, as defined by Wildcard Subset (3.10.6)." 16192 */ 16193 16194 /* 16195 * MAYBE TODO: Enable if ever needed. But this will be needed only 16196 * if created the type via a schema construction API. 16197 */ 16198 if (base->attributeWildcard != NULL) { 16199 if (type->attributeWilcard == NULL) { 16200 xmlChar *str = NULL; 16201 16202 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16203 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16204 NULL, type, 16205 "The base %s has an attribute wildcard, " 16206 "but this type is missing an attribute wildcard", 16207 xmlSchemaGetComponentDesignation(&str, base)); 16208 FREE_AND_NULL(str) 16209 16210 } else if (xmlSchemaCheckCOSNSSubset( 16211 base->attributeWildcard, type->attributeWildcard)) 16212 { 16213 xmlChar *str = NULL; 16214 16215 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16216 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16217 NULL, type, 16218 "The attribute wildcard is not a valid " 16219 "superset of the one in the base %s", 16220 xmlSchemaGetComponentDesignation(&str, base)); 16221 FREE_AND_NULL(str) 16222 } 16223 } 16224 #endif 16225 /* 16226 * SPEC (1.4) "One of the following must be true:" 16227 */ 16228 if ((type->contentTypeDef != NULL) && 16229 (type->contentTypeDef == base->contentTypeDef)) { 16230 /* 16231 * SPEC (1.4.1) "The {content type} of the {base type definition} 16232 * and the {content type} of the complex type definition itself 16233 * must be the same simple type definition" 16234 * PASS 16235 */ 16236 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16237 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16238 /* 16239 * SPEC (1.4.2) "The {content type} of both the {base type 16240 * definition} and the complex type definition itself must 16241 * be empty." 16242 * PASS 16243 */ 16244 } else { 16245 /* 16246 * SPEC (1.4.3) "All of the following must be true:" 16247 */ 16248 if (type->subtypes == NULL) { 16249 /* 16250 * SPEC 1.4.3.1 The {content type} of the complex type 16251 * definition itself must specify a particle. 16252 */ 16253 xmlSchemaPCustomErr(ctxt, 16254 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16255 WXS_BASIC_CAST type, NULL, 16256 "The content type must specify a particle", NULL); 16257 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16258 } 16259 /* 16260 * SPEC (1.4.3.2) "One of the following must be true:" 16261 */ 16262 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16263 /* 16264 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16265 * definition} must be empty. 16266 * PASS 16267 */ 16268 } else { 16269 /* 16270 * SPEC (1.4.3.2.2) "All of the following must be true:" 16271 */ 16272 if ((type->contentType != base->contentType) || 16273 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16274 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16275 /* 16276 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16277 * or both must be element-only." 16278 */ 16279 xmlSchemaPCustomErr(ctxt, 16280 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16281 WXS_BASIC_CAST type, NULL, 16282 "The content type of both, the type and its base " 16283 "type, must either 'mixed' or 'element-only'", NULL); 16284 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16285 } 16286 /* 16287 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16288 * complex type definition must be a valid extension 16289 * of the {base type definition}'s particle, as defined 16290 * in Particle Valid (Extension) (3.9.6)." 16291 * 16292 * NOTE that we won't check "Particle Valid (Extension)", 16293 * since it is ensured by the derivation process in 16294 * xmlSchemaTypeFixup(). We need to implement this when heading 16295 * for a construction API 16296 * TODO: !! This is needed to be checked if redefining a type !! 16297 */ 16298 } 16299 /* 16300 * URGENT TODO (1.5) 16301 */ 16302 } 16303 } else { 16304 /* 16305 * SPEC (2) "If the {base type definition} is a simple type definition, 16306 * then all of the following must be true:" 16307 */ 16308 if (type->contentTypeDef != base) { 16309 /* 16310 * SPEC (2.1) "The {content type} must be the same simple type 16311 * definition." 16312 */ 16313 xmlSchemaPCustomErr(ctxt, 16314 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16315 WXS_BASIC_CAST type, NULL, 16316 "The content type must be the simple base type", NULL); 16317 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16318 } 16319 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16320 /* 16321 * SPEC (2.2) "The {final} of the {base type definition} must not 16322 * contain extension" 16323 * NOTE that this is the same as (1.1). 16324 */ 16325 xmlSchemaPCustomErr(ctxt, 16326 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16327 WXS_BASIC_CAST type, NULL, 16328 "The 'final' of the base type definition " 16329 "contains 'extension'", NULL); 16330 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16331 } 16332 } 16333 return (0); 16334 } 16335 16336 /** 16337 * xmlSchemaCheckDerivationOKRestriction: 16338 * @ctxt: the schema parser context 16339 * @type: the complex type definition 16340 * 16341 * (3.4.6) Constraints on Complex Type Definition Schema Components 16342 * Schema Component Constraint: 16343 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16344 * 16345 * STATUS: 16346 * missing: 16347 * (5.4.2) ??? 16348 * 16349 * ATTENTION: 16350 * In XML Schema 1.1 this will be: 16351 * Validation Rule: Checking complex type subsumption 16352 * 16353 * Returns 0 if the constraints are satisfied, a positive 16354 * error code if not and -1 if an internal error occured. 16355 */ 16356 static int 16357 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16358 xmlSchemaTypePtr type) 16359 { 16360 xmlSchemaTypePtr base; 16361 16362 /* 16363 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16364 * temporarily only. 16365 */ 16366 base = type->baseType; 16367 if (! WXS_IS_COMPLEX(base)) { 16368 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16369 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16370 type->node, WXS_BASIC_CAST type, 16371 "The base type must be a complex type", NULL, NULL); 16372 return(ctxt->err); 16373 } 16374 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16375 /* 16376 * SPEC (1) "The {base type definition} must be a complex type 16377 * definition whose {final} does not contain restriction." 16378 */ 16379 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16380 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16381 type->node, WXS_BASIC_CAST type, 16382 "The 'final' of the base type definition " 16383 "contains 'restriction'", NULL, NULL); 16384 return (ctxt->err); 16385 } 16386 /* 16387 * SPEC (2), (3) and (4) 16388 * Those are handled in a separate function, since the 16389 * same constraints are needed for redefinition of 16390 * attribute groups as well. 16391 */ 16392 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16393 XML_SCHEMA_ACTION_DERIVE, 16394 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16395 type->attrUses, base->attrUses, 16396 type->attributeWildcard, 16397 base->attributeWildcard) == -1) 16398 { 16399 return(-1); 16400 } 16401 /* 16402 * SPEC (5) "One of the following must be true:" 16403 */ 16404 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16405 /* 16406 * SPEC (5.1) "The {base type definition} must be the 16407 * ur-type definition." 16408 * PASS 16409 */ 16410 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16411 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16412 /* 16413 * SPEC (5.2.1) "The {content type} of the complex type definition 16414 * must be a simple type definition" 16415 * 16416 * SPEC (5.2.2) "One of the following must be true:" 16417 */ 16418 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16419 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16420 { 16421 int err; 16422 /* 16423 * SPEC (5.2.2.1) "The {content type} of the {base type 16424 * definition} must be a simple type definition from which 16425 * the {content type} is validly derived given the empty 16426 * set as defined in Type Derivation OK (Simple) (3.14.6)." 16427 * 16428 * ATTENTION TODO: This seems not needed if the type implicitely 16429 * derived from the base type. 16430 * 16431 */ 16432 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16433 type->contentTypeDef, base->contentTypeDef, 0); 16434 if (err != 0) { 16435 xmlChar *strA = NULL, *strB = NULL; 16436 16437 if (err == -1) 16438 return(-1); 16439 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16440 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16441 NULL, WXS_BASIC_CAST type, 16442 "The {content type} %s is not validly derived from the " 16443 "base type's {content type} %s", 16444 xmlSchemaGetComponentDesignation(&strA, 16445 type->contentTypeDef), 16446 xmlSchemaGetComponentDesignation(&strB, 16447 base->contentTypeDef)); 16448 FREE_AND_NULL(strA); 16449 FREE_AND_NULL(strB); 16450 return(ctxt->err); 16451 } 16452 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16453 (xmlSchemaIsParticleEmptiable( 16454 (xmlSchemaParticlePtr) base->subtypes))) { 16455 /* 16456 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16457 * and have a particle which is emptiable as defined in 16458 * Particle Emptiable (3.9.6)." 16459 * PASS 16460 */ 16461 } else { 16462 xmlSchemaPCustomErr(ctxt, 16463 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16464 WXS_BASIC_CAST type, NULL, 16465 "The content type of the base type must be either " 16466 "a simple type or 'mixed' and an emptiable particle", NULL); 16467 return (ctxt->err); 16468 } 16469 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16470 /* 16471 * SPEC (5.3.1) "The {content type} of the complex type itself must 16472 * be empty" 16473 */ 16474 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16475 /* 16476 * SPEC (5.3.2.1) "The {content type} of the {base type 16477 * definition} must also be empty." 16478 * PASS 16479 */ 16480 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16481 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16482 xmlSchemaIsParticleEmptiable( 16483 (xmlSchemaParticlePtr) base->subtypes)) { 16484 /* 16485 * SPEC (5.3.2.2) "The {content type} of the {base type 16486 * definition} must be elementOnly or mixed and have a particle 16487 * which is emptiable as defined in Particle Emptiable (3.9.6)." 16488 * PASS 16489 */ 16490 } else { 16491 xmlSchemaPCustomErr(ctxt, 16492 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16493 WXS_BASIC_CAST type, NULL, 16494 "The content type of the base type must be either " 16495 "empty or 'mixed' (or 'elements-only') and an emptiable " 16496 "particle", NULL); 16497 return (ctxt->err); 16498 } 16499 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16500 WXS_HAS_MIXED_CONTENT(type)) { 16501 /* 16502 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16503 * itself must be element-only" 16504 */ 16505 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16506 /* 16507 * SPEC (5.4.1.2) "The {content type} of the complex type 16508 * definition itself and of the {base type definition} must be 16509 * mixed" 16510 */ 16511 xmlSchemaPCustomErr(ctxt, 16512 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16513 WXS_BASIC_CAST type, NULL, 16514 "If the content type is 'mixed', then the content type of the " 16515 "base type must also be 'mixed'", NULL); 16516 return (ctxt->err); 16517 } 16518 /* 16519 * SPEC (5.4.2) "The particle of the complex type definition itself 16520 * must be a valid restriction of the particle of the {content 16521 * type} of the {base type definition} as defined in Particle Valid 16522 * (Restriction) (3.9.6). 16523 * 16524 * URGENT TODO: (5.4.2) 16525 */ 16526 } else { 16527 xmlSchemaPCustomErr(ctxt, 16528 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16529 WXS_BASIC_CAST type, NULL, 16530 "The type is not a valid restriction of its base type", NULL); 16531 return (ctxt->err); 16532 } 16533 return (0); 16534 } 16535 16536 /** 16537 * xmlSchemaCheckCTComponent: 16538 * @ctxt: the schema parser context 16539 * @type: the complex type definition 16540 * 16541 * (3.4.6) Constraints on Complex Type Definition Schema Components 16542 * 16543 * Returns 0 if the constraints are satisfied, a positive 16544 * error code if not and -1 if an internal error occured. 16545 */ 16546 static int 16547 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16548 xmlSchemaTypePtr type) 16549 { 16550 int ret; 16551 /* 16552 * Complex Type Definition Properties Correct 16553 */ 16554 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16555 if (ret != 0) 16556 return (ret); 16557 if (WXS_IS_EXTENSION(type)) 16558 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16559 else 16560 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16561 return (ret); 16562 } 16563 16564 /** 16565 * xmlSchemaCheckSRCCT: 16566 * @ctxt: the schema parser context 16567 * @type: the complex type definition 16568 * 16569 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16570 * Schema Representation Constraint: 16571 * Complex Type Definition Representation OK (src-ct) 16572 * 16573 * Returns 0 if the constraints are satisfied, a positive 16574 * error code if not and -1 if an internal error occured. 16575 */ 16576 static int 16577 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16578 xmlSchemaTypePtr type) 16579 { 16580 xmlSchemaTypePtr base; 16581 int ret = 0; 16582 16583 /* 16584 * TODO: Adjust the error codes here, as I used 16585 * XML_SCHEMAP_SRC_CT_1 only yet. 16586 */ 16587 base = type->baseType; 16588 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16589 /* 16590 * 1 If the <complexContent> alternative is chosen, the type definition 16591 * resolved to by the actual value of the base [attribute] 16592 * must be a complex type definition; 16593 */ 16594 if (! WXS_IS_COMPLEX(base)) { 16595 xmlChar *str = NULL; 16596 xmlSchemaPCustomErr(ctxt, 16597 XML_SCHEMAP_SRC_CT_1, 16598 WXS_BASIC_CAST type, type->node, 16599 "If using <complexContent>, the base type is expected to be " 16600 "a complex type. The base type '%s' is a simple type", 16601 xmlSchemaFormatQName(&str, base->targetNamespace, 16602 base->name)); 16603 FREE_AND_NULL(str) 16604 return (XML_SCHEMAP_SRC_CT_1); 16605 } 16606 } else { 16607 /* 16608 * SPEC 16609 * 2 If the <simpleContent> alternative is chosen, all of the 16610 * following must be true: 16611 * 2.1 The type definition resolved to by the actual value of the 16612 * base [attribute] must be one of the following: 16613 */ 16614 if (WXS_IS_SIMPLE(base)) { 16615 if (WXS_IS_EXTENSION(type) == 0) { 16616 xmlChar *str = NULL; 16617 /* 16618 * 2.1.3 only if the <extension> alternative is also 16619 * chosen, a simple type definition. 16620 */ 16621 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16622 xmlSchemaPCustomErr(ctxt, 16623 XML_SCHEMAP_SRC_CT_1, 16624 WXS_BASIC_CAST type, NULL, 16625 "If using <simpleContent> and <restriction>, the base " 16626 "type must be a complex type. The base type '%s' is " 16627 "a simple type", 16628 xmlSchemaFormatQName(&str, base->targetNamespace, 16629 base->name)); 16630 FREE_AND_NULL(str) 16631 return (XML_SCHEMAP_SRC_CT_1); 16632 } 16633 } else { 16634 /* Base type is a complex type. */ 16635 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16636 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16637 /* 16638 * 2.1.1 a complex type definition whose {content type} is a 16639 * simple type definition; 16640 * PASS 16641 */ 16642 if (base->contentTypeDef == NULL) { 16643 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16644 WXS_BASIC_CAST type, NULL, 16645 "Internal error: xmlSchemaCheckSRCCT, " 16646 "'%s', base type has no content type", 16647 type->name); 16648 return (-1); 16649 } 16650 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16651 (WXS_IS_RESTRICTION(type))) { 16652 16653 /* 16654 * 2.1.2 only if the <restriction> alternative is also 16655 * chosen, a complex type definition whose {content type} 16656 * is mixed and a particle emptiable. 16657 */ 16658 if (! xmlSchemaIsParticleEmptiable( 16659 (xmlSchemaParticlePtr) base->subtypes)) { 16660 ret = XML_SCHEMAP_SRC_CT_1; 16661 } else 16662 /* 16663 * Attention: at this point the <simpleType> child is in 16664 * ->contentTypeDef (put there during parsing). 16665 */ 16666 if (type->contentTypeDef == NULL) { 16667 xmlChar *str = NULL; 16668 /* 16669 * 2.2 If clause 2.1.2 above is satisfied, then there 16670 * must be a <simpleType> among the [children] of 16671 * <restriction>. 16672 */ 16673 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16674 xmlSchemaPCustomErr(ctxt, 16675 XML_SCHEMAP_SRC_CT_1, 16676 WXS_BASIC_CAST type, NULL, 16677 "A <simpleType> is expected among the children " 16678 "of <restriction>, if <simpleContent> is used and " 16679 "the base type '%s' is a complex type", 16680 xmlSchemaFormatQName(&str, base->targetNamespace, 16681 base->name)); 16682 FREE_AND_NULL(str) 16683 return (XML_SCHEMAP_SRC_CT_1); 16684 } 16685 } else { 16686 ret = XML_SCHEMAP_SRC_CT_1; 16687 } 16688 } 16689 if (ret > 0) { 16690 xmlChar *str = NULL; 16691 if (WXS_IS_RESTRICTION(type)) { 16692 xmlSchemaPCustomErr(ctxt, 16693 XML_SCHEMAP_SRC_CT_1, 16694 WXS_BASIC_CAST type, NULL, 16695 "If <simpleContent> and <restriction> is used, the " 16696 "base type must be a simple type or a complex type with " 16697 "mixed content and particle emptiable. The base type " 16698 "'%s' is none of those", 16699 xmlSchemaFormatQName(&str, base->targetNamespace, 16700 base->name)); 16701 } else { 16702 xmlSchemaPCustomErr(ctxt, 16703 XML_SCHEMAP_SRC_CT_1, 16704 WXS_BASIC_CAST type, NULL, 16705 "If <simpleContent> and <extension> is used, the " 16706 "base type must be a simple type. The base type '%s' " 16707 "is a complex type", 16708 xmlSchemaFormatQName(&str, base->targetNamespace, 16709 base->name)); 16710 } 16711 FREE_AND_NULL(str) 16712 } 16713 } 16714 /* 16715 * SPEC (3) "The corresponding complex type definition component must 16716 * satisfy the conditions set out in Constraints on Complex Type 16717 * Definition Schema Components (3.4.6);" 16718 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16719 */ 16720 /* 16721 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16722 * above for {attribute wildcard} is satisfied, the intensional 16723 * intersection must be expressible, as defined in Attribute Wildcard 16724 * Intersection (3.10.6). 16725 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16726 */ 16727 return (ret); 16728 } 16729 16730 #ifdef ENABLE_PARTICLE_RESTRICTION 16731 /** 16732 * xmlSchemaCheckParticleRangeOK: 16733 * @ctxt: the schema parser context 16734 * @type: the complex type definition 16735 * 16736 * (3.9.6) Constraints on Particle Schema Components 16737 * Schema Component Constraint: 16738 * Occurrence Range OK (range-ok) 16739 * 16740 * STATUS: complete 16741 * 16742 * Returns 0 if the constraints are satisfied, a positive 16743 * error code if not and -1 if an internal error occured. 16744 */ 16745 static int 16746 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16747 int bmin, int bmax) 16748 { 16749 if (rmin < bmin) 16750 return (1); 16751 if ((bmax != UNBOUNDED) && 16752 (rmax > bmax)) 16753 return (1); 16754 return (0); 16755 } 16756 16757 /** 16758 * xmlSchemaCheckRCaseNameAndTypeOK: 16759 * @ctxt: the schema parser context 16760 * @r: the restricting element declaration particle 16761 * @b: the base element declaration particle 16762 * 16763 * (3.9.6) Constraints on Particle Schema Components 16764 * Schema Component Constraint: 16765 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16766 * (rcase-NameAndTypeOK) 16767 * 16768 * STATUS: 16769 * MISSING (3.2.3) 16770 * CLARIFY: (3.2.2) 16771 * 16772 * Returns 0 if the constraints are satisfied, a positive 16773 * error code if not and -1 if an internal error occured. 16774 */ 16775 static int 16776 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16777 xmlSchemaParticlePtr r, 16778 xmlSchemaParticlePtr b) 16779 { 16780 xmlSchemaElementPtr elemR, elemB; 16781 16782 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16783 elemR = (xmlSchemaElementPtr) r->children; 16784 elemB = (xmlSchemaElementPtr) b->children; 16785 /* 16786 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16787 * the same." 16788 */ 16789 if ((elemR != elemB) && 16790 ((! xmlStrEqual(elemR->name, elemB->name)) || 16791 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16792 return (1); 16793 /* 16794 * SPEC (2) "R's occurrence range is a valid restriction of B's 16795 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16796 */ 16797 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16798 b->minOccurs, b->maxOccurs) != 0) 16799 return (1); 16800 /* 16801 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16802 * {scope} are global." 16803 */ 16804 if (elemR == elemB) 16805 return (0); 16806 /* 16807 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16808 */ 16809 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16810 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16811 return (1); 16812 /* 16813 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16814 * or is not fixed, or R's declaration's {value constraint} is fixed 16815 * with the same value." 16816 */ 16817 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16818 ((elemR->value == NULL) || 16819 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16820 /* TODO: Equality of the initial value or normalized or canonical? */ 16821 (! xmlStrEqual(elemR->value, elemB->value)))) 16822 return (1); 16823 /* 16824 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16825 * definitions} is a subset of B's declaration's {identity-constraint 16826 * definitions}, if any." 16827 */ 16828 if (elemB->idcs != NULL) { 16829 /* TODO */ 16830 } 16831 /* 16832 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16833 * superset of B's declaration's {disallowed substitutions}." 16834 */ 16835 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16836 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16837 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16838 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16839 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16840 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16841 return (1); 16842 /* 16843 * SPEC (3.2.5) "R's {type definition} is validly derived given 16844 * {extension, list, union} from B's {type definition}" 16845 * 16846 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16847 * set, if the corresponding constraints handle "restriction" and 16848 * "extension" only? 16849 * 16850 */ 16851 { 16852 int set = 0; 16853 16854 set |= SUBSET_EXTENSION; 16855 set |= SUBSET_LIST; 16856 set |= SUBSET_UNION; 16857 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16858 elemB->subtypes, set) != 0) 16859 return (1); 16860 } 16861 return (0); 16862 } 16863 16864 /** 16865 * xmlSchemaCheckRCaseNSCompat: 16866 * @ctxt: the schema parser context 16867 * @r: the restricting element declaration particle 16868 * @b: the base wildcard particle 16869 * 16870 * (3.9.6) Constraints on Particle Schema Components 16871 * Schema Component Constraint: 16872 * Particle Derivation OK (Elt:Any -- NSCompat) 16873 * (rcase-NSCompat) 16874 * 16875 * STATUS: complete 16876 * 16877 * Returns 0 if the constraints are satisfied, a positive 16878 * error code if not and -1 if an internal error occured. 16879 */ 16880 static int 16881 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16882 xmlSchemaParticlePtr r, 16883 xmlSchemaParticlePtr b) 16884 { 16885 /* TODO:Error codes (rcase-NSCompat). */ 16886 /* 16887 * SPEC "For an element declaration particle to be a valid restriction 16888 * of a wildcard particle all of the following must be true:" 16889 * 16890 * SPEC (1) "The element declaration's {target namespace} is valid 16891 * with respect to the wildcard's {namespace constraint} as defined by 16892 * Wildcard allows Namespace Name (3.10.4)." 16893 */ 16894 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16895 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16896 return (1); 16897 /* 16898 * SPEC (2) "R's occurrence range is a valid restriction of B's 16899 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16900 */ 16901 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16902 b->minOccurs, b->maxOccurs) != 0) 16903 return (1); 16904 16905 return (0); 16906 } 16907 16908 /** 16909 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16910 * @ctxt: the schema parser context 16911 * @r: the restricting element declaration particle 16912 * @b: the base model group particle 16913 * 16914 * (3.9.6) Constraints on Particle Schema Components 16915 * Schema Component Constraint: 16916 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16917 * (rcase-RecurseAsIfGroup) 16918 * 16919 * STATUS: TODO 16920 * 16921 * Returns 0 if the constraints are satisfied, a positive 16922 * error code if not and -1 if an internal error occured. 16923 */ 16924 static int 16925 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16926 xmlSchemaParticlePtr r, 16927 xmlSchemaParticlePtr b) 16928 { 16929 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16930 TODO 16931 return (0); 16932 } 16933 16934 /** 16935 * xmlSchemaCheckRCaseNSSubset: 16936 * @ctxt: the schema parser context 16937 * @r: the restricting wildcard particle 16938 * @b: the base wildcard particle 16939 * 16940 * (3.9.6) Constraints on Particle Schema Components 16941 * Schema Component Constraint: 16942 * Particle Derivation OK (Any:Any -- NSSubset) 16943 * (rcase-NSSubset) 16944 * 16945 * STATUS: complete 16946 * 16947 * Returns 0 if the constraints are satisfied, a positive 16948 * error code if not and -1 if an internal error occured. 16949 */ 16950 static int 16951 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16952 xmlSchemaParticlePtr r, 16953 xmlSchemaParticlePtr b, 16954 int isAnyTypeBase) 16955 { 16956 /* TODO: Error codes (rcase-NSSubset). */ 16957 /* 16958 * SPEC (1) "R's occurrence range is a valid restriction of B's 16959 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16960 */ 16961 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16962 b->minOccurs, b->maxOccurs)) 16963 return (1); 16964 /* 16965 * SPEC (2) "R's {namespace constraint} must be an intensional subset 16966 * of B's {namespace constraint} as defined by Wildcard Subset (3.10.6)." 16967 */ 16968 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 16969 (xmlSchemaWildcardPtr) b->children)) 16970 return (1); 16971 /* 16972 * SPEC (3) "Unless B is the content model wildcard of the ur-type 16973 * definition, R's {process contents} must be identical to or stronger 16974 * than B's {process contents}, where strict is stronger than lax is 16975 * stronger than skip." 16976 */ 16977 if (! isAnyTypeBase) { 16978 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 16979 ((xmlSchemaWildcardPtr) b->children)->processContents) 16980 return (1); 16981 } 16982 16983 return (0); 16984 } 16985 16986 /** 16987 * xmlSchemaCheckCOSParticleRestrict: 16988 * @ctxt: the schema parser context 16989 * @type: the complex type definition 16990 * 16991 * (3.9.6) Constraints on Particle Schema Components 16992 * Schema Component Constraint: 16993 * Particle Valid (Restriction) (cos-particle-restrict) 16994 * 16995 * STATUS: TODO 16996 * 16997 * Returns 0 if the constraints are satisfied, a positive 16998 * error code if not and -1 if an internal error occured. 16999 */ 17000 static int 17001 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17002 xmlSchemaParticlePtr r, 17003 xmlSchemaParticlePtr b) 17004 { 17005 int ret = 0; 17006 17007 /*part = WXS_TYPE_PARTICLE(type); 17008 basePart = WXS_TYPE_PARTICLE(base); 17009 */ 17010 17011 TODO 17012 17013 /* 17014 * SPEC (1) "They are the same particle." 17015 */ 17016 if (r == b) 17017 return (0); 17018 17019 17020 return (0); 17021 } 17022 17023 #if 0 17024 /** 17025 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17026 * @ctxt: the schema parser context 17027 * @r: the model group particle 17028 * @b: the base wildcard particle 17029 * 17030 * (3.9.6) Constraints on Particle Schema Components 17031 * Schema Component Constraint: 17032 * Particle Derivation OK (All/Choice/Sequence:Any -- 17033 * NSRecurseCheckCardinality) 17034 * (rcase-NSRecurseCheckCardinality) 17035 * 17036 * STATUS: TODO: subst-groups 17037 * 17038 * Returns 0 if the constraints are satisfied, a positive 17039 * error code if not and -1 if an internal error occured. 17040 */ 17041 static int 17042 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17043 xmlSchemaParticlePtr r, 17044 xmlSchemaParticlePtr b) 17045 { 17046 xmlSchemaParticlePtr part; 17047 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17048 if ((r->children == NULL) || (r->children->children == NULL)) 17049 return (-1); 17050 /* 17051 * SPEC "For a group particle to be a valid restriction of a 17052 * wildcard particle..." 17053 * 17054 * SPEC (1) "Every member of the {particles} of the group is a valid 17055 * restriction of the wildcard as defined by 17056 * Particle Valid (Restriction) (3.9.6)." 17057 */ 17058 part = (xmlSchemaParticlePtr) r->children->children; 17059 do { 17060 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17061 return (1); 17062 part = (xmlSchemaParticlePtr) part->next; 17063 } while (part != NULL); 17064 /* 17065 * SPEC (2) "The effective total range of the group [...] is a 17066 * valid restriction of B's occurrence range as defined by 17067 * Occurrence Range OK (3.9.6)." 17068 */ 17069 if (xmlSchemaCheckParticleRangeOK( 17070 xmlSchemaGetParticleTotalRangeMin(r), 17071 xmlSchemaGetParticleTotalRangeMax(r), 17072 b->minOccurs, b->maxOccurs) != 0) 17073 return (1); 17074 return (0); 17075 } 17076 #endif 17077 17078 /** 17079 * xmlSchemaCheckRCaseRecurse: 17080 * @ctxt: the schema parser context 17081 * @r: the <all> or <sequence> model group particle 17082 * @b: the base <all> or <sequence> model group particle 17083 * 17084 * (3.9.6) Constraints on Particle Schema Components 17085 * Schema Component Constraint: 17086 * Particle Derivation OK (All:All,Sequence:Sequence -- 17087 Recurse) 17088 * (rcase-Recurse) 17089 * 17090 * STATUS: ? 17091 * TODO: subst-groups 17092 * 17093 * Returns 0 if the constraints are satisfied, a positive 17094 * error code if not and -1 if an internal error occured. 17095 */ 17096 static int 17097 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17098 xmlSchemaParticlePtr r, 17099 xmlSchemaParticlePtr b) 17100 { 17101 /* xmlSchemaParticlePtr part; */ 17102 /* TODO: Error codes (rcase-Recurse). */ 17103 if ((r->children == NULL) || (b->children == NULL) || 17104 (r->children->type != b->children->type)) 17105 return (-1); 17106 /* 17107 * SPEC "For an all or sequence group particle to be a valid 17108 * restriction of another group particle with the same {compositor}..." 17109 * 17110 * SPEC (1) "R's occurrence range is a valid restriction of B's 17111 * occurrence range as defined by Occurrence Range OK (3.9.6)." 17112 */ 17113 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17114 b->minOccurs, b->maxOccurs)) 17115 return (1); 17116 17117 17118 return (0); 17119 } 17120 17121 #endif 17122 17123 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17124 xmlSchemaPCustomErrExt(pctxt, \ 17125 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17126 WXS_BASIC_CAST fac1, fac1->node, \ 17127 "It is an error for both '%s' and '%s' to be specified on the "\ 17128 "same type definition", \ 17129 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17130 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17131 17132 #define FACET_RESTR_ERR(fac1, msg) \ 17133 xmlSchemaPCustomErr(pctxt, \ 17134 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17135 WXS_BASIC_CAST fac1, fac1->node, \ 17136 msg, NULL); 17137 17138 #define FACET_RESTR_FIXED_ERR(fac) \ 17139 xmlSchemaPCustomErr(pctxt, \ 17140 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17141 WXS_BASIC_CAST fac, fac->node, \ 17142 "The base type's facet is 'fixed', thus the value must not " \ 17143 "differ", NULL); 17144 17145 static void 17146 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17147 xmlSchemaFacetPtr facet1, 17148 xmlSchemaFacetPtr facet2, 17149 int lessGreater, 17150 int orEqual, 17151 int ofBase) 17152 { 17153 xmlChar *msg = NULL; 17154 17155 msg = xmlStrdup(BAD_CAST "'"); 17156 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17157 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17158 if (lessGreater == 0) 17159 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17160 if (lessGreater == 1) 17161 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17162 else 17163 msg = xmlStrcat(msg, BAD_CAST " less than"); 17164 17165 if (orEqual) 17166 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17167 msg = xmlStrcat(msg, BAD_CAST " '"); 17168 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17169 if (ofBase) 17170 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17171 else 17172 msg = xmlStrcat(msg, BAD_CAST "'"); 17173 17174 xmlSchemaPCustomErr(pctxt, 17175 XML_SCHEMAP_INVALID_FACET_VALUE, 17176 WXS_BASIC_CAST facet1, NULL, 17177 (const char *) msg, NULL); 17178 17179 if (msg != NULL) 17180 xmlFree(msg); 17181 } 17182 17183 /* 17184 * xmlSchemaDeriveAndValidateFacets: 17185 * 17186 * Schema Component Constraint: Simple Type Restriction (Facets) 17187 * (st-restrict-facets) 17188 */ 17189 static int 17190 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17191 xmlSchemaTypePtr type) 17192 { 17193 xmlSchemaTypePtr base = type->baseType; 17194 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17195 xmlSchemaFacetPtr facet, bfacet, 17196 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17197 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17198 fmininc = NULL, fmaxinc = NULL, 17199 fminexc = NULL, fmaxexc = NULL, 17200 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17201 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17202 bfmininc = NULL, bfmaxinc = NULL, 17203 bfminexc = NULL, bfmaxexc = NULL; 17204 int res; /* err = 0, fixedErr; */ 17205 17206 /* 17207 * SPEC st-restrict-facets 1: 17208 * "The {variety} of R is the same as that of B." 17209 */ 17210 /* 17211 * SPEC st-restrict-facets 2: 17212 * "If {variety} is atomic, the {primitive type definition} 17213 * of R is the same as that of B." 17214 * 17215 * NOTE: we leave 1 & 2 out for now, since this will be 17216 * satisfied by the derivation process. 17217 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17218 */ 17219 /* 17220 * SPEC st-restrict-facets 3: 17221 * "The {facets} of R are the union of S and the {facets} 17222 * of B, eliminating duplicates. To eliminate duplicates, 17223 * when a facet of the same kind occurs in both S and the 17224 * {facets} of B, the one in the {facets} of B is not 17225 * included, with the exception of enumeration and pattern 17226 * facets, for which multiple occurrences with distinct values 17227 * are allowed." 17228 */ 17229 17230 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17231 return (0); 17232 17233 last = type->facetSet; 17234 if (last != NULL) 17235 while (last->next != NULL) 17236 last = last->next; 17237 17238 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17239 facet = cur->facet; 17240 switch (facet->type) { 17241 case XML_SCHEMA_FACET_LENGTH: 17242 flength = facet; break; 17243 case XML_SCHEMA_FACET_MINLENGTH: 17244 fminlen = facet; break; 17245 case XML_SCHEMA_FACET_MININCLUSIVE: 17246 fmininc = facet; break; 17247 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17248 fminexc = facet; break; 17249 case XML_SCHEMA_FACET_MAXLENGTH: 17250 fmaxlen = facet; break; 17251 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17252 fmaxinc = facet; break; 17253 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17254 fmaxexc = facet; break; 17255 case XML_SCHEMA_FACET_TOTALDIGITS: 17256 ftotdig = facet; break; 17257 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17258 ffracdig = facet; break; 17259 default: 17260 break; 17261 } 17262 } 17263 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17264 facet = cur->facet; 17265 switch (facet->type) { 17266 case XML_SCHEMA_FACET_LENGTH: 17267 bflength = facet; break; 17268 case XML_SCHEMA_FACET_MINLENGTH: 17269 bfminlen = facet; break; 17270 case XML_SCHEMA_FACET_MININCLUSIVE: 17271 bfmininc = facet; break; 17272 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17273 bfminexc = facet; break; 17274 case XML_SCHEMA_FACET_MAXLENGTH: 17275 bfmaxlen = facet; break; 17276 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17277 bfmaxinc = facet; break; 17278 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17279 bfmaxexc = facet; break; 17280 case XML_SCHEMA_FACET_TOTALDIGITS: 17281 bftotdig = facet; break; 17282 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17283 bffracdig = facet; break; 17284 default: 17285 break; 17286 } 17287 } 17288 /* 17289 * length and minLength or maxLength (2.2) + (3.2) 17290 */ 17291 if (flength && (fminlen || fmaxlen)) { 17292 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17293 "either of 'minLength' or 'maxLength' to be specified on " 17294 "the same type definition") 17295 } 17296 /* 17297 * Mutual exclusions in the same derivation step. 17298 */ 17299 if ((fmaxinc) && (fmaxexc)) { 17300 /* 17301 * SCC "maxInclusive and maxExclusive" 17302 */ 17303 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17304 } 17305 if ((fmininc) && (fminexc)) { 17306 /* 17307 * SCC "minInclusive and minExclusive" 17308 */ 17309 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17310 } 17311 17312 if (flength && bflength) { 17313 /* 17314 * SCC "length valid restriction" 17315 * The values have to be equal. 17316 */ 17317 res = xmlSchemaCompareValues(flength->val, bflength->val); 17318 if (res == -2) 17319 goto internal_error; 17320 if (res != 0) 17321 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17322 if ((res != 0) && (bflength->fixed)) { 17323 FACET_RESTR_FIXED_ERR(flength) 17324 } 17325 17326 } 17327 if (fminlen && bfminlen) { 17328 /* 17329 * SCC "minLength valid restriction" 17330 * minLength >= BASE minLength 17331 */ 17332 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17333 if (res == -2) 17334 goto internal_error; 17335 if (res == -1) 17336 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17337 if ((res != 0) && (bfminlen->fixed)) { 17338 FACET_RESTR_FIXED_ERR(fminlen) 17339 } 17340 } 17341 if (fmaxlen && bfmaxlen) { 17342 /* 17343 * SCC "maxLength valid restriction" 17344 * maxLength <= BASE minLength 17345 */ 17346 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17347 if (res == -2) 17348 goto internal_error; 17349 if (res == 1) 17350 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17351 if ((res != 0) && (bfmaxlen->fixed)) { 17352 FACET_RESTR_FIXED_ERR(fmaxlen) 17353 } 17354 } 17355 /* 17356 * SCC "length and minLength or maxLength" 17357 */ 17358 if (! flength) 17359 flength = bflength; 17360 if (flength) { 17361 if (! fminlen) 17362 fminlen = bfminlen; 17363 if (fminlen) { 17364 /* (1.1) length >= minLength */ 17365 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17366 if (res == -2) 17367 goto internal_error; 17368 if (res == -1) 17369 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17370 } 17371 if (! fmaxlen) 17372 fmaxlen = bfmaxlen; 17373 if (fmaxlen) { 17374 /* (2.1) length <= maxLength */ 17375 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17376 if (res == -2) 17377 goto internal_error; 17378 if (res == 1) 17379 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17380 } 17381 } 17382 if (fmaxinc) { 17383 /* 17384 * "maxInclusive" 17385 */ 17386 if (fmininc) { 17387 /* SCC "maxInclusive >= minInclusive" */ 17388 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17389 if (res == -2) 17390 goto internal_error; 17391 if (res == -1) { 17392 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17393 } 17394 } 17395 /* 17396 * SCC "maxInclusive valid restriction" 17397 */ 17398 if (bfmaxinc) { 17399 /* maxInclusive <= BASE maxInclusive */ 17400 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17401 if (res == -2) 17402 goto internal_error; 17403 if (res == 1) 17404 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17405 if ((res != 0) && (bfmaxinc->fixed)) { 17406 FACET_RESTR_FIXED_ERR(fmaxinc) 17407 } 17408 } 17409 if (bfmaxexc) { 17410 /* maxInclusive < BASE maxExclusive */ 17411 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17412 if (res == -2) 17413 goto internal_error; 17414 if (res != -1) { 17415 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17416 } 17417 } 17418 if (bfmininc) { 17419 /* maxInclusive >= BASE minInclusive */ 17420 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17421 if (res == -2) 17422 goto internal_error; 17423 if (res == -1) { 17424 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17425 } 17426 } 17427 if (bfminexc) { 17428 /* maxInclusive > BASE minExclusive */ 17429 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17430 if (res == -2) 17431 goto internal_error; 17432 if (res != 1) { 17433 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17434 } 17435 } 17436 } 17437 if (fmaxexc) { 17438 /* 17439 * "maxExclusive >= minExclusive" 17440 */ 17441 if (fminexc) { 17442 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17443 if (res == -2) 17444 goto internal_error; 17445 if (res == -1) { 17446 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17447 } 17448 } 17449 /* 17450 * "maxExclusive valid restriction" 17451 */ 17452 if (bfmaxexc) { 17453 /* maxExclusive <= BASE maxExclusive */ 17454 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17455 if (res == -2) 17456 goto internal_error; 17457 if (res == 1) { 17458 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17459 } 17460 if ((res != 0) && (bfmaxexc->fixed)) { 17461 FACET_RESTR_FIXED_ERR(fmaxexc) 17462 } 17463 } 17464 if (bfmaxinc) { 17465 /* maxExclusive <= BASE maxInclusive */ 17466 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17467 if (res == -2) 17468 goto internal_error; 17469 if (res == 1) { 17470 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17471 } 17472 } 17473 if (bfmininc) { 17474 /* maxExclusive > BASE minInclusive */ 17475 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17476 if (res == -2) 17477 goto internal_error; 17478 if (res != 1) { 17479 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17480 } 17481 } 17482 if (bfminexc) { 17483 /* maxExclusive > BASE minExclusive */ 17484 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17485 if (res == -2) 17486 goto internal_error; 17487 if (res != 1) { 17488 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17489 } 17490 } 17491 } 17492 if (fminexc) { 17493 /* 17494 * "minExclusive < maxInclusive" 17495 */ 17496 if (fmaxinc) { 17497 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17498 if (res == -2) 17499 goto internal_error; 17500 if (res != -1) { 17501 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17502 } 17503 } 17504 /* 17505 * "minExclusive valid restriction" 17506 */ 17507 if (bfminexc) { 17508 /* minExclusive >= BASE minExclusive */ 17509 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17510 if (res == -2) 17511 goto internal_error; 17512 if (res == -1) { 17513 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17514 } 17515 if ((res != 0) && (bfminexc->fixed)) { 17516 FACET_RESTR_FIXED_ERR(fminexc) 17517 } 17518 } 17519 if (bfmaxinc) { 17520 /* minExclusive <= BASE maxInclusive */ 17521 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17522 if (res == -2) 17523 goto internal_error; 17524 if (res == 1) { 17525 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17526 } 17527 } 17528 if (bfmininc) { 17529 /* minExclusive >= BASE minInclusive */ 17530 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17531 if (res == -2) 17532 goto internal_error; 17533 if (res == -1) { 17534 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17535 } 17536 } 17537 if (bfmaxexc) { 17538 /* minExclusive < BASE maxExclusive */ 17539 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17540 if (res == -2) 17541 goto internal_error; 17542 if (res != -1) { 17543 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17544 } 17545 } 17546 } 17547 if (fmininc) { 17548 /* 17549 * "minInclusive < maxExclusive" 17550 */ 17551 if (fmaxexc) { 17552 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17553 if (res == -2) 17554 goto internal_error; 17555 if (res != -1) { 17556 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17557 } 17558 } 17559 /* 17560 * "minExclusive valid restriction" 17561 */ 17562 if (bfmininc) { 17563 /* minInclusive >= BASE minInclusive */ 17564 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17565 if (res == -2) 17566 goto internal_error; 17567 if (res == -1) { 17568 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17569 } 17570 if ((res != 0) && (bfmininc->fixed)) { 17571 FACET_RESTR_FIXED_ERR(fmininc) 17572 } 17573 } 17574 if (bfmaxinc) { 17575 /* minInclusive <= BASE maxInclusive */ 17576 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17577 if (res == -2) 17578 goto internal_error; 17579 if (res == 1) { 17580 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17581 } 17582 } 17583 if (bfminexc) { 17584 /* minInclusive > BASE minExclusive */ 17585 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17586 if (res == -2) 17587 goto internal_error; 17588 if (res != 1) 17589 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17590 } 17591 if (bfmaxexc) { 17592 /* minInclusive < BASE maxExclusive */ 17593 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17594 if (res == -2) 17595 goto internal_error; 17596 if (res != -1) 17597 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17598 } 17599 } 17600 if (ftotdig && bftotdig) { 17601 /* 17602 * SCC " totalDigits valid restriction" 17603 * totalDigits <= BASE totalDigits 17604 */ 17605 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17606 if (res == -2) 17607 goto internal_error; 17608 if (res == 1) 17609 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17610 -1, 1, 1); 17611 if ((res != 0) && (bftotdig->fixed)) { 17612 FACET_RESTR_FIXED_ERR(ftotdig) 17613 } 17614 } 17615 if (ffracdig && bffracdig) { 17616 /* 17617 * SCC "fractionDigits valid restriction" 17618 * fractionDigits <= BASE fractionDigits 17619 */ 17620 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17621 if (res == -2) 17622 goto internal_error; 17623 if (res == 1) 17624 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17625 -1, 1, 1); 17626 if ((res != 0) && (bffracdig->fixed)) { 17627 FACET_RESTR_FIXED_ERR(ffracdig) 17628 } 17629 } 17630 /* 17631 * SCC "fractionDigits less than or equal to totalDigits" 17632 */ 17633 if (! ftotdig) 17634 ftotdig = bftotdig; 17635 if (! ffracdig) 17636 ffracdig = bffracdig; 17637 if (ftotdig && ffracdig) { 17638 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17639 if (res == -2) 17640 goto internal_error; 17641 if (res == 1) 17642 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17643 -1, 1, 0); 17644 } 17645 /* 17646 * *Enumerations* won' be added here, since only the first set 17647 * of enumerations in the ancestor-or-self axis is used 17648 * for validation, plus we need to use the base type of those 17649 * enumerations for whitespace. 17650 * 17651 * *Patterns*: won't be add here, since they are ORed at 17652 * type level and ANDed at ancestor level. This will 17653 * happed during validation by walking the base axis 17654 * of the type. 17655 */ 17656 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17657 bfacet = cur->facet; 17658 /* 17659 * Special handling of enumerations and patterns. 17660 * TODO: hmm, they should not appear in the set, so remove this. 17661 */ 17662 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17663 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17664 continue; 17665 /* 17666 * Search for a duplicate facet in the current type. 17667 */ 17668 link = type->facetSet; 17669 /* err = 0; */ 17670 /* fixedErr = 0; */ 17671 while (link != NULL) { 17672 facet = link->facet; 17673 if (facet->type == bfacet->type) { 17674 switch (facet->type) { 17675 case XML_SCHEMA_FACET_WHITESPACE: 17676 /* 17677 * The whitespace must be stronger. 17678 */ 17679 if (facet->whitespace < bfacet->whitespace) { 17680 FACET_RESTR_ERR(facet, 17681 "The 'whitespace' value has to be equal to " 17682 "or stronger than the 'whitespace' value of " 17683 "the base type") 17684 } 17685 if ((bfacet->fixed) && 17686 (facet->whitespace != bfacet->whitespace)) { 17687 FACET_RESTR_FIXED_ERR(facet) 17688 } 17689 break; 17690 default: 17691 break; 17692 } 17693 /* Duplicate found. */ 17694 break; 17695 } 17696 link = link->next; 17697 } 17698 /* 17699 * If no duplicate was found: add the base types's facet 17700 * to the set. 17701 */ 17702 if (link == NULL) { 17703 link = (xmlSchemaFacetLinkPtr) 17704 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17705 if (link == NULL) { 17706 xmlSchemaPErrMemory(pctxt, 17707 "deriving facets, creating a facet link", NULL); 17708 return (-1); 17709 } 17710 link->facet = cur->facet; 17711 link->next = NULL; 17712 if (last == NULL) 17713 type->facetSet = link; 17714 else 17715 last->next = link; 17716 last = link; 17717 } 17718 17719 } 17720 17721 return (0); 17722 internal_error: 17723 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17724 "an error occured"); 17725 return (-1); 17726 } 17727 17728 static int 17729 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17730 xmlSchemaTypePtr type) 17731 { 17732 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17733 /* 17734 * The actual value is then formed by replacing any union type 17735 * definition in the explicit members with the members of their 17736 * {member type definitions}, in order. 17737 * 17738 * TODO: There's a bug entry at 17739 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17740 * which indicates that we'll keep the union types the future. 17741 */ 17742 link = type->memberTypes; 17743 while (link != NULL) { 17744 17745 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17746 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17747 17748 if (WXS_IS_UNION(link->type)) { 17749 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17750 if (subLink != NULL) { 17751 link->type = subLink->type; 17752 if (subLink->next != NULL) { 17753 lastLink = link->next; 17754 subLink = subLink->next; 17755 prevLink = link; 17756 while (subLink != NULL) { 17757 newLink = (xmlSchemaTypeLinkPtr) 17758 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17759 if (newLink == NULL) { 17760 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17761 NULL); 17762 return (-1); 17763 } 17764 newLink->type = subLink->type; 17765 prevLink->next = newLink; 17766 prevLink = newLink; 17767 newLink->next = lastLink; 17768 17769 subLink = subLink->next; 17770 } 17771 } 17772 } 17773 } 17774 link = link->next; 17775 } 17776 return (0); 17777 } 17778 17779 static void 17780 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17781 { 17782 int has = 0, needVal = 0, normVal = 0; 17783 17784 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17785 if (has) { 17786 needVal = (type->baseType->flags & 17787 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17788 normVal = (type->baseType->flags & 17789 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17790 } 17791 if (type->facets != NULL) { 17792 xmlSchemaFacetPtr fac; 17793 17794 for (fac = type->facets; fac != NULL; fac = fac->next) { 17795 switch (fac->type) { 17796 case XML_SCHEMA_FACET_WHITESPACE: 17797 break; 17798 case XML_SCHEMA_FACET_PATTERN: 17799 normVal = 1; 17800 has = 1; 17801 break; 17802 case XML_SCHEMA_FACET_ENUMERATION: 17803 needVal = 1; 17804 normVal = 1; 17805 has = 1; 17806 break; 17807 default: 17808 has = 1; 17809 break; 17810 } 17811 } 17812 } 17813 if (normVal) 17814 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17815 if (needVal) 17816 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17817 if (has) 17818 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17819 17820 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17821 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17822 /* 17823 * OPTIMIZE VAL TODO: Some facets need a computed value. 17824 */ 17825 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17826 (prim->builtInType != XML_SCHEMAS_STRING)) { 17827 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17828 } 17829 } 17830 } 17831 17832 static int 17833 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17834 { 17835 17836 17837 /* 17838 * Evaluate the whitespace-facet value. 17839 */ 17840 if (WXS_IS_LIST(type)) { 17841 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17842 return (0); 17843 } else if (WXS_IS_UNION(type)) 17844 return (0); 17845 17846 if (type->facetSet != NULL) { 17847 xmlSchemaFacetLinkPtr lin; 17848 17849 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17850 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17851 switch (lin->facet->whitespace) { 17852 case XML_SCHEMAS_FACET_PRESERVE: 17853 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17854 break; 17855 case XML_SCHEMAS_FACET_REPLACE: 17856 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17857 break; 17858 case XML_SCHEMAS_FACET_COLLAPSE: 17859 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17860 break; 17861 default: 17862 return (-1); 17863 } 17864 return (0); 17865 } 17866 } 17867 } 17868 /* 17869 * For all atomic datatypes other than string (and types derived 17870 * by restriction from it) the value of whiteSpace is fixed to 17871 * collapse 17872 */ 17873 { 17874 xmlSchemaTypePtr anc; 17875 17876 for (anc = type->baseType; anc != NULL && 17877 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17878 anc = anc->baseType) { 17879 17880 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17881 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17882 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17883 17884 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17885 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17886 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17887 17888 } else 17889 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17890 break; 17891 } 17892 } 17893 } 17894 return (0); 17895 } 17896 17897 static int 17898 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17899 xmlSchemaTypePtr type) 17900 { 17901 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17902 return(0); 17903 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17904 return(0); 17905 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17906 17907 if (WXS_IS_LIST(type)) { 17908 /* 17909 * Corresponds to <simpleType><list>... 17910 */ 17911 if (type->subtypes == NULL) { 17912 /* 17913 * This one is really needed, so get out. 17914 */ 17915 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17916 "list type has no item-type assigned"); 17917 return(-1); 17918 } 17919 } else if (WXS_IS_UNION(type)) { 17920 /* 17921 * Corresponds to <simpleType><union>... 17922 */ 17923 if (type->memberTypes == NULL) { 17924 /* 17925 * This one is really needed, so get out. 17926 */ 17927 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17928 "union type has no member-types assigned"); 17929 return(-1); 17930 } 17931 } else { 17932 /* 17933 * Corresponds to <simpleType><restriction>... 17934 */ 17935 if (type->baseType == NULL) { 17936 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17937 "type has no base-type assigned"); 17938 return(-1); 17939 } 17940 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17941 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17942 return(-1); 17943 /* 17944 * Variety 17945 * If the <restriction> alternative is chosen, then the 17946 * {variety} of the {base type definition}. 17947 */ 17948 if (WXS_IS_ATOMIC(type->baseType)) 17949 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17950 else if (WXS_IS_LIST(type->baseType)) { 17951 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17952 /* 17953 * Inherit the itemType. 17954 */ 17955 type->subtypes = type->baseType->subtypes; 17956 } else if (WXS_IS_UNION(type->baseType)) { 17957 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 17958 /* 17959 * NOTE that we won't assign the memberTypes of the base, 17960 * since this will make trouble when freeing them; we will 17961 * use a lookup function to access them instead. 17962 */ 17963 } 17964 } 17965 return(0); 17966 } 17967 17968 #ifdef DEBUG_TYPE 17969 static void 17970 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 17971 xmlSchemaTypePtr type) 17972 { 17973 if (type->node != NULL) { 17974 xmlGenericError(xmlGenericErrorContext, 17975 "Type of %s : %s:%d :", name, 17976 type->node->doc->URL, 17977 xmlGetLineNo(type->node)); 17978 } else { 17979 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 17980 } 17981 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 17982 switch (type->contentType) { 17983 case XML_SCHEMA_CONTENT_SIMPLE: 17984 xmlGenericError(xmlGenericErrorContext, "simple\n"); 17985 break; 17986 case XML_SCHEMA_CONTENT_ELEMENTS: 17987 xmlGenericError(xmlGenericErrorContext, "elements\n"); 17988 break; 17989 case XML_SCHEMA_CONTENT_UNKNOWN: 17990 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 17991 break; 17992 case XML_SCHEMA_CONTENT_EMPTY: 17993 xmlGenericError(xmlGenericErrorContext, "empty\n"); 17994 break; 17995 case XML_SCHEMA_CONTENT_MIXED: 17996 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 17997 type->subtypes)) 17998 xmlGenericError(xmlGenericErrorContext, 17999 "mixed as emptiable particle\n"); 18000 else 18001 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18002 break; 18003 /* Removed, since not used. */ 18004 /* 18005 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18006 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18007 break; 18008 */ 18009 case XML_SCHEMA_CONTENT_BASIC: 18010 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18011 break; 18012 default: 18013 xmlGenericError(xmlGenericErrorContext, 18014 "not registered !!!\n"); 18015 break; 18016 } 18017 } 18018 } 18019 #endif 18020 18021 /* 18022 * 3.14.6 Constraints on Simple Type Definition Schema Components 18023 */ 18024 static int 18025 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18026 xmlSchemaTypePtr type) 18027 { 18028 int res, olderrs = pctxt->nberrors; 18029 18030 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18031 return(-1); 18032 18033 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18034 return(0); 18035 18036 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18037 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18038 18039 if (type->baseType == NULL) { 18040 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18041 "missing baseType"); 18042 goto exit_failure; 18043 } 18044 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18045 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18046 /* 18047 * If a member type of a union is a union itself, we need to substitute 18048 * that member type for its member types. 18049 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18050 * types in WXS 1.1. 18051 */ 18052 if ((type->memberTypes != NULL) && 18053 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18054 return(-1); 18055 /* 18056 * SPEC src-simple-type 1 18057 * "The corresponding simple type definition, if any, must satisfy 18058 * the conditions set out in Constraints on Simple Type Definition 18059 * Schema Components (3.14.6)." 18060 */ 18061 /* 18062 * Schema Component Constraint: Simple Type Definition Properties Correct 18063 * (st-props-correct) 18064 */ 18065 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18066 HFAILURE HERROR 18067 /* 18068 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18069 * (cos-st-restricts) 18070 */ 18071 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18072 HFAILURE HERROR 18073 /* 18074 * TODO: Removed the error report, since it got annoying to get an 18075 * extra error report, if anything failed until now. 18076 * Enable this if needed. 18077 * 18078 * xmlSchemaPErr(ctxt, type->node, 18079 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18080 * "Simple type '%s' does not satisfy the constraints " 18081 * "on simple type definitions.\n", 18082 * type->name, NULL); 18083 */ 18084 /* 18085 * Schema Component Constraint: Simple Type Restriction (Facets) 18086 * (st-restrict-facets) 18087 */ 18088 res = xmlSchemaCheckFacetValues(type, pctxt); 18089 HFAILURE HERROR 18090 if ((type->facetSet != NULL) || 18091 (type->baseType->facetSet != NULL)) { 18092 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18093 HFAILURE HERROR 18094 } 18095 /* 18096 * Whitespace value. 18097 */ 18098 res = xmlSchemaTypeFixupWhitespace(type); 18099 HFAILURE HERROR 18100 xmlSchemaTypeFixupOptimFacets(type); 18101 18102 exit_error: 18103 #ifdef DEBUG_TYPE 18104 xmlSchemaDebugFixedType(pctxt, type); 18105 #endif 18106 if (olderrs != pctxt->nberrors) 18107 return(pctxt->err); 18108 return(0); 18109 18110 exit_failure: 18111 #ifdef DEBUG_TYPE 18112 xmlSchemaDebugFixedType(pctxt, type); 18113 #endif 18114 return(-1); 18115 } 18116 18117 static int 18118 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18119 xmlSchemaTypePtr type) 18120 { 18121 int res = 0, olderrs = pctxt->nberrors; 18122 xmlSchemaTypePtr baseType = type->baseType; 18123 18124 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18125 return(0); 18126 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18127 if (baseType == NULL) { 18128 PERROR_INT("xmlSchemaFixupComplexType", 18129 "missing baseType"); 18130 goto exit_failure; 18131 } 18132 /* 18133 * Fixup the base type. 18134 */ 18135 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18136 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18137 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18138 /* 18139 * Skip fixup if the base type is invalid. 18140 * TODO: Generate a warning! 18141 */ 18142 return(0); 18143 } 18144 /* 18145 * This basically checks if the base type can be derived. 18146 */ 18147 res = xmlSchemaCheckSRCCT(pctxt, type); 18148 HFAILURE HERROR 18149 /* 18150 * Fixup the content type. 18151 */ 18152 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18153 /* 18154 * Corresponds to <complexType><simpleContent>... 18155 */ 18156 if ((WXS_IS_COMPLEX(baseType)) && 18157 (baseType->contentTypeDef != NULL) && 18158 (WXS_IS_RESTRICTION(type))) { 18159 xmlSchemaTypePtr contentBase, content; 18160 #ifdef ENABLE_NAMED_LOCALS 18161 char buf[30]; 18162 const xmlChar *tmpname; 18163 #endif 18164 /* 18165 * SPEC (1) If <restriction> + base type is <complexType>, 18166 * "whose own {content type} is a simple type..." 18167 */ 18168 if (type->contentTypeDef != NULL) { 18169 /* 18170 * SPEC (1.1) "the simple type definition corresponding to the 18171 * <simpleType> among the [children] of <restriction> if there 18172 * is one;" 18173 * Note that this "<simpleType> among the [children]" was put 18174 * into ->contentTypeDef during parsing. 18175 */ 18176 contentBase = type->contentTypeDef; 18177 type->contentTypeDef = NULL; 18178 } else { 18179 /* 18180 * (1.2) "...otherwise (<restriction> has no <simpleType> 18181 * among its [children]), the simple type definition which 18182 * is the {content type} of the ... base type." 18183 */ 18184 contentBase = baseType->contentTypeDef; 18185 } 18186 /* 18187 * SPEC 18188 * "... a simple type definition which restricts the simple 18189 * type definition identified in clause 1.1 or clause 1.2 18190 * with a set of facet components" 18191 * 18192 * Create the anonymous simple type, which will be the content 18193 * type of the complex type. 18194 */ 18195 #ifdef ENABLE_NAMED_LOCALS 18196 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18197 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18198 content = xmlSchemaAddType(pctxt, pctxt->schema, 18199 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18200 type->node, 0); 18201 #else 18202 content = xmlSchemaAddType(pctxt, pctxt->schema, 18203 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18204 type->node, 0); 18205 #endif 18206 if (content == NULL) 18207 goto exit_failure; 18208 /* 18209 * We will use the same node as for the <complexType> 18210 * to have it somehow anchored in the schema doc. 18211 */ 18212 content->type = XML_SCHEMA_TYPE_SIMPLE; 18213 content->baseType = contentBase; 18214 /* 18215 * Move the facets, previously anchored on the 18216 * complexType during parsing. 18217 */ 18218 content->facets = type->facets; 18219 type->facets = NULL; 18220 content->facetSet = type->facetSet; 18221 type->facetSet = NULL; 18222 18223 type->contentTypeDef = content; 18224 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18225 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18226 /* 18227 * Fixup the newly created type. We don't need to check 18228 * for circularity here. 18229 */ 18230 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18231 HFAILURE HERROR 18232 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18233 HFAILURE HERROR 18234 18235 } else if ((WXS_IS_COMPLEX(baseType)) && 18236 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18237 (WXS_IS_RESTRICTION(type))) { 18238 /* 18239 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18240 * an emptiable particle, then a simple type definition which 18241 * restricts the <restriction>'s <simpleType> child. 18242 */ 18243 if ((type->contentTypeDef == NULL) || 18244 (type->contentTypeDef->baseType == NULL)) { 18245 /* 18246 * TODO: Check if this ever happens. 18247 */ 18248 xmlSchemaPCustomErr(pctxt, 18249 XML_SCHEMAP_INTERNAL, 18250 WXS_BASIC_CAST type, NULL, 18251 "Internal error: xmlSchemaTypeFixup, " 18252 "complex type '%s': the <simpleContent><restriction> " 18253 "is missing a <simpleType> child, but was not catched " 18254 "by xmlSchemaCheckSRCCT()", type->name); 18255 goto exit_failure; 18256 } 18257 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18258 /* 18259 * SPEC (3) If <extension> + base is <complexType> with 18260 * <simpleType> content, "...then the {content type} of that 18261 * complex type definition" 18262 */ 18263 if (baseType->contentTypeDef == NULL) { 18264 /* 18265 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18266 * should have catched this already. 18267 */ 18268 xmlSchemaPCustomErr(pctxt, 18269 XML_SCHEMAP_INTERNAL, 18270 WXS_BASIC_CAST type, NULL, 18271 "Internal error: xmlSchemaTypeFixup, " 18272 "complex type '%s': the <extension>ed base type is " 18273 "a complex type with no simple content type", 18274 type->name); 18275 goto exit_failure; 18276 } 18277 type->contentTypeDef = baseType->contentTypeDef; 18278 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18279 /* 18280 * SPEC (4) <extension> + base is <simpleType> 18281 * "... then that simple type definition" 18282 */ 18283 type->contentTypeDef = baseType; 18284 } else { 18285 /* 18286 * TODO: Check if this ever happens. 18287 */ 18288 xmlSchemaPCustomErr(pctxt, 18289 XML_SCHEMAP_INTERNAL, 18290 WXS_BASIC_CAST type, NULL, 18291 "Internal error: xmlSchemaTypeFixup, " 18292 "complex type '%s' with <simpleContent>: unhandled " 18293 "derivation case", type->name); 18294 goto exit_failure; 18295 } 18296 } else { 18297 int dummySequence = 0; 18298 xmlSchemaParticlePtr particle = 18299 (xmlSchemaParticlePtr) type->subtypes; 18300 /* 18301 * Corresponds to <complexType><complexContent>... 18302 * 18303 * NOTE that the effective mixed was already set during parsing of 18304 * <complexType> and <complexContent>; its flag value is 18305 * XML_SCHEMAS_TYPE_MIXED. 18306 * 18307 * Compute the "effective content": 18308 * (2.1.1) + (2.1.2) + (2.1.3) 18309 */ 18310 if ((particle == NULL) || 18311 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18312 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18313 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18314 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18315 (particle->minOccurs == 0))) && 18316 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18317 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18318 /* 18319 * SPEC (2.1.4) "If the effective mixed is true, then 18320 * a particle whose properties are as follows:..." 18321 * 18322 * Empty sequence model group with 18323 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18324 * NOTE that we sill assign it the <complexType> node to 18325 * somehow anchor it in the doc. 18326 */ 18327 if ((particle == NULL) || 18328 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18329 /* 18330 * Create the particle. 18331 */ 18332 particle = xmlSchemaAddParticle(pctxt, 18333 type->node, 1, 1); 18334 if (particle == NULL) 18335 goto exit_failure; 18336 /* 18337 * Create the model group. 18338 */ /* URGENT TODO: avoid adding to pending items. */ 18339 particle->children = (xmlSchemaTreeItemPtr) 18340 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18341 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18342 if (particle->children == NULL) 18343 goto exit_failure; 18344 18345 type->subtypes = (xmlSchemaTypePtr) particle; 18346 } 18347 dummySequence = 1; 18348 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18349 } else { 18350 /* 18351 * SPEC (2.1.5) "otherwise empty" 18352 */ 18353 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18354 } 18355 } else { 18356 /* 18357 * SPEC (2.2) "otherwise the particle corresponding to the 18358 * <all>, <choice>, <group> or <sequence> among the 18359 * [children]." 18360 */ 18361 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18362 } 18363 /* 18364 * Compute the "content type". 18365 */ 18366 if (WXS_IS_RESTRICTION(type)) { 18367 /* 18368 * SPEC (3.1) "If <restriction>..." 18369 * (3.1.1) + (3.1.2) */ 18370 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18371 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18372 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18373 } 18374 } else { 18375 /* 18376 * SPEC (3.2) "If <extension>..." 18377 */ 18378 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18379 /* 18380 * SPEC (3.2.1) 18381 * "If the effective content is empty, then the 18382 * {content type} of the [...] base ..." 18383 */ 18384 type->contentType = baseType->contentType; 18385 type->subtypes = baseType->subtypes; 18386 /* 18387 * Fixes bug #347316: 18388 * This is the case when the base type has a simple 18389 * type definition as content. 18390 */ 18391 type->contentTypeDef = baseType->contentTypeDef; 18392 /* 18393 * NOTE that the effective mixed is ignored here. 18394 */ 18395 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18396 /* 18397 * SPEC (3.2.2) 18398 */ 18399 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18400 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18401 } else { 18402 /* 18403 * SPEC (3.2.3) 18404 */ 18405 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18406 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18407 /* 18408 * "A model group whose {compositor} is sequence and whose 18409 * {particles} are..." 18410 */ 18411 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18412 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18413 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18414 XML_SCHEMA_TYPE_ALL)) 18415 { 18416 /* 18417 * SPEC cos-all-limited (1) 18418 */ 18419 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18420 /* TODO: error code */ 18421 XML_SCHEMAP_COS_ALL_LIMITED, 18422 WXS_ITEM_NODE(type), NULL, 18423 "The type has an 'all' model group in its " 18424 "{content type} and thus cannot be derived from " 18425 "a non-empty type, since this would produce a " 18426 "'sequence' model group containing the 'all' " 18427 "model group; 'all' model groups are not " 18428 "allowed to appear inside other model groups", 18429 NULL, NULL); 18430 18431 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18432 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18433 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18434 XML_SCHEMA_TYPE_ALL)) 18435 { 18436 /* 18437 * SPEC cos-all-limited (1) 18438 */ 18439 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18440 /* TODO: error code */ 18441 XML_SCHEMAP_COS_ALL_LIMITED, 18442 WXS_ITEM_NODE(type), NULL, 18443 "A type cannot be derived by extension from a type " 18444 "which has an 'all' model group in its " 18445 "{content type}, since this would produce a " 18446 "'sequence' model group containing the 'all' " 18447 "model group; 'all' model groups are not " 18448 "allowed to appear inside other model groups", 18449 NULL, NULL); 18450 18451 } else if (! dummySequence) { 18452 xmlSchemaTreeItemPtr effectiveContent = 18453 (xmlSchemaTreeItemPtr) type->subtypes; 18454 /* 18455 * Create the particle. 18456 */ 18457 particle = xmlSchemaAddParticle(pctxt, 18458 type->node, 1, 1); 18459 if (particle == NULL) 18460 goto exit_failure; 18461 /* 18462 * Create the "sequence" model group. 18463 */ 18464 particle->children = (xmlSchemaTreeItemPtr) 18465 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18466 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18467 if (particle->children == NULL) 18468 goto exit_failure; 18469 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18470 /* 18471 * SPEC "the particle of the {content type} of 18472 * the ... base ..." 18473 * Create a duplicate of the base type's particle 18474 * and assign its "term" to it. 18475 */ 18476 particle->children->children = 18477 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18478 type->node, 18479 ((xmlSchemaParticlePtr) type->subtypes)->minOccurs, 18480 ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs); 18481 if (particle->children->children == NULL) 18482 goto exit_failure; 18483 particle = (xmlSchemaParticlePtr) 18484 particle->children->children; 18485 particle->children = 18486 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18487 /* 18488 * SPEC "followed by the effective content." 18489 */ 18490 particle->next = effectiveContent; 18491 /* 18492 * This all will result in: 18493 * new-particle 18494 * --> new-sequence( 18495 * new-particle 18496 * --> base-model, 18497 * this-particle 18498 * --> this-model 18499 * ) 18500 */ 18501 } else { 18502 /* 18503 * This is the case when there is already an empty 18504 * <sequence> with minOccurs==maxOccurs==1. 18505 * Just add the base types's content type. 18506 * NOTE that, although we miss to add an intermediate 18507 * <sequence>, this should produce no difference to 18508 * neither the regex compilation of the content model, 18509 * nor to the complex type contraints. 18510 */ 18511 particle->children->children = 18512 (xmlSchemaTreeItemPtr) baseType->subtypes; 18513 } 18514 } 18515 } 18516 } 18517 /* 18518 * Now fixup attribute uses: 18519 * - expand attr. group references 18520 * - intersect attribute wildcards 18521 * - inherit attribute uses of the base type 18522 * - inherit or union attr. wildcards if extending 18523 * - apply attr. use prohibitions if restricting 18524 */ 18525 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18526 HFAILURE HERROR 18527 /* 18528 * Apply the complex type component constraints; this will not 18529 * check attributes, since this is done in 18530 * xmlSchemaFixupTypeAttributeUses(). 18531 */ 18532 res = xmlSchemaCheckCTComponent(pctxt, type); 18533 HFAILURE HERROR 18534 18535 #ifdef DEBUG_TYPE 18536 xmlSchemaDebugFixedType(pctxt, type); 18537 #endif 18538 if (olderrs != pctxt->nberrors) 18539 return(pctxt->err); 18540 else 18541 return(0); 18542 18543 exit_error: 18544 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18545 #ifdef DEBUG_TYPE 18546 xmlSchemaDebugFixedType(pctxt, type); 18547 #endif 18548 return(pctxt->err); 18549 18550 exit_failure: 18551 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18552 #ifdef DEBUG_TYPE 18553 xmlSchemaDebugFixedType(pctxt, type); 18554 #endif 18555 return(-1); 18556 } 18557 18558 18559 /** 18560 * xmlSchemaTypeFixup: 18561 * @typeDecl: the schema type definition 18562 * @ctxt: the schema parser context 18563 * 18564 * Fixes the content model of the type. 18565 * URGENT TODO: We need an int result! 18566 */ 18567 static int 18568 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18569 xmlSchemaAbstractCtxtPtr actxt) 18570 { 18571 if (type == NULL) 18572 return(0); 18573 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18574 AERROR_INT("xmlSchemaTypeFixup", 18575 "this function needs a parser context"); 18576 return(-1); 18577 } 18578 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18579 return(0); 18580 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18581 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18582 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18583 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18584 return(0); 18585 } 18586 18587 /** 18588 * xmlSchemaCheckFacet: 18589 * @facet: the facet 18590 * @typeDecl: the schema type definition 18591 * @pctxt: the schema parser context or NULL 18592 * @name: the optional name of the type 18593 * 18594 * Checks and computes the values of facets. 18595 * 18596 * Returns 0 if valid, a positive error code if not valid and 18597 * -1 in case of an internal or API error. 18598 */ 18599 int 18600 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18601 xmlSchemaTypePtr typeDecl, 18602 xmlSchemaParserCtxtPtr pctxt, 18603 const xmlChar * name ATTRIBUTE_UNUSED) 18604 { 18605 int ret = 0, ctxtGiven; 18606 18607 if ((facet == NULL) || (typeDecl == NULL)) 18608 return(-1); 18609 /* 18610 * TODO: will the parser context be given if used from 18611 * the relaxNG module? 18612 */ 18613 if (pctxt == NULL) 18614 ctxtGiven = 0; 18615 else 18616 ctxtGiven = 1; 18617 18618 switch (facet->type) { 18619 case XML_SCHEMA_FACET_MININCLUSIVE: 18620 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18621 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18622 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18623 case XML_SCHEMA_FACET_ENUMERATION: { 18624 /* 18625 * Okay we need to validate the value 18626 * at that point. 18627 */ 18628 xmlSchemaTypePtr base; 18629 18630 /* 4.3.5.5 Constraints on enumeration Schema Components 18631 * Schema Component Constraint: enumeration valid restriction 18632 * It is an error if any member of {value} is not in the 18633 * value space of {base type definition}. 18634 * 18635 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18636 * The value must be in the 18637 * value space of the base type. 18638 */ 18639 /* 18640 * This function is intended to deliver a compiled value 18641 * on the facet. In this implementation of XML Schemata the 18642 * type holding a facet, won't be a built-in type. 18643 * Thus to ensure that other API 18644 * calls (relaxng) do work, if the given type is a built-in 18645 * type, we will assume that the given built-in type *is 18646 * already* the base type. 18647 */ 18648 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18649 base = typeDecl->baseType; 18650 if (base == NULL) { 18651 PERROR_INT("xmlSchemaCheckFacet", 18652 "a type user derived type has no base type"); 18653 return (-1); 18654 } 18655 } else 18656 base = typeDecl; 18657 18658 if (! ctxtGiven) { 18659 /* 18660 * A context is needed if called from RelaxNG. 18661 */ 18662 pctxt = xmlSchemaNewParserCtxt("*"); 18663 if (pctxt == NULL) 18664 return (-1); 18665 } 18666 /* 18667 * NOTE: This call does not check the content nodes, 18668 * since they are not available: 18669 * facet->node is just the node holding the facet 18670 * definition, *not* the attribute holding the *value* 18671 * of the facet. 18672 */ 18673 ret = xmlSchemaVCheckCVCSimpleType( 18674 ACTXT_CAST pctxt, facet->node, base, 18675 facet->value, &(facet->val), 1, 1, 0); 18676 if (ret != 0) { 18677 if (ret < 0) { 18678 /* No error message for RelaxNG. */ 18679 if (ctxtGiven) { 18680 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18681 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18682 "Internal error: xmlSchemaCheckFacet, " 18683 "failed to validate the value '%s' of the " 18684 "facet '%s' against the base type", 18685 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18686 } 18687 goto internal_error; 18688 } 18689 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18690 /* No error message for RelaxNG. */ 18691 if (ctxtGiven) { 18692 xmlChar *str = NULL; 18693 18694 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18695 ret, facet->node, WXS_BASIC_CAST facet, 18696 "The value '%s' of the facet does not validate " 18697 "against the base type '%s'", 18698 facet->value, 18699 xmlSchemaFormatQName(&str, 18700 base->targetNamespace, base->name)); 18701 FREE_AND_NULL(str); 18702 } 18703 goto exit; 18704 } else if (facet->val == NULL) { 18705 if (ctxtGiven) { 18706 PERROR_INT("xmlSchemaCheckFacet", 18707 "value was not computed"); 18708 } 18709 TODO 18710 } 18711 break; 18712 } 18713 case XML_SCHEMA_FACET_PATTERN: 18714 facet->regexp = xmlRegexpCompile(facet->value); 18715 if (facet->regexp == NULL) { 18716 ret = XML_SCHEMAP_REGEXP_INVALID; 18717 /* No error message for RelaxNG. */ 18718 if (ctxtGiven) { 18719 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18720 ret, facet->node, WXS_BASIC_CAST typeDecl, 18721 "The value '%s' of the facet 'pattern' is not a " 18722 "valid regular expression", 18723 facet->value, NULL); 18724 } 18725 } 18726 break; 18727 case XML_SCHEMA_FACET_TOTALDIGITS: 18728 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18729 case XML_SCHEMA_FACET_LENGTH: 18730 case XML_SCHEMA_FACET_MAXLENGTH: 18731 case XML_SCHEMA_FACET_MINLENGTH: 18732 18733 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18734 ret = xmlSchemaValidatePredefinedType( 18735 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18736 facet->value, &(facet->val)); 18737 } else { 18738 ret = xmlSchemaValidatePredefinedType( 18739 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18740 facet->value, &(facet->val)); 18741 } 18742 if (ret != 0) { 18743 if (ret < 0) { 18744 /* No error message for RelaxNG. */ 18745 if (ctxtGiven) { 18746 PERROR_INT("xmlSchemaCheckFacet", 18747 "validating facet value"); 18748 } 18749 goto internal_error; 18750 } 18751 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18752 /* No error message for RelaxNG. */ 18753 if (ctxtGiven) { 18754 /* error code */ 18755 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18756 ret, facet->node, WXS_BASIC_CAST typeDecl, 18757 "The value '%s' of the facet '%s' is not a valid '%s'", 18758 facet->value, 18759 xmlSchemaFacetTypeToString(facet->type), 18760 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18761 BAD_CAST "nonNegativeInteger" : 18762 BAD_CAST "positiveInteger", 18763 NULL); 18764 } 18765 } 18766 break; 18767 18768 case XML_SCHEMA_FACET_WHITESPACE:{ 18769 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18770 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18771 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18772 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18773 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18774 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18775 } else { 18776 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18777 /* No error message for RelaxNG. */ 18778 if (ctxtGiven) { 18779 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18780 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18781 ret, facet->node, WXS_BASIC_CAST typeDecl, 18782 "The value '%s' of the facet 'whitespace' is not " 18783 "valid", facet->value, NULL); 18784 } 18785 } 18786 } 18787 default: 18788 break; 18789 } 18790 exit: 18791 if ((! ctxtGiven) && (pctxt != NULL)) 18792 xmlSchemaFreeParserCtxt(pctxt); 18793 return (ret); 18794 internal_error: 18795 if ((! ctxtGiven) && (pctxt != NULL)) 18796 xmlSchemaFreeParserCtxt(pctxt); 18797 return (-1); 18798 } 18799 18800 /** 18801 * xmlSchemaCheckFacetValues: 18802 * @typeDecl: the schema type definition 18803 * @ctxt: the schema parser context 18804 * 18805 * Checks the default values types, especially for facets 18806 */ 18807 static int 18808 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18809 xmlSchemaParserCtxtPtr pctxt) 18810 { 18811 int res, olderrs = pctxt->nberrors; 18812 const xmlChar *name = typeDecl->name; 18813 /* 18814 * NOTE: It is intended to use the facets list, instead 18815 * of facetSet. 18816 */ 18817 if (typeDecl->facets != NULL) { 18818 xmlSchemaFacetPtr facet = typeDecl->facets; 18819 18820 /* 18821 * Temporarily assign the "schema" to the validation context 18822 * of the parser context. This is needed for NOTATION validation. 18823 */ 18824 if (pctxt->vctxt == NULL) { 18825 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18826 return(-1); 18827 } 18828 pctxt->vctxt->schema = pctxt->schema; 18829 while (facet != NULL) { 18830 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18831 HFAILURE 18832 facet = facet->next; 18833 } 18834 pctxt->vctxt->schema = NULL; 18835 } 18836 if (olderrs != pctxt->nberrors) 18837 return(pctxt->err); 18838 return(0); 18839 exit_failure: 18840 return(-1); 18841 } 18842 18843 /** 18844 * xmlSchemaGetCircModelGrDefRef: 18845 * @ctxtMGroup: the searched model group 18846 * @selfMGroup: the second searched model group 18847 * @particle: the first particle 18848 * 18849 * This one is intended to be used by 18850 * xmlSchemaCheckGroupDefCircular only. 18851 * 18852 * Returns the particle with the circular model group definition reference, 18853 * otherwise NULL. 18854 */ 18855 static xmlSchemaTreeItemPtr 18856 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18857 xmlSchemaTreeItemPtr particle) 18858 { 18859 xmlSchemaTreeItemPtr circ = NULL; 18860 xmlSchemaTreeItemPtr term; 18861 xmlSchemaModelGroupDefPtr gdef; 18862 18863 for (; particle != NULL; particle = particle->next) { 18864 term = particle->children; 18865 if (term == NULL) 18866 continue; 18867 switch (term->type) { 18868 case XML_SCHEMA_TYPE_GROUP: 18869 gdef = (xmlSchemaModelGroupDefPtr) term; 18870 if (gdef == groupDef) 18871 return (particle); 18872 /* 18873 * Mark this model group definition to avoid infinite 18874 * recursion on circular references not yet examined. 18875 */ 18876 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18877 continue; 18878 if (gdef->children != NULL) { 18879 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18880 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18881 gdef->children->children); 18882 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18883 if (circ != NULL) 18884 return (circ); 18885 } 18886 break; 18887 case XML_SCHEMA_TYPE_SEQUENCE: 18888 case XML_SCHEMA_TYPE_CHOICE: 18889 case XML_SCHEMA_TYPE_ALL: 18890 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18891 if (circ != NULL) 18892 return (circ); 18893 break; 18894 default: 18895 break; 18896 } 18897 } 18898 return (NULL); 18899 } 18900 18901 /** 18902 * xmlSchemaCheckGroupDefCircular: 18903 * @item: the model group definition 18904 * @ctxt: the parser context 18905 * @name: the name 18906 * 18907 * Checks for circular references to model group definitions. 18908 */ 18909 static void 18910 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18911 xmlSchemaParserCtxtPtr ctxt) 18912 { 18913 /* 18914 * Schema Component Constraint: Model Group Correct 18915 * 2 Circular groups are disallowed. That is, within the {particles} 18916 * of a group there must not be at any depth a particle whose {term} 18917 * is the group itself. 18918 */ 18919 if ((item == NULL) || 18920 (item->type != XML_SCHEMA_TYPE_GROUP) || 18921 (item->children == NULL)) 18922 return; 18923 { 18924 xmlSchemaTreeItemPtr circ; 18925 18926 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18927 if (circ != NULL) { 18928 xmlChar *str = NULL; 18929 /* 18930 * TODO: The error report is not adequate: this constraint 18931 * is defined for model groups but not definitions, but since 18932 * there cannot be any circular model groups without a model group 18933 * definition (if not using a construction API), we check those 18934 * defintions only. 18935 */ 18936 xmlSchemaPCustomErr(ctxt, 18937 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18938 NULL, WXS_ITEM_NODE(circ), 18939 "Circular reference to the model group definition '%s' " 18940 "defined", xmlSchemaFormatQName(&str, 18941 item->targetNamespace, item->name)); 18942 FREE_AND_NULL(str) 18943 /* 18944 * NOTE: We will cut the reference to avoid further 18945 * confusion of the processor. This is a fatal error. 18946 */ 18947 circ->children = NULL; 18948 } 18949 } 18950 } 18951 18952 /** 18953 * xmlSchemaModelGroupToModelGroupDefFixup: 18954 * @ctxt: the parser context 18955 * @mg: the model group 18956 * 18957 * Assigns the model group of model group definitions to the "term" 18958 * of the referencing particle. 18959 * In xmlSchemaResolveModelGroupParticleReferences the model group 18960 * definitions were assigned to the "term", since needed for the 18961 * circularity check. 18962 * 18963 * Schema Component Constraint: 18964 * All Group Limited (cos-all-limited) (1.2) 18965 */ 18966 static void 18967 xmlSchemaModelGroupToModelGroupDefFixup( 18968 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 18969 xmlSchemaModelGroupPtr mg) 18970 { 18971 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 18972 18973 while (particle != NULL) { 18974 if ((WXS_PARTICLE_TERM(particle) == NULL) || 18975 ((WXS_PARTICLE_TERM(particle))->type != 18976 XML_SCHEMA_TYPE_GROUP)) 18977 { 18978 particle = WXS_PTC_CAST particle->next; 18979 continue; 18980 } 18981 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 18982 /* 18983 * TODO: Remove the particle. 18984 */ 18985 WXS_PARTICLE_TERM(particle) = NULL; 18986 particle = WXS_PTC_CAST particle->next; 18987 continue; 18988 } 18989 /* 18990 * Assign the model group to the {term} of the particle. 18991 */ 18992 WXS_PARTICLE_TERM(particle) = 18993 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 18994 18995 particle = WXS_PTC_CAST particle->next; 18996 } 18997 } 18998 18999 /** 19000 * xmlSchemaCheckAttrGroupCircularRecur: 19001 * @ctxtGr: the searched attribute group 19002 * @attr: the current attribute list to be processed 19003 * 19004 * This one is intended to be used by 19005 * xmlSchemaCheckAttrGroupCircular only. 19006 * 19007 * Returns the circular attribute grou reference, otherwise NULL. 19008 */ 19009 static xmlSchemaQNameRefPtr 19010 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19011 xmlSchemaItemListPtr list) 19012 { 19013 xmlSchemaAttributeGroupPtr gr; 19014 xmlSchemaQNameRefPtr ref, circ; 19015 int i; 19016 /* 19017 * We will search for an attribute group reference which 19018 * references the context attribute group. 19019 */ 19020 for (i = 0; i < list->nbItems; i++) { 19021 ref = list->items[i]; 19022 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19023 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19024 (ref->item != NULL)) 19025 { 19026 gr = WXS_ATTR_GROUP_CAST ref->item; 19027 if (gr == ctxtGr) 19028 return(ref); 19029 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19030 continue; 19031 /* 19032 * Mark as visited to avoid infinite recursion on 19033 * circular references not yet examined. 19034 */ 19035 if ((gr->attrUses) && 19036 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19037 { 19038 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19039 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19040 (xmlSchemaItemListPtr) gr->attrUses); 19041 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19042 if (circ != NULL) 19043 return (circ); 19044 } 19045 19046 } 19047 } 19048 return (NULL); 19049 } 19050 19051 /** 19052 * xmlSchemaCheckAttrGroupCircular: 19053 * attrGr: the attribute group definition 19054 * @ctxt: the parser context 19055 * @name: the name 19056 * 19057 * Checks for circular references of attribute groups. 19058 */ 19059 static int 19060 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19061 xmlSchemaParserCtxtPtr ctxt) 19062 { 19063 /* 19064 * Schema Representation Constraint: 19065 * Attribute Group Definition Representation OK 19066 * 3 Circular group reference is disallowed outside <redefine>. 19067 * That is, unless this element information item's parent is 19068 * <redefine>, then among the [children], if any, there must 19069 * not be an <attributeGroup> with ref [attribute] which resolves 19070 * to the component corresponding to this <attributeGroup>. Indirect 19071 * circularity is also ruled out. That is, when QName resolution 19072 * (Schema Document) (3.15.3) is applied to a QName arising from 19073 * any <attributeGroup>s with a ref [attribute] among the [children], 19074 * it must not be the case that a QName is encountered at any depth 19075 * which resolves to the component corresponding to this <attributeGroup>. 19076 */ 19077 if (attrGr->attrUses == NULL) 19078 return(0); 19079 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19080 return(0); 19081 else { 19082 xmlSchemaQNameRefPtr circ; 19083 19084 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19085 (xmlSchemaItemListPtr) attrGr->attrUses); 19086 if (circ != NULL) { 19087 xmlChar *str = NULL; 19088 /* 19089 * TODO: Report the referenced attr group as QName. 19090 */ 19091 xmlSchemaPCustomErr(ctxt, 19092 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19093 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19094 "Circular reference to the attribute group '%s' " 19095 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19096 FREE_AND_NULL(str); 19097 /* 19098 * NOTE: We will cut the reference to avoid further 19099 * confusion of the processor. 19100 * BADSPEC TODO: The spec should define how to process in this case. 19101 */ 19102 circ->item = NULL; 19103 return(ctxt->err); 19104 } 19105 } 19106 return(0); 19107 } 19108 19109 static int 19110 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19111 xmlSchemaAttributeGroupPtr attrGr); 19112 19113 /** 19114 * xmlSchemaExpandAttributeGroupRefs: 19115 * @pctxt: the parser context 19116 * @node: the node of the component holding the attribute uses 19117 * @completeWild: the intersected wildcard to be returned 19118 * @list: the attribute uses 19119 * 19120 * Substitutes contained attribute group references 19121 * for their attribute uses. Wilcards are intersected. 19122 * Attribute use prohibitions are removed from the list 19123 * and returned via the @prohibs list. 19124 * Pointlessness of attr. prohibs, if a matching attr. decl 19125 * is existent a well, are checked. 19126 */ 19127 static int 19128 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19129 xmlSchemaBasicItemPtr item, 19130 xmlSchemaWildcardPtr *completeWild, 19131 xmlSchemaItemListPtr list, 19132 xmlSchemaItemListPtr prohibs) 19133 { 19134 xmlSchemaAttributeGroupPtr gr; 19135 xmlSchemaAttributeUsePtr use; 19136 xmlSchemaItemListPtr sublist; 19137 int i, j; 19138 int created = (*completeWild == NULL) ? 0 : 1; 19139 19140 if (prohibs) 19141 prohibs->nbItems = 0; 19142 19143 for (i = 0; i < list->nbItems; i++) { 19144 use = list->items[i]; 19145 19146 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19147 if (prohibs == NULL) { 19148 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19149 "unexpected attr prohibition found"); 19150 return(-1); 19151 } 19152 /* 19153 * Remove from attribute uses. 19154 */ 19155 if (xmlSchemaItemListRemove(list, i) == -1) 19156 return(-1); 19157 i--; 19158 /* 19159 * Note that duplicate prohibitions were already 19160 * handled at parsing time. 19161 */ 19162 /* 19163 * Add to list of prohibitions. 19164 */ 19165 xmlSchemaItemListAddSize(prohibs, 2, use); 19166 continue; 19167 } 19168 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19169 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19170 { 19171 if ((WXS_QNAME_CAST use)->item == NULL) 19172 return(-1); 19173 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19174 /* 19175 * Expand the referenced attr. group. 19176 * TODO: remove this, this is done in a previous step, so 19177 * already done here. 19178 */ 19179 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19180 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19181 return(-1); 19182 } 19183 /* 19184 * Build the 'complete' wildcard; i.e. intersect multiple 19185 * wildcards. 19186 */ 19187 if (gr->attributeWildcard != NULL) { 19188 if (*completeWild == NULL) { 19189 *completeWild = gr->attributeWildcard; 19190 } else { 19191 if (! created) { 19192 xmlSchemaWildcardPtr tmpWild; 19193 19194 /* 19195 * Copy the first encountered wildcard as context, 19196 * except for the annotation. 19197 * 19198 * Although the complete wildcard might not correspond 19199 * to any node in the schema, we will anchor it on 19200 * the node of the owner component. 19201 */ 19202 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19203 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19204 WXS_ITEM_NODE(item)); 19205 if (tmpWild == NULL) 19206 return(-1); 19207 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19208 tmpWild, *completeWild) == -1) 19209 return (-1); 19210 tmpWild->processContents = (*completeWild)->processContents; 19211 *completeWild = tmpWild; 19212 created = 1; 19213 } 19214 19215 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19216 gr->attributeWildcard) == -1) 19217 return(-1); 19218 } 19219 } 19220 /* 19221 * Just remove the reference if the referenced group does not 19222 * contain any attribute uses. 19223 */ 19224 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19225 if ((sublist == NULL) || sublist->nbItems == 0) { 19226 if (xmlSchemaItemListRemove(list, i) == -1) 19227 return(-1); 19228 i--; 19229 continue; 19230 } 19231 /* 19232 * Add the attribute uses. 19233 */ 19234 list->items[i] = sublist->items[0]; 19235 if (sublist->nbItems != 1) { 19236 for (j = 1; j < sublist->nbItems; j++) { 19237 i++; 19238 if (xmlSchemaItemListInsert(list, 19239 sublist->items[j], i) == -1) 19240 return(-1); 19241 } 19242 } 19243 } 19244 19245 } 19246 /* 19247 * Handle pointless prohibitions of declared attributes. 19248 */ 19249 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19250 xmlSchemaAttributeUseProhibPtr prohib; 19251 19252 for (i = prohibs->nbItems -1; i >= 0; i--) { 19253 prohib = prohibs->items[i]; 19254 for (j = 0; j < list->nbItems; j++) { 19255 use = list->items[j]; 19256 19257 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19258 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19259 { 19260 xmlChar *str = NULL; 19261 19262 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19263 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19264 prohib->node, NULL, 19265 "Skipping pointless attribute use prohibition " 19266 "'%s', since a corresponding attribute use " 19267 "exists already in the type definition", 19268 xmlSchemaFormatQName(&str, 19269 prohib->targetNamespace, prohib->name), 19270 NULL, NULL); 19271 FREE_AND_NULL(str); 19272 /* 19273 * Remove the prohibition. 19274 */ 19275 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19276 return(-1); 19277 break; 19278 } 19279 } 19280 } 19281 } 19282 return(0); 19283 } 19284 19285 /** 19286 * xmlSchemaAttributeGroupExpandRefs: 19287 * @pctxt: the parser context 19288 * @attrGr: the attribute group definition 19289 * 19290 * Computation of: 19291 * {attribute uses} property 19292 * {attribute wildcard} property 19293 * 19294 * Substitutes contained attribute group references 19295 * for their attribute uses. Wilcards are intersected. 19296 */ 19297 static int 19298 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19299 xmlSchemaAttributeGroupPtr attrGr) 19300 { 19301 if ((attrGr->attrUses == NULL) || 19302 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19303 return(0); 19304 19305 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19306 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19307 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19308 return(-1); 19309 return(0); 19310 } 19311 19312 /** 19313 * xmlSchemaAttributeGroupExpandRefs: 19314 * @pctxt: the parser context 19315 * @attrGr: the attribute group definition 19316 * 19317 * Substitutes contained attribute group references 19318 * for their attribute uses. Wilcards are intersected. 19319 * 19320 * Schema Component Constraint: 19321 * Attribute Group Definition Properties Correct (ag-props-correct) 19322 */ 19323 static int 19324 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19325 xmlSchemaAttributeGroupPtr attrGr) 19326 { 19327 /* 19328 * SPEC ag-props-correct 19329 * (1) "The values of the properties of an attribute group definition 19330 * must be as described in the property tableau in The Attribute 19331 * Group Definition Schema Component (3.6.1), modulo the impact of 19332 * Missing Sub-components (5.3);" 19333 */ 19334 19335 if ((attrGr->attrUses != NULL) && 19336 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19337 { 19338 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19339 xmlSchemaAttributeUsePtr use, tmp; 19340 int i, j, hasId = 0; 19341 19342 for (i = uses->nbItems -1; i >= 0; i--) { 19343 use = uses->items[i]; 19344 /* 19345 * SPEC ag-props-correct 19346 * (2) "Two distinct members of the {attribute uses} must not have 19347 * {attribute declaration}s both of whose {name}s match and whose 19348 * {target namespace}s are identical." 19349 */ 19350 if (i > 0) { 19351 for (j = i -1; j >= 0; j--) { 19352 tmp = uses->items[j]; 19353 if ((WXS_ATTRUSE_DECL_NAME(use) == 19354 WXS_ATTRUSE_DECL_NAME(tmp)) && 19355 (WXS_ATTRUSE_DECL_TNS(use) == 19356 WXS_ATTRUSE_DECL_TNS(tmp))) 19357 { 19358 xmlChar *str = NULL; 19359 19360 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19361 XML_SCHEMAP_AG_PROPS_CORRECT, 19362 attrGr->node, WXS_BASIC_CAST attrGr, 19363 "Duplicate %s", 19364 xmlSchemaGetComponentDesignation(&str, use), 19365 NULL); 19366 FREE_AND_NULL(str); 19367 /* 19368 * Remove the duplicate. 19369 */ 19370 if (xmlSchemaItemListRemove(uses, i) == -1) 19371 return(-1); 19372 goto next_use; 19373 } 19374 } 19375 } 19376 /* 19377 * SPEC ag-props-correct 19378 * (3) "Two distinct members of the {attribute uses} must not have 19379 * {attribute declaration}s both of whose {type definition}s are or 19380 * are derived from ID." 19381 * TODO: Does 'derived' include member-types of unions? 19382 */ 19383 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19384 if (xmlSchemaIsDerivedFromBuiltInType( 19385 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19386 { 19387 if (hasId) { 19388 xmlChar *str = NULL; 19389 19390 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19391 XML_SCHEMAP_AG_PROPS_CORRECT, 19392 attrGr->node, WXS_BASIC_CAST attrGr, 19393 "There must not exist more than one attribute " 19394 "declaration of type 'xs:ID' " 19395 "(or derived from 'xs:ID'). The %s violates this " 19396 "constraint", 19397 xmlSchemaGetComponentDesignation(&str, use), 19398 NULL); 19399 FREE_AND_NULL(str); 19400 if (xmlSchemaItemListRemove(uses, i) == -1) 19401 return(-1); 19402 } 19403 hasId = 1; 19404 } 19405 } 19406 next_use: {} 19407 } 19408 } 19409 return(0); 19410 } 19411 19412 /** 19413 * xmlSchemaResolveAttrGroupReferences: 19414 * @attrgrpDecl: the schema attribute definition 19415 * @ctxt: the schema parser context 19416 * @name: the attribute name 19417 * 19418 * Resolves references to attribute group definitions. 19419 */ 19420 static int 19421 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19422 xmlSchemaParserCtxtPtr ctxt) 19423 { 19424 xmlSchemaAttributeGroupPtr group; 19425 19426 if (ref->item != NULL) 19427 return(0); 19428 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19429 ref->name, 19430 ref->targetNamespace); 19431 if (group == NULL) { 19432 xmlSchemaPResCompAttrErr(ctxt, 19433 XML_SCHEMAP_SRC_RESOLVE, 19434 NULL, ref->node, 19435 "ref", ref->name, ref->targetNamespace, 19436 ref->itemType, NULL); 19437 return(ctxt->err); 19438 } 19439 ref->item = WXS_BASIC_CAST group; 19440 return(0); 19441 } 19442 19443 /** 19444 * xmlSchemaCheckAttrPropsCorrect: 19445 * @item: an schema attribute declaration/use 19446 * @ctxt: a schema parser context 19447 * @name: the name of the attribute 19448 * 19449 * 19450 * Schema Component Constraint: 19451 * Attribute Declaration Properties Correct (a-props-correct) 19452 * 19453 * Validates the value constraints of an attribute declaration/use. 19454 * NOTE that this needs the simle type definitions to be already 19455 * builded and checked. 19456 */ 19457 static int 19458 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19459 xmlSchemaAttributePtr attr) 19460 { 19461 19462 /* 19463 * SPEC a-props-correct (1) 19464 * "The values of the properties of an attribute declaration must 19465 * be as described in the property tableau in The Attribute 19466 * Declaration Schema Component (3.2.1), modulo the impact of 19467 * Missing Sub-components (5.3)." 19468 */ 19469 19470 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19471 return(0); 19472 19473 if (attr->defValue != NULL) { 19474 int ret; 19475 19476 /* 19477 * SPEC a-props-correct (3) 19478 * "If the {type definition} is or is derived from ID then there 19479 * must not be a {value constraint}." 19480 */ 19481 if (xmlSchemaIsDerivedFromBuiltInType( 19482 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19483 { 19484 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19485 XML_SCHEMAP_A_PROPS_CORRECT_3, 19486 NULL, WXS_BASIC_CAST attr, 19487 "Value constraints are not allowed if the type definition " 19488 "is or is derived from xs:ID", 19489 NULL, NULL); 19490 return(pctxt->err); 19491 } 19492 /* 19493 * SPEC a-props-correct (2) 19494 * "if there is a {value constraint}, the canonical lexical 19495 * representation of its value must be valid with respect 19496 * to the {type definition} as defined in String Valid (3.14.4)." 19497 * TODO: Don't care about the *cononical* stuff here, this requirement 19498 * will be removed in WXS 1.1 anyway. 19499 */ 19500 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19501 attr->node, WXS_ATTR_TYPEDEF(attr), 19502 attr->defValue, &(attr->defVal), 19503 1, 1, 0); 19504 if (ret != 0) { 19505 if (ret < 0) { 19506 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19507 "calling xmlSchemaVCheckCVCSimpleType()"); 19508 return(-1); 19509 } 19510 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19511 XML_SCHEMAP_A_PROPS_CORRECT_2, 19512 NULL, WXS_BASIC_CAST attr, 19513 "The value of the value constraint is not valid", 19514 NULL, NULL); 19515 return(pctxt->err); 19516 } 19517 } 19518 19519 return(0); 19520 } 19521 19522 static xmlSchemaElementPtr 19523 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19524 xmlSchemaElementPtr ancestor) 19525 { 19526 xmlSchemaElementPtr ret; 19527 19528 if (WXS_SUBST_HEAD(ancestor) == NULL) 19529 return (NULL); 19530 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19531 return (ancestor); 19532 19533 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19534 return (NULL); 19535 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19536 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19537 WXS_SUBST_HEAD(ancestor)); 19538 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19539 19540 return (ret); 19541 } 19542 19543 /** 19544 * xmlSchemaCheckElemPropsCorrect: 19545 * @ctxt: a schema parser context 19546 * @decl: the element declaration 19547 * @name: the name of the attribute 19548 * 19549 * Schema Component Constraint: 19550 * Element Declaration Properties Correct (e-props-correct) 19551 * 19552 * STATUS: 19553 * missing: (6) 19554 */ 19555 static int 19556 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19557 xmlSchemaElementPtr elemDecl) 19558 { 19559 int ret = 0; 19560 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19561 /* 19562 * SPEC (1) "The values of the properties of an element declaration 19563 * must be as described in the property tableau in The Element 19564 * Declaration Schema Component (3.3.1), modulo the impact of Missing 19565 * Sub-components (5.3)." 19566 */ 19567 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19568 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19569 19570 xmlSchemaCheckElementDeclComponent(head, pctxt); 19571 /* 19572 * SPEC (3) "If there is a non-absent {substitution group 19573 * affiliation}, then {scope} must be global." 19574 */ 19575 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19576 xmlSchemaPCustomErr(pctxt, 19577 XML_SCHEMAP_E_PROPS_CORRECT_3, 19578 WXS_BASIC_CAST elemDecl, NULL, 19579 "Only global element declarations can have a " 19580 "substitution group affiliation", NULL); 19581 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19582 } 19583 /* 19584 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19585 * That is, it must not be possible to return to an element declaration 19586 * by repeatedly following the {substitution group affiliation} 19587 * property." 19588 */ 19589 if (head == elemDecl) 19590 circ = head; 19591 else if (WXS_SUBST_HEAD(head) != NULL) 19592 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19593 else 19594 circ = NULL; 19595 if (circ != NULL) { 19596 xmlChar *strA = NULL, *strB = NULL; 19597 19598 xmlSchemaPCustomErrExt(pctxt, 19599 XML_SCHEMAP_E_PROPS_CORRECT_6, 19600 WXS_BASIC_CAST circ, NULL, 19601 "The element declaration '%s' defines a circular " 19602 "substitution group to element declaration '%s'", 19603 xmlSchemaGetComponentQName(&strA, circ), 19604 xmlSchemaGetComponentQName(&strB, head), 19605 NULL); 19606 FREE_AND_NULL(strA) 19607 FREE_AND_NULL(strB) 19608 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19609 } 19610 /* 19611 * SPEC (4) "If there is a {substitution group affiliation}, 19612 * the {type definition} 19613 * of the element declaration must be validly derived from the {type 19614 * definition} of the {substitution group affiliation}, given the value 19615 * of the {substitution group exclusions} of the {substitution group 19616 * affiliation}, as defined in Type Derivation OK (Complex) (3.4.6) 19617 * (if the {type definition} is complex) or as defined in 19618 * Type Derivation OK (Simple) (3.14.6) (if the {type definition} is 19619 * simple)." 19620 * 19621 * NOTE: {substitution group exclusions} means the values of the 19622 * attribute "final". 19623 */ 19624 19625 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19626 int set = 0; 19627 19628 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19629 set |= SUBSET_EXTENSION; 19630 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19631 set |= SUBSET_RESTRICTION; 19632 19633 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19634 WXS_ELEM_TYPEDEF(head), set) != 0) { 19635 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19636 19637 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19638 xmlSchemaPCustomErrExt(pctxt, 19639 XML_SCHEMAP_E_PROPS_CORRECT_4, 19640 WXS_BASIC_CAST elemDecl, NULL, 19641 "The type definition '%s' was " 19642 "either rejected by the substitution group " 19643 "affiliation '%s', or not validly derived from its type " 19644 "definition '%s'", 19645 xmlSchemaGetComponentQName(&strA, typeDef), 19646 xmlSchemaGetComponentQName(&strB, head), 19647 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19648 FREE_AND_NULL(strA) 19649 FREE_AND_NULL(strB) 19650 FREE_AND_NULL(strC) 19651 } 19652 } 19653 } 19654 /* 19655 * SPEC (5) "If the {type definition} or {type definition}'s 19656 * {content type} 19657 * is or is derived from ID then there must not be a {value constraint}. 19658 * Note: The use of ID as a type definition for elements goes beyond 19659 * XML 1.0, and should be avoided if backwards compatibility is desired" 19660 */ 19661 if ((elemDecl->value != NULL) && 19662 ((WXS_IS_SIMPLE(typeDef) && 19663 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19664 (WXS_IS_COMPLEX(typeDef) && 19665 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19666 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19667 XML_SCHEMAS_ID)))) { 19668 19669 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19670 xmlSchemaPCustomErr(pctxt, 19671 XML_SCHEMAP_E_PROPS_CORRECT_5, 19672 WXS_BASIC_CAST elemDecl, NULL, 19673 "The type definition (or type definition's content type) is or " 19674 "is derived from ID; value constraints are not allowed in " 19675 "conjunction with such a type definition", NULL); 19676 } else if (elemDecl->value != NULL) { 19677 int vcret; 19678 xmlNodePtr node = NULL; 19679 19680 /* 19681 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19682 * representation of its value must be valid with respect to the 19683 * {type definition} as defined in Element Default Valid (Immediate) 19684 * (3.3.6)." 19685 */ 19686 if (typeDef == NULL) { 19687 xmlSchemaPErr(pctxt, elemDecl->node, 19688 XML_SCHEMAP_INTERNAL, 19689 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19690 "type is missing... skipping validation of " 19691 "the value constraint", NULL, NULL); 19692 return (-1); 19693 } 19694 if (elemDecl->node != NULL) { 19695 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19696 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19697 BAD_CAST "fixed"); 19698 else 19699 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19700 BAD_CAST "default"); 19701 } 19702 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19703 typeDef, elemDecl->value, &(elemDecl->defVal)); 19704 if (vcret != 0) { 19705 if (vcret < 0) { 19706 PERROR_INT("xmlSchemaElemCheckValConstr", 19707 "failed to validate the value constraint of an " 19708 "element declaration"); 19709 return (-1); 19710 } 19711 return (vcret); 19712 } 19713 } 19714 19715 return (ret); 19716 } 19717 19718 /** 19719 * xmlSchemaCheckElemSubstGroup: 19720 * @ctxt: a schema parser context 19721 * @decl: the element declaration 19722 * @name: the name of the attribute 19723 * 19724 * Schema Component Constraint: 19725 * Substitution Group (cos-equiv-class) 19726 * 19727 * In Libxml2 the subst. groups will be precomputed, in terms of that 19728 * a list will be built for each subst. group head, holding all direct 19729 * referents to this head. 19730 * NOTE that this function needs: 19731 * 1. circular subst. groups to be checked beforehand 19732 * 2. the declaration's type to be derived from the head's type 19733 * 19734 * STATUS: 19735 * 19736 */ 19737 static void 19738 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19739 xmlSchemaElementPtr elemDecl) 19740 { 19741 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19742 /* SPEC (1) "Its {abstract} is false." */ 19743 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19744 return; 19745 { 19746 xmlSchemaElementPtr head; 19747 xmlSchemaTypePtr headType, type; 19748 int set, methSet; 19749 /* 19750 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19751 * {disallowed substitutions} as the blocking constraint, as defined in 19752 * Substitution Group OK (Transitive) (3.3.6)." 19753 */ 19754 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19755 head = WXS_SUBST_HEAD(head)) { 19756 set = 0; 19757 methSet = 0; 19758 /* 19759 * The blocking constraints. 19760 */ 19761 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19762 continue; 19763 headType = head->subtypes; 19764 type = elemDecl->subtypes; 19765 if (headType == type) 19766 goto add_member; 19767 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19768 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19769 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19770 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19771 /* 19772 * SPEC: Substitution Group OK (Transitive) (2.3) 19773 * "The set of all {derivation method}s involved in the 19774 * derivation of D's {type definition} from C's {type definition} 19775 * does not intersect with the union of the blocking constraint, 19776 * C's {prohibited substitutions} (if C is complex, otherwise the 19777 * empty set) and the {prohibited substitutions} (respectively the 19778 * empty set) of any intermediate {type definition}s in the 19779 * derivation of D's {type definition} from C's {type definition}." 19780 */ 19781 /* 19782 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19783 * subst.head axis, the methSet does not need to be computed for 19784 * the full depth over and over. 19785 */ 19786 /* 19787 * The set of all {derivation method}s involved in the derivation 19788 */ 19789 while ((type != NULL) && (type != headType)) { 19790 if ((WXS_IS_EXTENSION(type)) && 19791 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19792 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19793 19794 if (WXS_IS_RESTRICTION(type) && 19795 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19796 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19797 19798 type = type->baseType; 19799 } 19800 /* 19801 * The {prohibited substitutions} of all intermediate types + 19802 * the head's type. 19803 */ 19804 type = elemDecl->subtypes->baseType; 19805 while (type != NULL) { 19806 if (WXS_IS_COMPLEX(type)) { 19807 if ((type->flags & 19808 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19809 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19810 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19811 if ((type->flags & 19812 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19813 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19814 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19815 } else 19816 break; 19817 if (type == headType) 19818 break; 19819 type = type->baseType; 19820 } 19821 if ((set != 0) && 19822 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19823 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19824 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19825 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19826 continue; 19827 } 19828 add_member: 19829 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19830 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19831 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19832 } 19833 } 19834 } 19835 19836 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19837 /** 19838 * xmlSchemaCheckElementDeclComponent 19839 * @pctxt: the schema parser context 19840 * @ctxtComponent: the context component (an element declaration) 19841 * @ctxtParticle: the first particle of the context component 19842 * @searchParticle: the element declaration particle to be analysed 19843 * 19844 * Schema Component Constraint: Element Declarations Consistent 19845 */ 19846 static int 19847 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19848 xmlSchemaBasicItemPtr ctxtComponent, 19849 xmlSchemaParticlePtr ctxtParticle, 19850 xmlSchemaParticlePtr searchParticle, 19851 xmlSchemaParticlePtr curParticle, 19852 int search) 19853 { 19854 return(0); 19855 19856 int ret = 0; 19857 xmlSchemaParticlePtr cur = curParticle; 19858 if (curParticle == NULL) { 19859 return(0); 19860 } 19861 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19862 /* 19863 * Just return in this case. A missing "term" of the particle 19864 * might arise due to an invalid "term" component. 19865 */ 19866 return(0); 19867 } 19868 while (cur != NULL) { 19869 switch (WXS_PARTICLE_TERM(cur)->type) { 19870 case XML_SCHEMA_TYPE_ANY: 19871 break; 19872 case XML_SCHEMA_TYPE_ELEMENT: 19873 if (search == 0) { 19874 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19875 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19876 if (ret != 0) 19877 return(ret); 19878 } else { 19879 xmlSchemaElementPtr elem = 19880 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19881 /* 19882 * SPEC Element Declarations Consistent: 19883 * "If the {particles} contains, either directly, 19884 * indirectly (that is, within the {particles} of a 19885 * contained model group, recursively) or implicitly 19886 * two or more element declaration particles with 19887 * the same {name} and {target namespace}, then 19888 * all their type definitions must be the same 19889 * top-level definition [...]" 19890 */ 19891 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19892 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19893 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19894 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19895 { 19896 xmlChar *strA = NULL, *strB = NULL; 19897 19898 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19899 /* TODO: error code */ 19900 XML_SCHEMAP_COS_NONAMBIG, 19901 WXS_ITEM_NODE(cur), NULL, 19902 "In the content model of %s, there are multiple " 19903 "element declarations for '%s' with different " 19904 "type definitions", 19905 xmlSchemaGetComponentDesignation(&strA, 19906 ctxtComponent), 19907 xmlSchemaFormatQName(&strB, 19908 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19909 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19910 FREE_AND_NULL(strA); 19911 FREE_AND_NULL(strB); 19912 return(XML_SCHEMAP_COS_NONAMBIG); 19913 } 19914 } 19915 break; 19916 case XML_SCHEMA_TYPE_SEQUENCE: { 19917 break; 19918 } 19919 case XML_SCHEMA_TYPE_CHOICE:{ 19920 /* 19921 xmlSchemaTreeItemPtr sub; 19922 19923 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19924 while (sub != NULL) { 19925 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19926 ctxtParticle, ctxtElem); 19927 if (ret != 0) 19928 return(ret); 19929 sub = sub->next; 19930 } 19931 */ 19932 break; 19933 } 19934 case XML_SCHEMA_TYPE_ALL: 19935 break; 19936 case XML_SCHEMA_TYPE_GROUP: 19937 break; 19938 default: 19939 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19940 "xmlSchemaCheckElementDeclConsistent", 19941 "found unexpected term of type '%s' in content model", 19942 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19943 return(-1); 19944 } 19945 cur = (xmlSchemaParticlePtr) cur->next; 19946 } 19947 19948 exit: 19949 return(ret); 19950 } 19951 #endif 19952 19953 /** 19954 * xmlSchemaCheckElementDeclComponent 19955 * @item: an schema element declaration/particle 19956 * @ctxt: a schema parser context 19957 * @name: the name of the attribute 19958 * 19959 * Validates the value constraints of an element declaration. 19960 * Adds substitution group members. 19961 */ 19962 static void 19963 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 19964 xmlSchemaParserCtxtPtr ctxt) 19965 { 19966 if (elemDecl == NULL) 19967 return; 19968 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 19969 return; 19970 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 19971 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 19972 /* 19973 * Adds substitution group members. 19974 */ 19975 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 19976 } 19977 } 19978 19979 /** 19980 * xmlSchemaResolveModelGroupParticleReferences: 19981 * @particle: a particle component 19982 * @ctxt: a parser context 19983 * 19984 * Resolves references of a model group's {particles} to 19985 * model group definitions and to element declarations. 19986 */ 19987 static void 19988 xmlSchemaResolveModelGroupParticleReferences( 19989 xmlSchemaParserCtxtPtr ctxt, 19990 xmlSchemaModelGroupPtr mg) 19991 { 19992 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19993 xmlSchemaQNameRefPtr ref; 19994 xmlSchemaBasicItemPtr refItem; 19995 19996 /* 19997 * URGENT TODO: Test this. 19998 */ 19999 while (particle != NULL) { 20000 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20001 ((WXS_PARTICLE_TERM(particle))->type != 20002 XML_SCHEMA_EXTRA_QNAMEREF)) 20003 { 20004 goto next_particle; 20005 } 20006 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20007 /* 20008 * Resolve the reference. 20009 * NULL the {term} by default. 20010 */ 20011 particle->children = NULL; 20012 20013 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20014 ref->itemType, ref->name, ref->targetNamespace); 20015 if (refItem == NULL) { 20016 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20017 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20018 ref->targetNamespace, ref->itemType, NULL); 20019 /* TODO: remove the particle. */ 20020 goto next_particle; 20021 } 20022 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20023 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20024 /* TODO: remove the particle. */ 20025 goto next_particle; 20026 /* 20027 * NOTE that we will assign the model group definition 20028 * itself to the "term" of the particle. This will ease 20029 * the check for circular model group definitions. After 20030 * that the "term" will be assigned the model group of the 20031 * model group definition. 20032 */ 20033 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20034 XML_SCHEMA_TYPE_ALL) { 20035 /* 20036 * SPEC cos-all-limited (1) 20037 * SPEC cos-all-limited (1.2) 20038 * "It appears only as the value of one or both of the 20039 * following properties:" 20040 * (1.1) "the {model group} property of a model group 20041 * definition." 20042 * (1.2) "the {term} property of a particle [... of] the " 20043 * {content type} of a complex type definition." 20044 */ 20045 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20046 /* TODO: error code */ 20047 XML_SCHEMAP_COS_ALL_LIMITED, 20048 WXS_ITEM_NODE(particle), NULL, 20049 "A model group definition is referenced, but " 20050 "it contains an 'all' model group, which " 20051 "cannot be contained by model groups", 20052 NULL, NULL); 20053 /* TODO: remove the particle. */ 20054 goto next_particle; 20055 } 20056 particle->children = (xmlSchemaTreeItemPtr) refItem; 20057 } else { 20058 /* 20059 * TODO: Are referenced element declarations the only 20060 * other components we expect here? 20061 */ 20062 particle->children = (xmlSchemaTreeItemPtr) refItem; 20063 } 20064 next_particle: 20065 particle = WXS_PTC_CAST particle->next; 20066 } 20067 } 20068 20069 static int 20070 xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20071 xmlSchemaValPtr y) 20072 { 20073 xmlSchemaTypePtr tx, ty, ptx, pty; 20074 int ret; 20075 20076 while (x != NULL) { 20077 /* Same types. */ 20078 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20079 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20080 ptx = xmlSchemaGetPrimitiveType(tx); 20081 pty = xmlSchemaGetPrimitiveType(ty); 20082 /* 20083 * (1) if a datatype T' is derived by restriction from an 20084 * atomic datatype T then the value space of T' is a subset of 20085 * the value space of T. */ 20086 /* 20087 * (2) if datatypes T' and T'' are derived by restriction 20088 * from a common atomic ancestor T then the value spaces of T' 20089 * and T'' may overlap. 20090 */ 20091 if (ptx != pty) 20092 return(0); 20093 /* 20094 * We assume computed values to be normalized, so do a fast 20095 * string comparison for string based types. 20096 */ 20097 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20098 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20099 if (! xmlStrEqual( 20100 xmlSchemaValueGetAsString(x), 20101 xmlSchemaValueGetAsString(y))) 20102 return (0); 20103 } else { 20104 ret = xmlSchemaCompareValuesWhtsp( 20105 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20106 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20107 if (ret == -2) 20108 return(-1); 20109 if (ret != 0) 20110 return(0); 20111 } 20112 /* 20113 * Lists. 20114 */ 20115 x = xmlSchemaValueGetNext(x); 20116 if (x != NULL) { 20117 y = xmlSchemaValueGetNext(y); 20118 if (y == NULL) 20119 return (0); 20120 } else if (xmlSchemaValueGetNext(y) != NULL) 20121 return (0); 20122 else 20123 return (1); 20124 } 20125 return (0); 20126 } 20127 20128 /** 20129 * xmlSchemaResolveAttrUseReferences: 20130 * @item: an attribute use 20131 * @ctxt: a parser context 20132 * 20133 * Resolves the referenced attribute declaration. 20134 */ 20135 static int 20136 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20137 xmlSchemaParserCtxtPtr ctxt) 20138 { 20139 if ((ctxt == NULL) || (ause == NULL)) 20140 return(-1); 20141 if ((ause->attrDecl == NULL) || 20142 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20143 return(0); 20144 20145 { 20146 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20147 20148 /* 20149 * TODO: Evaluate, what errors could occur if the declaration is not 20150 * found. 20151 */ 20152 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20153 ref->name, ref->targetNamespace); 20154 if (ause->attrDecl == NULL) { 20155 xmlSchemaPResCompAttrErr(ctxt, 20156 XML_SCHEMAP_SRC_RESOLVE, 20157 WXS_BASIC_CAST ause, ause->node, 20158 "ref", ref->name, ref->targetNamespace, 20159 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20160 return(ctxt->err);; 20161 } 20162 } 20163 return(0); 20164 } 20165 20166 /** 20167 * xmlSchemaCheckAttrUsePropsCorrect: 20168 * @ctxt: a parser context 20169 * @use: an attribute use 20170 * 20171 * Schema Component Constraint: 20172 * Attribute Use Correct (au-props-correct) 20173 * 20174 */ 20175 static int 20176 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20177 xmlSchemaAttributeUsePtr use) 20178 { 20179 if ((ctxt == NULL) || (use == NULL)) 20180 return(-1); 20181 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20182 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20183 return(0); 20184 20185 /* 20186 * SPEC au-props-correct (1) 20187 * "The values of the properties of an attribute use must be as 20188 * described in the property tableau in The Attribute Use Schema 20189 * Component (3.5.1), modulo the impact of Missing 20190 * Sub-components (5.3)." 20191 */ 20192 20193 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20194 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20195 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20196 { 20197 xmlSchemaPCustomErr(ctxt, 20198 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20199 WXS_BASIC_CAST use, NULL, 20200 "The attribute declaration has a 'fixed' value constraint " 20201 ", thus the attribute use must also have a 'fixed' value " 20202 "constraint", 20203 NULL); 20204 return(ctxt->err); 20205 } 20206 /* 20207 * Compute and check the value constraint's value. 20208 */ 20209 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20210 int ret; 20211 /* 20212 * TODO: The spec seems to be missing a check of the 20213 * value constraint of the attribute use. We will do it here. 20214 */ 20215 /* 20216 * SPEC a-props-correct (3) 20217 */ 20218 if (xmlSchemaIsDerivedFromBuiltInType( 20219 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20220 { 20221 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20222 XML_SCHEMAP_AU_PROPS_CORRECT, 20223 NULL, WXS_BASIC_CAST use, 20224 "Value constraints are not allowed if the type definition " 20225 "is or is derived from xs:ID", 20226 NULL, NULL); 20227 return(ctxt->err); 20228 } 20229 20230 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20231 use->node, WXS_ATTRUSE_TYPEDEF(use), 20232 use->defValue, &(use->defVal), 20233 1, 1, 0); 20234 if (ret != 0) { 20235 if (ret < 0) { 20236 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20237 "calling xmlSchemaVCheckCVCSimpleType()"); 20238 return(-1); 20239 } 20240 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20241 XML_SCHEMAP_AU_PROPS_CORRECT, 20242 NULL, WXS_BASIC_CAST use, 20243 "The value of the value constraint is not valid", 20244 NULL, NULL); 20245 return(ctxt->err); 20246 } 20247 } 20248 /* 20249 * SPEC au-props-correct (2) 20250 * "If the {attribute declaration} has a fixed 20251 * {value constraint}, then if the attribute use itself has a 20252 * {value constraint}, it must also be fixed and its value must match 20253 * that of the {attribute declaration}'s {value constraint}." 20254 */ 20255 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20256 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20257 { 20258 if (! xmlSchemaAreValuesEqual(use->defVal, 20259 (WXS_ATTRUSE_DECL(use))->defVal)) 20260 { 20261 xmlSchemaPCustomErr(ctxt, 20262 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20263 WXS_BASIC_CAST use, NULL, 20264 "The 'fixed' value constraint of the attribute use " 20265 "must match the attribute declaration's value " 20266 "constraint '%s'", 20267 (WXS_ATTRUSE_DECL(use))->defValue); 20268 } 20269 return(ctxt->err); 20270 } 20271 return(0); 20272 } 20273 20274 20275 20276 20277 /** 20278 * xmlSchemaResolveAttrTypeReferences: 20279 * @item: an attribute declaration 20280 * @ctxt: a parser context 20281 * 20282 * Resolves the referenced type definition component. 20283 */ 20284 static int 20285 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20286 xmlSchemaParserCtxtPtr ctxt) 20287 { 20288 /* 20289 * The simple type definition corresponding to the <simpleType> element 20290 * information item in the [children], if present, otherwise the simple 20291 * type definition resolved to by the actual value of the type 20292 * [attribute], if present, otherwise the simple ur-type definition. 20293 */ 20294 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20295 return(0); 20296 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20297 if (item->subtypes != NULL) 20298 return(0); 20299 if (item->typeName != NULL) { 20300 xmlSchemaTypePtr type; 20301 20302 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20303 item->typeNs); 20304 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20305 xmlSchemaPResCompAttrErr(ctxt, 20306 XML_SCHEMAP_SRC_RESOLVE, 20307 WXS_BASIC_CAST item, item->node, 20308 "type", item->typeName, item->typeNs, 20309 XML_SCHEMA_TYPE_SIMPLE, NULL); 20310 return(ctxt->err); 20311 } else 20312 item->subtypes = type; 20313 20314 } else { 20315 /* 20316 * The type defaults to the xs:anySimpleType. 20317 */ 20318 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20319 } 20320 return(0); 20321 } 20322 20323 /** 20324 * xmlSchemaResolveIDCKeyReferences: 20325 * @idc: the identity-constraint definition 20326 * @ctxt: the schema parser context 20327 * @name: the attribute name 20328 * 20329 * Resolve keyRef references to key/unique IDCs. 20330 * Schema Component Constraint: 20331 * Identity-constraint Definition Properties Correct (c-props-correct) 20332 */ 20333 static int 20334 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20335 xmlSchemaParserCtxtPtr pctxt) 20336 { 20337 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20338 return(0); 20339 if (idc->ref->name != NULL) { 20340 idc->ref->item = (xmlSchemaBasicItemPtr) 20341 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20342 idc->ref->targetNamespace); 20343 if (idc->ref->item == NULL) { 20344 /* 20345 * TODO: It is actually not an error to fail to resolve 20346 * at this stage. BUT we need to be that strict! 20347 */ 20348 xmlSchemaPResCompAttrErr(pctxt, 20349 XML_SCHEMAP_SRC_RESOLVE, 20350 WXS_BASIC_CAST idc, idc->node, 20351 "refer", idc->ref->name, 20352 idc->ref->targetNamespace, 20353 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20354 return(pctxt->err); 20355 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20356 /* 20357 * SPEC c-props-correct (1) 20358 */ 20359 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20360 XML_SCHEMAP_C_PROPS_CORRECT, 20361 NULL, WXS_BASIC_CAST idc, 20362 "The keyref references a keyref", 20363 NULL, NULL); 20364 idc->ref->item = NULL; 20365 return(pctxt->err); 20366 } else { 20367 if (idc->nbFields != 20368 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20369 xmlChar *str = NULL; 20370 xmlSchemaIDCPtr refer; 20371 20372 refer = (xmlSchemaIDCPtr) idc->ref->item; 20373 /* 20374 * SPEC c-props-correct(2) 20375 * "If the {identity-constraint category} is keyref, 20376 * the cardinality of the {fields} must equal that of 20377 * the {fields} of the {referenced key}. 20378 */ 20379 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20380 XML_SCHEMAP_C_PROPS_CORRECT, 20381 NULL, WXS_BASIC_CAST idc, 20382 "The cardinality of the keyref differs from the " 20383 "cardinality of the referenced key/unique '%s'", 20384 xmlSchemaFormatQName(&str, refer->targetNamespace, 20385 refer->name), 20386 NULL); 20387 FREE_AND_NULL(str) 20388 return(pctxt->err); 20389 } 20390 } 20391 } 20392 return(0); 20393 } 20394 20395 static int 20396 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20397 xmlSchemaParserCtxtPtr pctxt) 20398 { 20399 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20400 prohib->targetNamespace) == NULL) { 20401 20402 xmlSchemaPResCompAttrErr(pctxt, 20403 XML_SCHEMAP_SRC_RESOLVE, 20404 NULL, prohib->node, 20405 "ref", prohib->name, prohib->targetNamespace, 20406 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20407 return(XML_SCHEMAP_SRC_RESOLVE); 20408 } 20409 return(0); 20410 } 20411 20412 #define WXS_REDEFINED_TYPE(c) \ 20413 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20414 20415 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20416 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20417 20418 #define WXS_REDEFINED_ATTR_GROUP(c) \ 20419 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20420 20421 static int 20422 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20423 { 20424 int err = 0; 20425 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20426 xmlSchemaBasicItemPtr prev, item; 20427 int wasRedefined; 20428 20429 if (redef == NULL) 20430 return(0); 20431 20432 do { 20433 item = redef->item; 20434 /* 20435 * First try to locate the redefined component in the 20436 * schema graph starting with the redefined schema. 20437 * NOTE: According to this schema bug entry: 20438 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20439 * it's not clear if the referenced component needs to originate 20440 * from the <redefine>d schema _document_ or the schema; the latter 20441 * would include all imported and included sub-schemas of the 20442 * <redefine>d schema. Currenlty we latter approach is used. 20443 * SUPPLEMENT: It seems that the WG moves towards the latter 20444 * approach, so we are doing it right. 20445 * 20446 */ 20447 prev = xmlSchemaFindRedefCompInGraph( 20448 redef->targetBucket, item->type, 20449 redef->refName, redef->refTargetNs); 20450 if (prev == NULL) { 20451 xmlChar *str = NULL; 20452 xmlNodePtr node; 20453 20454 /* 20455 * SPEC src-redefine: 20456 * (6.2.1) "The actual value of its own name attribute plus 20457 * target namespace must successfully resolve to a model 20458 * group definition in I." 20459 * (7.2.1) "The actual value of its own name attribute plus 20460 * target namespace must successfully resolve to an attribute 20461 * group definition in I." 20462 20463 * 20464 * Note that, if we are redefining with the use of references 20465 * to components, the spec assumes the src-resolve to be used; 20466 * but this won't assure that we search only *inside* the 20467 * redefined schema. 20468 */ 20469 if (redef->reference) 20470 node = WXS_ITEM_NODE(redef->reference); 20471 else 20472 node = WXS_ITEM_NODE(item); 20473 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20474 /* 20475 * TODO: error code. 20476 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20477 * reference kind. 20478 */ 20479 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20480 "The %s '%s' to be redefined could not be found in " 20481 "the redefined schema", 20482 WXS_ITEM_TYPE_NAME(item), 20483 xmlSchemaFormatQName(&str, redef->refTargetNs, 20484 redef->refName)); 20485 FREE_AND_NULL(str); 20486 err = pctxt->err; 20487 redef = redef->next; 20488 continue; 20489 } 20490 /* 20491 * TODO: Obtaining and setting the redefinition state is really 20492 * clumsy. 20493 */ 20494 wasRedefined = 0; 20495 switch (item->type) { 20496 case XML_SCHEMA_TYPE_COMPLEX: 20497 case XML_SCHEMA_TYPE_SIMPLE: 20498 if ((WXS_TYPE_CAST prev)->flags & 20499 XML_SCHEMAS_TYPE_REDEFINED) 20500 { 20501 wasRedefined = 1; 20502 break; 20503 } 20504 /* Mark it as redefined. */ 20505 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20506 /* 20507 * Assign the redefined type to the 20508 * base type of the redefining type. 20509 * TODO: How 20510 */ 20511 ((xmlSchemaTypePtr) item)->baseType = 20512 (xmlSchemaTypePtr) prev; 20513 break; 20514 case XML_SCHEMA_TYPE_GROUP: 20515 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20516 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20517 { 20518 wasRedefined = 1; 20519 break; 20520 } 20521 /* Mark it as redefined. */ 20522 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20523 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20524 if (redef->reference != NULL) { 20525 /* 20526 * Overwrite the QName-reference with the 20527 * referenced model group def. 20528 */ 20529 (WXS_PTC_CAST redef->reference)->children = 20530 WXS_TREE_CAST prev; 20531 } 20532 redef->target = prev; 20533 break; 20534 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20535 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20536 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20537 { 20538 wasRedefined = 1; 20539 break; 20540 } 20541 (WXS_ATTR_GROUP_CAST prev)->flags |= 20542 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20543 if (redef->reference != NULL) { 20544 /* 20545 * Assign the redefined attribute group to the 20546 * QName-reference component. 20547 * This is the easy case, since we will just 20548 * expand the redefined group. 20549 */ 20550 (WXS_QNAME_CAST redef->reference)->item = prev; 20551 redef->target = NULL; 20552 } else { 20553 /* 20554 * This is the complicated case: we need 20555 * to apply src-redefine (7.2.2) at a later 20556 * stage, i.e. when attribute group references 20557 * have beed expanded and simple types have 20558 * beed fixed. 20559 */ 20560 redef->target = prev; 20561 } 20562 break; 20563 default: 20564 PERROR_INT("xmlSchemaResolveRedefReferences", 20565 "Unexpected redefined component type"); 20566 return(-1); 20567 } 20568 if (wasRedefined) { 20569 xmlChar *str = NULL; 20570 xmlNodePtr node; 20571 20572 if (redef->reference) 20573 node = WXS_ITEM_NODE(redef->reference); 20574 else 20575 node = WXS_ITEM_NODE(redef->item); 20576 20577 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20578 /* TODO: error code. */ 20579 XML_SCHEMAP_SRC_REDEFINE, 20580 node, NULL, 20581 "The referenced %s was already redefined. Multiple " 20582 "redefinition of the same component is not supported", 20583 xmlSchemaGetComponentDesignation(&str, prev), 20584 NULL); 20585 FREE_AND_NULL(str) 20586 err = pctxt->err; 20587 redef = redef->next; 20588 continue; 20589 } 20590 redef = redef->next; 20591 } while (redef != NULL); 20592 20593 return(err); 20594 } 20595 20596 static int 20597 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20598 { 20599 int err = 0; 20600 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20601 xmlSchemaBasicItemPtr item; 20602 20603 if (redef == NULL) 20604 return(0); 20605 20606 do { 20607 if (redef->target == NULL) { 20608 redef = redef->next; 20609 continue; 20610 } 20611 item = redef->item; 20612 20613 switch (item->type) { 20614 case XML_SCHEMA_TYPE_SIMPLE: 20615 case XML_SCHEMA_TYPE_COMPLEX: 20616 /* 20617 * Since the spec wants the {name} of the redefined 20618 * type to be 'absent', we'll NULL it. 20619 */ 20620 (WXS_TYPE_CAST redef->target)->name = NULL; 20621 20622 /* 20623 * TODO: Seems like there's nothing more to do. The normal 20624 * inheritance mechanism is used. But not 100% sure. 20625 */ 20626 break; 20627 case XML_SCHEMA_TYPE_GROUP: 20628 /* 20629 * URGENT TODO: 20630 * SPEC src-redefine: 20631 * (6.2.2) "The {model group} of the model group definition 20632 * which corresponds to it per XML Representation of Model 20633 * Group Definition Schema Components (3.7.2) must be a 20634 * valid restriction of the {model group} of that model 20635 * group definition in I, as defined in Particle Valid 20636 * (Restriction) (3.9.6)." 20637 */ 20638 break; 20639 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20640 /* 20641 * SPEC src-redefine: 20642 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20643 * the attribute group definition which corresponds to it 20644 * per XML Representation of Attribute Group Definition Schema 20645 * Components (3.6.2) must be valid restrictions of the 20646 * {attribute uses} and {attribute wildcard} of that attribute 20647 * group definition in I, as defined in clause 2, clause 3 and 20648 * clause 4 of Derivation Valid (Restriction, Complex) 20649 * (3.4.6) (where references to the base type definition are 20650 * understood as references to the attribute group definition 20651 * in I)." 20652 */ 20653 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20654 XML_SCHEMA_ACTION_REDEFINE, 20655 item, redef->target, 20656 (WXS_ATTR_GROUP_CAST item)->attrUses, 20657 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20658 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20659 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20660 if (err == -1) 20661 return(-1); 20662 break; 20663 default: 20664 break; 20665 } 20666 redef = redef->next; 20667 } while (redef != NULL); 20668 return(0); 20669 } 20670 20671 20672 static int 20673 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20674 xmlSchemaBucketPtr bucket) 20675 { 20676 xmlSchemaBasicItemPtr item; 20677 int err; 20678 xmlHashTablePtr *table; 20679 const xmlChar *name; 20680 int i; 20681 20682 #define WXS_GET_GLOBAL_HASH(c, slot) { \ 20683 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20684 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20685 else \ 20686 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20687 20688 /* 20689 * Add global components to the schema's hash tables. 20690 * This is the place where duplicate components will be 20691 * detected. 20692 * TODO: I think normally we should support imports of the 20693 * same namespace from multiple locations. We don't do currently, 20694 * but if we do then according to: 20695 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20696 * we would need, if imported directly, to import redefined 20697 * components as well to be able to catch clashing components. 20698 * (I hope I'll still know what this means after some months :-() 20699 */ 20700 if (bucket == NULL) 20701 return(-1); 20702 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20703 return(0); 20704 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20705 20706 for (i = 0; i < bucket->globals->nbItems; i++) { 20707 item = bucket->globals->items[i]; 20708 table = NULL; 20709 switch (item->type) { 20710 case XML_SCHEMA_TYPE_COMPLEX: 20711 case XML_SCHEMA_TYPE_SIMPLE: 20712 if (WXS_REDEFINED_TYPE(item)) 20713 continue; 20714 name = (WXS_TYPE_CAST item)->name; 20715 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20716 break; 20717 case XML_SCHEMA_TYPE_ELEMENT: 20718 name = (WXS_ELEM_CAST item)->name; 20719 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20720 break; 20721 case XML_SCHEMA_TYPE_ATTRIBUTE: 20722 name = (WXS_ATTR_CAST item)->name; 20723 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20724 break; 20725 case XML_SCHEMA_TYPE_GROUP: 20726 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20727 continue; 20728 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20729 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20730 break; 20731 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20732 if (WXS_REDEFINED_ATTR_GROUP(item)) 20733 continue; 20734 name = (WXS_ATTR_GROUP_CAST item)->name; 20735 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20736 break; 20737 case XML_SCHEMA_TYPE_IDC_KEY: 20738 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20739 case XML_SCHEMA_TYPE_IDC_KEYREF: 20740 name = (WXS_IDC_CAST item)->name; 20741 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20742 break; 20743 case XML_SCHEMA_TYPE_NOTATION: 20744 name = ((xmlSchemaNotationPtr) item)->name; 20745 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20746 break; 20747 default: 20748 PERROR_INT("xmlSchemaAddComponents", 20749 "Unexpected global component type"); 20750 continue; 20751 } 20752 if (*table == NULL) { 20753 *table = xmlHashCreateDict(10, pctxt->dict); 20754 if (*table == NULL) { 20755 PERROR_INT("xmlSchemaAddComponents", 20756 "failed to create a component hash table"); 20757 return(-1); 20758 } 20759 } 20760 err = xmlHashAddEntry(*table, name, item); 20761 if (err != 0) { 20762 xmlChar *str = NULL; 20763 20764 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20765 XML_SCHEMAP_REDEFINED_TYPE, 20766 WXS_ITEM_NODE(item), 20767 WXS_BASIC_CAST item, 20768 "A global %s '%s' does already exist", 20769 WXS_ITEM_TYPE_NAME(item), 20770 xmlSchemaGetComponentQName(&str, item)); 20771 FREE_AND_NULL(str); 20772 } 20773 } 20774 /* 20775 * Process imported/included schemas. 20776 */ 20777 if (bucket->relations != NULL) { 20778 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20779 do { 20780 if ((rel->bucket != NULL) && 20781 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20782 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20783 return(-1); 20784 } 20785 rel = rel->next; 20786 } while (rel != NULL); 20787 } 20788 return(0); 20789 } 20790 20791 static int 20792 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20793 xmlSchemaBucketPtr rootBucket) 20794 { 20795 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20796 xmlSchemaTreeItemPtr item, *items; 20797 int nbItems, i, ret = 0; 20798 xmlSchemaBucketPtr oldbucket = con->bucket; 20799 xmlSchemaElementPtr elemDecl; 20800 20801 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20802 20803 if ((con->pending == NULL) || 20804 (con->pending->nbItems == 0)) 20805 return(0); 20806 20807 /* 20808 * Since xmlSchemaFixupComplexType() will create new particles 20809 * (local components), and those particle components need a bucket 20810 * on the constructor, we'll assure here that the constructor has 20811 * a bucket. 20812 * TODO: Think about storing locals _only_ on the main bucket. 20813 */ 20814 if (con->bucket == NULL) 20815 con->bucket = rootBucket; 20816 20817 /* TODO: 20818 * SPEC (src-redefine): 20819 * (6.2) "If it has no such self-reference, then all of the 20820 * following must be true:" 20821 20822 * (6.2.2) The {model group} of the model group definition which 20823 * corresponds to it per XML Representation of Model Group 20824 * Definition Schema Components (3.7.2) must be a valid 20825 * restriction of the {model group} of that model group definition 20826 * in I, as defined in Particle Valid (Restriction) (3.9.6)." 20827 */ 20828 xmlSchemaCheckSRCRedefineFirst(pctxt); 20829 20830 /* 20831 * Add global components to the schemata's hash tables. 20832 */ 20833 xmlSchemaAddComponents(pctxt, rootBucket); 20834 20835 pctxt->ctxtType = NULL; 20836 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20837 nbItems = con->pending->nbItems; 20838 /* 20839 * Now that we have parsed *all* the schema document(s) and converted 20840 * them to schema components, we can resolve references, apply component 20841 * constraints, create the FSA from the content model, etc. 20842 */ 20843 /* 20844 * Resolve references of.. 20845 * 20846 * 1. element declarations: 20847 * - the type definition 20848 * - the substitution group affiliation 20849 * 2. simple/complex types: 20850 * - the base type definition 20851 * - the memberTypes of union types 20852 * - the itemType of list types 20853 * 3. attributes declarations and attribute uses: 20854 * - the type definition 20855 * - if an attribute use, then the attribute declaration 20856 * 4. attribute group references: 20857 * - the attribute group definition 20858 * 5. particles: 20859 * - the term of the particle (e.g. a model group) 20860 * 6. IDC key-references: 20861 * - the referenced IDC 'key' or 'unique' definition 20862 * 7. Attribute prohibitions which had a "ref" attribute. 20863 */ 20864 for (i = 0; i < nbItems; i++) { 20865 item = items[i]; 20866 switch (item->type) { 20867 case XML_SCHEMA_TYPE_ELEMENT: 20868 xmlSchemaResolveElementReferences( 20869 (xmlSchemaElementPtr) item, pctxt); 20870 FIXHFAILURE; 20871 break; 20872 case XML_SCHEMA_TYPE_COMPLEX: 20873 case XML_SCHEMA_TYPE_SIMPLE: 20874 xmlSchemaResolveTypeReferences( 20875 (xmlSchemaTypePtr) item, pctxt); 20876 FIXHFAILURE; 20877 break; 20878 case XML_SCHEMA_TYPE_ATTRIBUTE: 20879 xmlSchemaResolveAttrTypeReferences( 20880 (xmlSchemaAttributePtr) item, pctxt); 20881 FIXHFAILURE; 20882 break; 20883 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20884 xmlSchemaResolveAttrUseReferences( 20885 (xmlSchemaAttributeUsePtr) item, pctxt); 20886 FIXHFAILURE; 20887 break; 20888 case XML_SCHEMA_EXTRA_QNAMEREF: 20889 if ((WXS_QNAME_CAST item)->itemType == 20890 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20891 { 20892 xmlSchemaResolveAttrGroupReferences( 20893 WXS_QNAME_CAST item, pctxt); 20894 } 20895 FIXHFAILURE; 20896 break; 20897 case XML_SCHEMA_TYPE_SEQUENCE: 20898 case XML_SCHEMA_TYPE_CHOICE: 20899 case XML_SCHEMA_TYPE_ALL: 20900 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20901 WXS_MODEL_GROUP_CAST item); 20902 FIXHFAILURE; 20903 break; 20904 case XML_SCHEMA_TYPE_IDC_KEY: 20905 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20906 case XML_SCHEMA_TYPE_IDC_KEYREF: 20907 xmlSchemaResolveIDCKeyReferences( 20908 (xmlSchemaIDCPtr) item, pctxt); 20909 FIXHFAILURE; 20910 break; 20911 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20912 /* 20913 * Handle attribue prohibition which had a 20914 * "ref" attribute. 20915 */ 20916 xmlSchemaResolveAttrUseProhibReferences( 20917 WXS_ATTR_PROHIB_CAST item, pctxt); 20918 FIXHFAILURE; 20919 break; 20920 default: 20921 break; 20922 } 20923 } 20924 if (pctxt->nberrors != 0) 20925 goto exit_error; 20926 20927 /* 20928 * Now that all references are resolved we 20929 * can check for circularity of... 20930 * 1. the base axis of type definitions 20931 * 2. nested model group definitions 20932 * 3. nested attribute group definitions 20933 * TODO: check for circual substitution groups. 20934 */ 20935 for (i = 0; i < nbItems; i++) { 20936 item = items[i]; 20937 /* 20938 * Let's better stop on the first error here. 20939 */ 20940 switch (item->type) { 20941 case XML_SCHEMA_TYPE_COMPLEX: 20942 case XML_SCHEMA_TYPE_SIMPLE: 20943 xmlSchemaCheckTypeDefCircular( 20944 (xmlSchemaTypePtr) item, pctxt); 20945 FIXHFAILURE; 20946 if (pctxt->nberrors != 0) 20947 goto exit_error; 20948 break; 20949 case XML_SCHEMA_TYPE_GROUP: 20950 xmlSchemaCheckGroupDefCircular( 20951 (xmlSchemaModelGroupDefPtr) item, pctxt); 20952 FIXHFAILURE; 20953 if (pctxt->nberrors != 0) 20954 goto exit_error; 20955 break; 20956 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20957 xmlSchemaCheckAttrGroupCircular( 20958 (xmlSchemaAttributeGroupPtr) item, pctxt); 20959 FIXHFAILURE; 20960 if (pctxt->nberrors != 0) 20961 goto exit_error; 20962 break; 20963 default: 20964 break; 20965 } 20966 } 20967 if (pctxt->nberrors != 0) 20968 goto exit_error; 20969 /* 20970 * Model group definition references: 20971 * Such a reference is reflected by a particle at the component 20972 * level. Until now the 'term' of such particles pointed 20973 * to the model group definition; this was done, in order to 20974 * ease circularity checks. Now we need to set the 'term' of 20975 * such particles to the model group of the model group definition. 20976 */ 20977 for (i = 0; i < nbItems; i++) { 20978 item = items[i]; 20979 switch (item->type) { 20980 case XML_SCHEMA_TYPE_SEQUENCE: 20981 case XML_SCHEMA_TYPE_CHOICE: 20982 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 20983 WXS_MODEL_GROUP_CAST item); 20984 break; 20985 default: 20986 break; 20987 } 20988 } 20989 if (pctxt->nberrors != 0) 20990 goto exit_error; 20991 /* 20992 * Expand attribute group references of attribute group definitions. 20993 */ 20994 for (i = 0; i < nbItems; i++) { 20995 item = items[i]; 20996 switch (item->type) { 20997 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20998 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 20999 WXS_ATTR_GROUP_HAS_REFS(item)) 21000 { 21001 xmlSchemaAttributeGroupExpandRefs(pctxt, 21002 WXS_ATTR_GROUP_CAST item); 21003 FIXHFAILURE; 21004 } 21005 break; 21006 default: 21007 break; 21008 } 21009 } 21010 if (pctxt->nberrors != 0) 21011 goto exit_error; 21012 /* 21013 * First compute the variety of simple types. This is needed as 21014 * a seperate step, since otherwise we won't be able to detect 21015 * circular union types in all cases. 21016 */ 21017 for (i = 0; i < nbItems; i++) { 21018 item = items[i]; 21019 switch (item->type) { 21020 case XML_SCHEMA_TYPE_SIMPLE: 21021 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21022 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21023 (xmlSchemaTypePtr) item); 21024 FIXHFAILURE; 21025 } 21026 break; 21027 default: 21028 break; 21029 } 21030 } 21031 if (pctxt->nberrors != 0) 21032 goto exit_error; 21033 /* 21034 * Detect circular union types. Note that this needs the variety to 21035 * be already computed. 21036 */ 21037 for (i = 0; i < nbItems; i++) { 21038 item = items[i]; 21039 switch (item->type) { 21040 case XML_SCHEMA_TYPE_SIMPLE: 21041 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21042 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21043 (xmlSchemaTypePtr) item); 21044 FIXHFAILURE; 21045 } 21046 break; 21047 default: 21048 break; 21049 } 21050 } 21051 if (pctxt->nberrors != 0) 21052 goto exit_error; 21053 21054 /* 21055 * Do the complete type fixup for simple types. 21056 */ 21057 for (i = 0; i < nbItems; i++) { 21058 item = items[i]; 21059 switch (item->type) { 21060 case XML_SCHEMA_TYPE_SIMPLE: 21061 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21062 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21063 FIXHFAILURE; 21064 } 21065 break; 21066 default: 21067 break; 21068 } 21069 } 21070 if (pctxt->nberrors != 0) 21071 goto exit_error; 21072 /* 21073 * At this point we need build and check all simple types. 21074 */ 21075 /* 21076 * Apply contraints for attribute declarations. 21077 */ 21078 for (i = 0; i < nbItems; i++) { 21079 item = items[i]; 21080 switch (item->type) { 21081 case XML_SCHEMA_TYPE_ATTRIBUTE: 21082 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21083 FIXHFAILURE; 21084 break; 21085 default: 21086 break; 21087 } 21088 } 21089 if (pctxt->nberrors != 0) 21090 goto exit_error; 21091 /* 21092 * Apply constraints for attribute uses. 21093 */ 21094 for (i = 0; i < nbItems; i++) { 21095 item = items[i]; 21096 switch (item->type) { 21097 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21098 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21099 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21100 WXS_ATTR_USE_CAST item); 21101 FIXHFAILURE; 21102 } 21103 break; 21104 default: 21105 break; 21106 } 21107 } 21108 if (pctxt->nberrors != 0) 21109 goto exit_error; 21110 21111 /* 21112 * Apply constraints for attribute group definitions. 21113 */ 21114 for (i = 0; i < nbItems; i++) { 21115 item = items[i]; 21116 switch (item->type) { 21117 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21118 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21119 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21120 { 21121 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21122 FIXHFAILURE; 21123 } 21124 break; 21125 default: 21126 break; 21127 } 21128 } 21129 if (pctxt->nberrors != 0) 21130 goto exit_error; 21131 21132 /* 21133 * Apply constraints for redefinitions. 21134 */ 21135 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21136 xmlSchemaCheckSRCRedefineSecond(pctxt); 21137 if (pctxt->nberrors != 0) 21138 goto exit_error; 21139 21140 /* 21141 * Complex types are builded and checked. 21142 */ 21143 for (i = 0; i < nbItems; i++) { 21144 item = con->pending->items[i]; 21145 switch (item->type) { 21146 case XML_SCHEMA_TYPE_COMPLEX: 21147 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21148 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21149 FIXHFAILURE; 21150 } 21151 break; 21152 default: 21153 break; 21154 } 21155 } 21156 if (pctxt->nberrors != 0) 21157 goto exit_error; 21158 21159 /* 21160 * The list could have changed, since xmlSchemaFixupComplexType() 21161 * will create particles and model groups in some cases. 21162 */ 21163 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21164 nbItems = con->pending->nbItems; 21165 21166 /* 21167 * Apply some constraints for element declarations. 21168 */ 21169 for (i = 0; i < nbItems; i++) { 21170 item = items[i]; 21171 switch (item->type) { 21172 case XML_SCHEMA_TYPE_ELEMENT: 21173 elemDecl = (xmlSchemaElementPtr) item; 21174 21175 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21176 { 21177 xmlSchemaCheckElementDeclComponent( 21178 (xmlSchemaElementPtr) elemDecl, pctxt); 21179 FIXHFAILURE; 21180 } 21181 21182 #ifdef WXS_ELEM_DECL_CONS_ENABLED 21183 /* 21184 * Schema Component Constraint: Element Declarations Consistent 21185 * Apply this constraint to local types of element declarations. 21186 */ 21187 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21188 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21189 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21190 { 21191 xmlSchemaCheckElementDeclConsistent(pctxt, 21192 WXS_BASIC_CAST elemDecl, 21193 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21194 NULL, NULL, 0); 21195 } 21196 #endif 21197 break; 21198 default: 21199 break; 21200 } 21201 } 21202 if (pctxt->nberrors != 0) 21203 goto exit_error; 21204 21205 /* 21206 * Finally we can build the automaton from the content model of 21207 * complex types. 21208 */ 21209 21210 for (i = 0; i < nbItems; i++) { 21211 item = items[i]; 21212 switch (item->type) { 21213 case XML_SCHEMA_TYPE_COMPLEX: 21214 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21215 /* FIXHFAILURE; */ 21216 break; 21217 default: 21218 break; 21219 } 21220 } 21221 if (pctxt->nberrors != 0) 21222 goto exit_error; 21223 /* 21224 * URGENT TODO: cos-element-consistent 21225 */ 21226 goto exit; 21227 21228 exit_error: 21229 ret = pctxt->err; 21230 goto exit; 21231 21232 exit_failure: 21233 ret = -1; 21234 21235 exit: 21236 /* 21237 * Reset the constructor. This is needed for XSI acquisition, since 21238 * those items will be processed over and over again for every XSI 21239 * if not cleared here. 21240 */ 21241 con->bucket = oldbucket; 21242 con->pending->nbItems = 0; 21243 if (con->substGroups != NULL) { 21244 xmlHashFree(con->substGroups, 21245 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 21246 con->substGroups = NULL; 21247 } 21248 if (con->redefs != NULL) { 21249 xmlSchemaRedefListFree(con->redefs); 21250 con->redefs = NULL; 21251 } 21252 return(ret); 21253 } 21254 /** 21255 * xmlSchemaParse: 21256 * @ctxt: a schema validation context 21257 * 21258 * parse a schema definition resource and build an internal 21259 * XML Shema struture which can be used to validate instances. 21260 * 21261 * Returns the internal XML Schema structure built from the resource or 21262 * NULL in case of error 21263 */ 21264 xmlSchemaPtr 21265 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21266 { 21267 xmlSchemaPtr mainSchema = NULL; 21268 xmlSchemaBucketPtr bucket = NULL; 21269 int res; 21270 21271 /* 21272 * This one is used if the schema to be parsed was specified via 21273 * the API; i.e. not automatically by the validated instance document. 21274 */ 21275 21276 xmlSchemaInitTypes(); 21277 21278 if (ctxt == NULL) 21279 return (NULL); 21280 21281 /* TODO: Init the context. Is this all we need?*/ 21282 ctxt->nberrors = 0; 21283 ctxt->err = 0; 21284 ctxt->counter = 0; 21285 21286 /* Create the *main* schema. */ 21287 mainSchema = xmlSchemaNewSchema(ctxt); 21288 if (mainSchema == NULL) 21289 goto exit_failure; 21290 /* 21291 * Create the schema constructor. 21292 */ 21293 if (ctxt->constructor == NULL) { 21294 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21295 if (ctxt->constructor == NULL) 21296 return(NULL); 21297 /* Take ownership of the constructor to be able to free it. */ 21298 ctxt->ownsConstructor = 1; 21299 } 21300 ctxt->constructor->mainSchema = mainSchema; 21301 /* 21302 * Locate and add the schema document. 21303 */ 21304 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21305 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21306 NULL, NULL, &bucket); 21307 if (res == -1) 21308 goto exit_failure; 21309 if (res != 0) 21310 goto exit; 21311 21312 if (bucket == NULL) { 21313 /* TODO: Error code, actually we failed to *locate* the schema. */ 21314 if (ctxt->URL) 21315 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21316 NULL, NULL, 21317 "Failed to locate the main schema resource at '%s'", 21318 ctxt->URL, NULL); 21319 else 21320 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21321 NULL, NULL, 21322 "Failed to locate the main schema resource", 21323 NULL, NULL); 21324 goto exit; 21325 } 21326 /* Then do the parsing for good. */ 21327 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21328 goto exit_failure; 21329 if (ctxt->nberrors != 0) 21330 goto exit; 21331 21332 mainSchema->doc = bucket->doc; 21333 mainSchema->preserve = ctxt->preserve; 21334 21335 ctxt->schema = mainSchema; 21336 21337 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21338 goto exit_failure; 21339 21340 /* 21341 * TODO: This is not nice, since we cannot distinguish from the 21342 * result if there was an internal error or not. 21343 */ 21344 exit: 21345 if (ctxt->nberrors != 0) { 21346 if (mainSchema) { 21347 xmlSchemaFree(mainSchema); 21348 mainSchema = NULL; 21349 } 21350 if (ctxt->constructor) { 21351 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21352 ctxt->constructor = NULL; 21353 ctxt->ownsConstructor = 0; 21354 } 21355 } 21356 ctxt->schema = NULL; 21357 return(mainSchema); 21358 exit_failure: 21359 /* 21360 * Quite verbose, but should catch internal errors, which were 21361 * not communitated. 21362 */ 21363 if (mainSchema) { 21364 xmlSchemaFree(mainSchema); 21365 mainSchema = NULL; 21366 } 21367 if (ctxt->constructor) { 21368 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21369 ctxt->constructor = NULL; 21370 ctxt->ownsConstructor = 0; 21371 } 21372 PERROR_INT2("xmlSchemaParse", 21373 "An internal error occured"); 21374 ctxt->schema = NULL; 21375 return(NULL); 21376 } 21377 21378 /** 21379 * xmlSchemaSetParserErrors: 21380 * @ctxt: a schema validation context 21381 * @err: the error callback 21382 * @warn: the warning callback 21383 * @ctx: contextual data for the callbacks 21384 * 21385 * Set the callback functions used to handle errors for a validation context 21386 */ 21387 void 21388 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21389 xmlSchemaValidityErrorFunc err, 21390 xmlSchemaValidityWarningFunc warn, void *ctx) 21391 { 21392 if (ctxt == NULL) 21393 return; 21394 ctxt->error = err; 21395 ctxt->warning = warn; 21396 ctxt->errCtxt = ctx; 21397 if (ctxt->vctxt != NULL) 21398 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21399 } 21400 21401 /** 21402 * xmlSchemaSetParserStructuredErrors: 21403 * @ctxt: a schema parser context 21404 * @serror: the structured error function 21405 * @ctx: the functions context 21406 * 21407 * Set the structured error callback 21408 */ 21409 void 21410 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21411 xmlStructuredErrorFunc serror, 21412 void *ctx) 21413 { 21414 if (ctxt == NULL) 21415 return; 21416 ctxt->serror = serror; 21417 ctxt->errCtxt = ctx; 21418 if (ctxt->vctxt != NULL) 21419 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21420 } 21421 21422 /** 21423 * xmlSchemaGetParserErrors: 21424 * @ctxt: a XMl-Schema parser context 21425 * @err: the error callback result 21426 * @warn: the warning callback result 21427 * @ctx: contextual data for the callbacks result 21428 * 21429 * Get the callback information used to handle errors for a parser context 21430 * 21431 * Returns -1 in case of failure, 0 otherwise 21432 */ 21433 int 21434 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21435 xmlSchemaValidityErrorFunc * err, 21436 xmlSchemaValidityWarningFunc * warn, void **ctx) 21437 { 21438 if (ctxt == NULL) 21439 return(-1); 21440 if (err != NULL) 21441 *err = ctxt->error; 21442 if (warn != NULL) 21443 *warn = ctxt->warning; 21444 if (ctx != NULL) 21445 *ctx = ctxt->errCtxt; 21446 return(0); 21447 } 21448 21449 /** 21450 * xmlSchemaFacetTypeToString: 21451 * @type: the facet type 21452 * 21453 * Convert the xmlSchemaTypeType to a char string. 21454 * 21455 * Returns the char string representation of the facet type if the 21456 * type is a facet and an "Internal Error" string otherwise. 21457 */ 21458 static const xmlChar * 21459 xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21460 { 21461 switch (type) { 21462 case XML_SCHEMA_FACET_PATTERN: 21463 return (BAD_CAST "pattern"); 21464 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21465 return (BAD_CAST "maxExclusive"); 21466 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21467 return (BAD_CAST "maxInclusive"); 21468 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21469 return (BAD_CAST "minExclusive"); 21470 case XML_SCHEMA_FACET_MININCLUSIVE: 21471 return (BAD_CAST "minInclusive"); 21472 case XML_SCHEMA_FACET_WHITESPACE: 21473 return (BAD_CAST "whiteSpace"); 21474 case XML_SCHEMA_FACET_ENUMERATION: 21475 return (BAD_CAST "enumeration"); 21476 case XML_SCHEMA_FACET_LENGTH: 21477 return (BAD_CAST "length"); 21478 case XML_SCHEMA_FACET_MAXLENGTH: 21479 return (BAD_CAST "maxLength"); 21480 case XML_SCHEMA_FACET_MINLENGTH: 21481 return (BAD_CAST "minLength"); 21482 case XML_SCHEMA_FACET_TOTALDIGITS: 21483 return (BAD_CAST "totalDigits"); 21484 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21485 return (BAD_CAST "fractionDigits"); 21486 default: 21487 break; 21488 } 21489 return (BAD_CAST "Internal Error"); 21490 } 21491 21492 static xmlSchemaWhitespaceValueType 21493 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21494 { 21495 /* 21496 * The normalization type can be changed only for types which are derived 21497 * from xsd:string. 21498 */ 21499 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21500 /* 21501 * Note that we assume a whitespace of preserve for anySimpleType. 21502 */ 21503 if ((type->builtInType == XML_SCHEMAS_STRING) || 21504 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21505 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21506 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21507 return(XML_SCHEMA_WHITESPACE_REPLACE); 21508 else { 21509 /* 21510 * For all atomic datatypes other than string (and types derived 21511 * by restriction from it) the value of whiteSpace is fixed to 21512 * collapse 21513 * Note that this includes built-in list datatypes. 21514 */ 21515 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21516 } 21517 } else if (WXS_IS_LIST(type)) { 21518 /* 21519 * For list types the facet "whiteSpace" is fixed to "collapse". 21520 */ 21521 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21522 } else if (WXS_IS_UNION(type)) { 21523 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21524 } else if (WXS_IS_ATOMIC(type)) { 21525 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21526 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21527 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21528 return (XML_SCHEMA_WHITESPACE_REPLACE); 21529 else 21530 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21531 } 21532 return (-1); 21533 } 21534 21535 /************************************************************************ 21536 * * 21537 * Simple type validation * 21538 * * 21539 ************************************************************************/ 21540 21541 21542 /************************************************************************ 21543 * * 21544 * DOM Validation code * 21545 * * 21546 ************************************************************************/ 21547 21548 /** 21549 * xmlSchemaAssembleByLocation: 21550 * @pctxt: a schema parser context 21551 * @vctxt: a schema validation context 21552 * @schema: the existing schema 21553 * @node: the node that fired the assembling 21554 * @nsName: the namespace name of the new schema 21555 * @location: the location of the schema 21556 * 21557 * Expands an existing schema by an additional schema. 21558 * 21559 * Returns 0 if the new schema is correct, a positive error code 21560 * number otherwise and -1 in case of an internal or API error. 21561 */ 21562 static int 21563 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21564 xmlSchemaPtr schema, 21565 xmlNodePtr node, 21566 const xmlChar *nsName, 21567 const xmlChar *location) 21568 { 21569 int ret = 0; 21570 xmlSchemaParserCtxtPtr pctxt; 21571 xmlSchemaBucketPtr bucket = NULL; 21572 21573 if ((vctxt == NULL) || (schema == NULL)) 21574 return (-1); 21575 21576 if (vctxt->pctxt == NULL) { 21577 VERROR_INT("xmlSchemaAssembleByLocation", 21578 "no parser context available"); 21579 return(-1); 21580 } 21581 pctxt = vctxt->pctxt; 21582 if (pctxt->constructor == NULL) { 21583 PERROR_INT("xmlSchemaAssembleByLocation", 21584 "no constructor"); 21585 return(-1); 21586 } 21587 /* 21588 * Acquire the schema document. 21589 */ 21590 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21591 location, node); 21592 /* 21593 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21594 * the process will automatically change this to 21595 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21596 */ 21597 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21598 location, NULL, NULL, 0, node, NULL, nsName, 21599 &bucket); 21600 if (ret != 0) 21601 return(ret); 21602 if (bucket == NULL) { 21603 /* 21604 * Generate a warning that the document could not be located. 21605 */ 21606 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21607 node, NULL, 21608 "The document at location '%s' could not be acquired", 21609 location, NULL, NULL); 21610 return(ret); 21611 } 21612 /* 21613 * The first located schema will be handled as if all other 21614 * schemas imported by XSI were imported by this first schema. 21615 */ 21616 if ((bucket != NULL) && 21617 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21618 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21619 /* 21620 * TODO: Is this handled like an import? I.e. is it not an error 21621 * if the schema cannot be located? 21622 */ 21623 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21624 return(0); 21625 /* 21626 * We will reuse the parser context for every schema imported 21627 * directly via XSI. So reset the context. 21628 */ 21629 pctxt->nberrors = 0; 21630 pctxt->err = 0; 21631 pctxt->doc = bucket->doc; 21632 21633 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21634 if (ret == -1) { 21635 pctxt->doc = NULL; 21636 goto exit_failure; 21637 } 21638 /* Paranoid error channelling. */ 21639 if ((ret == 0) && (pctxt->nberrors != 0)) 21640 ret = pctxt->err; 21641 if (pctxt->nberrors == 0) { 21642 /* 21643 * Only bother to fixup pending components, if there was 21644 * no error yet. 21645 * For every XSI acquired schema (and its sub-schemata) we will 21646 * fixup the components. 21647 */ 21648 xmlSchemaFixupComponents(pctxt, bucket); 21649 ret = pctxt->err; 21650 /* 21651 * Not nice, but we need somehow to channel the schema parser 21652 * error to the validation context. 21653 */ 21654 if ((ret != 0) && (vctxt->err == 0)) 21655 vctxt->err = ret; 21656 vctxt->nberrors += pctxt->nberrors; 21657 } else { 21658 /* Add to validation error sum. */ 21659 vctxt->nberrors += pctxt->nberrors; 21660 } 21661 pctxt->doc = NULL; 21662 return(ret); 21663 exit_failure: 21664 pctxt->doc = NULL; 21665 return (-1); 21666 } 21667 21668 static xmlSchemaAttrInfoPtr 21669 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21670 int metaType) 21671 { 21672 if (vctxt->nbAttrInfos == 0) 21673 return (NULL); 21674 { 21675 int i; 21676 xmlSchemaAttrInfoPtr iattr; 21677 21678 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21679 iattr = vctxt->attrInfos[i]; 21680 if (iattr->metaType == metaType) 21681 return (iattr); 21682 } 21683 21684 } 21685 return (NULL); 21686 } 21687 21688 /** 21689 * xmlSchemaAssembleByXSI: 21690 * @vctxt: a schema validation context 21691 * 21692 * Expands an existing schema by an additional schema using 21693 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21694 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21695 * must be set to 1. 21696 * 21697 * Returns 0 if the new schema is correct, a positive error code 21698 * number otherwise and -1 in case of an internal or API error. 21699 */ 21700 static int 21701 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21702 { 21703 const xmlChar *cur, *end; 21704 const xmlChar *nsname = NULL, *location; 21705 int count = 0; 21706 int ret = 0; 21707 xmlSchemaAttrInfoPtr iattr; 21708 21709 /* 21710 * Parse the value; we will assume an even number of values 21711 * to be given (this is how Xerces and XSV work). 21712 * 21713 * URGENT TODO: !! This needs to work for both 21714 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21715 * element !! 21716 */ 21717 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21718 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21719 if (iattr == NULL) 21720 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21721 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21722 if (iattr == NULL) 21723 return (0); 21724 cur = iattr->value; 21725 do { 21726 /* 21727 * TODO: Move the string parsing mechanism away from here. 21728 */ 21729 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21730 /* 21731 * Get the namespace name. 21732 */ 21733 while (IS_BLANK_CH(*cur)) 21734 cur++; 21735 end = cur; 21736 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21737 end++; 21738 if (end == cur) 21739 break; 21740 count++; /* TODO: Don't use the schema's dict. */ 21741 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21742 cur = end; 21743 } 21744 /* 21745 * Get the URI. 21746 */ 21747 while (IS_BLANK_CH(*cur)) 21748 cur++; 21749 end = cur; 21750 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21751 end++; 21752 if (end == cur) { 21753 if (iattr->metaType == 21754 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21755 { 21756 /* 21757 * If using @schemaLocation then tuples are expected. 21758 * I.e. the namespace name *and* the document's URI. 21759 */ 21760 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21761 iattr->node, NULL, 21762 "The value must consist of tuples: the target namespace " 21763 "name and the document's URI", NULL, NULL, NULL); 21764 } 21765 break; 21766 } 21767 count++; /* TODO: Don't use the schema's dict. */ 21768 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21769 cur = end; 21770 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21771 iattr->node, nsname, location); 21772 if (ret == -1) { 21773 VERROR_INT("xmlSchemaAssembleByXSI", 21774 "assembling schemata"); 21775 return (-1); 21776 } 21777 } while (*cur != 0); 21778 return (ret); 21779 } 21780 21781 static const xmlChar * 21782 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21783 const xmlChar *prefix) 21784 { 21785 if (vctxt->sax != NULL) { 21786 int i, j; 21787 xmlSchemaNodeInfoPtr inode; 21788 21789 for (i = vctxt->depth; i >= 0; i--) { 21790 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21791 inode = vctxt->elemInfos[i]; 21792 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21793 if (((prefix == NULL) && 21794 (inode->nsBindings[j] == NULL)) || 21795 ((prefix != NULL) && xmlStrEqual(prefix, 21796 inode->nsBindings[j]))) { 21797 21798 /* 21799 * Note that the namespace bindings are already 21800 * in a string dict. 21801 */ 21802 return (inode->nsBindings[j+1]); 21803 } 21804 } 21805 } 21806 } 21807 return (NULL); 21808 #ifdef LIBXML_READER_ENABLED 21809 } else if (vctxt->reader != NULL) { 21810 xmlChar *nsName; 21811 21812 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21813 if (nsName != NULL) { 21814 const xmlChar *ret; 21815 21816 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21817 xmlFree(nsName); 21818 return (ret); 21819 } else 21820 return (NULL); 21821 #endif 21822 } else { 21823 xmlNsPtr ns; 21824 21825 if ((vctxt->inode->node == NULL) || 21826 (vctxt->inode->node->doc == NULL)) { 21827 VERROR_INT("xmlSchemaLookupNamespace", 21828 "no node or node's doc avaliable"); 21829 return (NULL); 21830 } 21831 ns = xmlSearchNs(vctxt->inode->node->doc, 21832 vctxt->inode->node, prefix); 21833 if (ns != NULL) 21834 return (ns->href); 21835 return (NULL); 21836 } 21837 } 21838 21839 /* 21840 * This one works on the schema of the validation context. 21841 */ 21842 static int 21843 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21844 xmlSchemaPtr schema, 21845 xmlNodePtr node, 21846 const xmlChar *value, 21847 xmlSchemaValPtr *val, 21848 int valNeeded) 21849 { 21850 int ret; 21851 21852 if (vctxt && (vctxt->schema == NULL)) { 21853 VERROR_INT("xmlSchemaValidateNotation", 21854 "a schema is needed on the validation context"); 21855 return (-1); 21856 } 21857 ret = xmlValidateQName(value, 1); 21858 if (ret != 0) 21859 return (ret); 21860 { 21861 xmlChar *localName = NULL; 21862 xmlChar *prefix = NULL; 21863 21864 localName = xmlSplitQName2(value, &prefix); 21865 if (prefix != NULL) { 21866 const xmlChar *nsName = NULL; 21867 21868 if (vctxt != NULL) 21869 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21870 else if (node != NULL) { 21871 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21872 if (ns != NULL) 21873 nsName = ns->href; 21874 } else { 21875 xmlFree(prefix); 21876 xmlFree(localName); 21877 return (1); 21878 } 21879 if (nsName == NULL) { 21880 xmlFree(prefix); 21881 xmlFree(localName); 21882 return (1); 21883 } 21884 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21885 if ((valNeeded) && (val != NULL)) { 21886 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21887 xmlStrdup(nsName)); 21888 if (*val == NULL) 21889 ret = -1; 21890 } 21891 } else 21892 ret = 1; 21893 xmlFree(prefix); 21894 xmlFree(localName); 21895 } else { 21896 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21897 if (valNeeded && (val != NULL)) { 21898 (*val) = xmlSchemaNewNOTATIONValue( 21899 BAD_CAST xmlStrdup(value), NULL); 21900 if (*val == NULL) 21901 ret = -1; 21902 } 21903 } else 21904 return (1); 21905 } 21906 } 21907 return (ret); 21908 } 21909 21910 static int 21911 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21912 const xmlChar* lname, 21913 const xmlChar* nsname) 21914 { 21915 int i; 21916 21917 lname = xmlDictLookup(vctxt->dict, lname, -1); 21918 if (lname == NULL) 21919 return(-1); 21920 if (nsname != NULL) { 21921 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21922 if (nsname == NULL) 21923 return(-1); 21924 } 21925 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21926 if ((vctxt->nodeQNames->items [i] == lname) && 21927 (vctxt->nodeQNames->items[i +1] == nsname)) 21928 /* Already there */ 21929 return(i); 21930 } 21931 /* Add new entry. */ 21932 i = vctxt->nodeQNames->nbItems; 21933 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21934 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21935 return(i); 21936 } 21937 21938 /************************************************************************ 21939 * * 21940 * Validation of identity-constraints (IDC) * 21941 * * 21942 ************************************************************************/ 21943 21944 /** 21945 * xmlSchemaAugmentIDC: 21946 * @idcDef: the IDC definition 21947 * 21948 * Creates an augmented IDC definition item. 21949 * 21950 * Returns the item, or NULL on internal errors. 21951 */ 21952 static void 21953 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, 21954 xmlSchemaValidCtxtPtr vctxt) 21955 { 21956 xmlSchemaIDCAugPtr aidc; 21957 21958 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 21959 if (aidc == NULL) { 21960 xmlSchemaVErrMemory(vctxt, 21961 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 21962 NULL); 21963 return; 21964 } 21965 aidc->keyrefDepth = -1; 21966 aidc->def = idcDef; 21967 aidc->next = NULL; 21968 if (vctxt->aidcs == NULL) 21969 vctxt->aidcs = aidc; 21970 else { 21971 aidc->next = vctxt->aidcs; 21972 vctxt->aidcs = aidc; 21973 } 21974 /* 21975 * Save if we have keyrefs at all. 21976 */ 21977 if ((vctxt->hasKeyrefs == 0) && 21978 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 21979 vctxt->hasKeyrefs = 1; 21980 } 21981 21982 /** 21983 * xmlSchemaAugmentImportedIDC: 21984 * @imported: the imported schema 21985 * 21986 * Creates an augmented IDC definition for the imported schema. 21987 */ 21988 static void 21989 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) { 21990 if (imported->schema->idcDef != NULL) { 21991 xmlHashScan(imported->schema->idcDef , 21992 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); 21993 } 21994 } 21995 21996 /** 21997 * xmlSchemaIDCNewBinding: 21998 * @idcDef: the IDC definition of this binding 21999 * 22000 * Creates a new IDC binding. 22001 * 22002 * Returns the new IDC binding, NULL on internal errors. 22003 */ 22004 static xmlSchemaPSVIIDCBindingPtr 22005 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22006 { 22007 xmlSchemaPSVIIDCBindingPtr ret; 22008 22009 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22010 sizeof(xmlSchemaPSVIIDCBinding)); 22011 if (ret == NULL) { 22012 xmlSchemaVErrMemory(NULL, 22013 "allocating a PSVI IDC binding item", NULL); 22014 return (NULL); 22015 } 22016 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22017 ret->definition = idcDef; 22018 return (ret); 22019 } 22020 22021 /** 22022 * xmlSchemaIDCStoreNodeTableItem: 22023 * @vctxt: the WXS validation context 22024 * @item: the IDC node table item 22025 * 22026 * The validation context is used to store IDC node table items. 22027 * They are stored to avoid copying them if IDC node-tables are merged 22028 * with corresponding parent IDC node-tables (bubbling). 22029 * 22030 * Returns 0 if succeeded, -1 on internal errors. 22031 */ 22032 static int 22033 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22034 xmlSchemaPSVIIDCNodePtr item) 22035 { 22036 /* 22037 * Add to gobal list. 22038 */ 22039 if (vctxt->idcNodes == NULL) { 22040 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22041 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22042 if (vctxt->idcNodes == NULL) { 22043 xmlSchemaVErrMemory(vctxt, 22044 "allocating the IDC node table item list", NULL); 22045 return (-1); 22046 } 22047 vctxt->sizeIdcNodes = 20; 22048 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22049 vctxt->sizeIdcNodes *= 2; 22050 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22051 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22052 sizeof(xmlSchemaPSVIIDCNodePtr)); 22053 if (vctxt->idcNodes == NULL) { 22054 xmlSchemaVErrMemory(vctxt, 22055 "re-allocating the IDC node table item list", NULL); 22056 return (-1); 22057 } 22058 } 22059 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22060 22061 return (0); 22062 } 22063 22064 /** 22065 * xmlSchemaIDCStoreKey: 22066 * @vctxt: the WXS validation context 22067 * @item: the IDC key 22068 * 22069 * The validation context is used to store an IDC key. 22070 * 22071 * Returns 0 if succeeded, -1 on internal errors. 22072 */ 22073 static int 22074 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22075 xmlSchemaPSVIIDCKeyPtr key) 22076 { 22077 /* 22078 * Add to gobal list. 22079 */ 22080 if (vctxt->idcKeys == NULL) { 22081 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22082 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22083 if (vctxt->idcKeys == NULL) { 22084 xmlSchemaVErrMemory(vctxt, 22085 "allocating the IDC key storage list", NULL); 22086 return (-1); 22087 } 22088 vctxt->sizeIdcKeys = 40; 22089 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22090 vctxt->sizeIdcKeys *= 2; 22091 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22092 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22093 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22094 if (vctxt->idcKeys == NULL) { 22095 xmlSchemaVErrMemory(vctxt, 22096 "re-allocating the IDC key storage list", NULL); 22097 return (-1); 22098 } 22099 } 22100 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22101 22102 return (0); 22103 } 22104 22105 /** 22106 * xmlSchemaIDCAppendNodeTableItem: 22107 * @bind: the IDC binding 22108 * @ntItem: the node-table item 22109 * 22110 * Appends the IDC node-table item to the binding. 22111 * 22112 * Returns 0 on success and -1 on internal errors. 22113 */ 22114 static int 22115 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22116 xmlSchemaPSVIIDCNodePtr ntItem) 22117 { 22118 if (bind->nodeTable == NULL) { 22119 bind->sizeNodes = 10; 22120 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22121 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22122 if (bind->nodeTable == NULL) { 22123 xmlSchemaVErrMemory(NULL, 22124 "allocating an array of IDC node-table items", NULL); 22125 return(-1); 22126 } 22127 } else if (bind->sizeNodes <= bind->nbNodes) { 22128 bind->sizeNodes *= 2; 22129 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22130 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22131 sizeof(xmlSchemaPSVIIDCNodePtr)); 22132 if (bind->nodeTable == NULL) { 22133 xmlSchemaVErrMemory(NULL, 22134 "re-allocating an array of IDC node-table items", NULL); 22135 return(-1); 22136 } 22137 } 22138 bind->nodeTable[bind->nbNodes++] = ntItem; 22139 return(0); 22140 } 22141 22142 /** 22143 * xmlSchemaIDCAcquireBinding: 22144 * @vctxt: the WXS validation context 22145 * @matcher: the IDC matcher 22146 * 22147 * Looks up an PSVI IDC binding, for the IDC definition and 22148 * of the given matcher. If none found, a new one is created 22149 * and added to the IDC table. 22150 * 22151 * Returns an IDC binding or NULL on internal errors. 22152 */ 22153 static xmlSchemaPSVIIDCBindingPtr 22154 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22155 xmlSchemaIDCMatcherPtr matcher) 22156 { 22157 xmlSchemaNodeInfoPtr ielem; 22158 22159 ielem = vctxt->elemInfos[matcher->depth]; 22160 22161 if (ielem->idcTable == NULL) { 22162 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22163 if (ielem->idcTable == NULL) 22164 return (NULL); 22165 return(ielem->idcTable); 22166 } else { 22167 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22168 22169 bind = ielem->idcTable; 22170 do { 22171 if (bind->definition == matcher->aidc->def) 22172 return(bind); 22173 if (bind->next == NULL) { 22174 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22175 if (bind->next == NULL) 22176 return (NULL); 22177 return(bind->next); 22178 } 22179 bind = bind->next; 22180 } while (bind != NULL); 22181 } 22182 return (NULL); 22183 } 22184 22185 static xmlSchemaItemListPtr 22186 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22187 xmlSchemaIDCMatcherPtr matcher) 22188 { 22189 if (matcher->targets == NULL) 22190 matcher->targets = xmlSchemaItemListCreate(); 22191 return(matcher->targets); 22192 } 22193 22194 /** 22195 * xmlSchemaIDCFreeKey: 22196 * @key: the IDC key 22197 * 22198 * Frees an IDC key together with its compiled value. 22199 */ 22200 static void 22201 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22202 { 22203 if (key->val != NULL) 22204 xmlSchemaFreeValue(key->val); 22205 xmlFree(key); 22206 } 22207 22208 /** 22209 * xmlSchemaIDCFreeBinding: 22210 * 22211 * Frees an IDC binding. Note that the node table-items 22212 * are not freed. 22213 */ 22214 static void 22215 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22216 { 22217 if (bind->nodeTable != NULL) 22218 xmlFree(bind->nodeTable); 22219 if (bind->dupls != NULL) 22220 xmlSchemaItemListFree(bind->dupls); 22221 xmlFree(bind); 22222 } 22223 22224 /** 22225 * xmlSchemaIDCFreeIDCTable: 22226 * @bind: the first IDC binding in the list 22227 * 22228 * Frees an IDC table, i.e. all the IDC bindings in the list. 22229 */ 22230 static void 22231 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22232 { 22233 xmlSchemaPSVIIDCBindingPtr prev; 22234 22235 while (bind != NULL) { 22236 prev = bind; 22237 bind = bind->next; 22238 xmlSchemaIDCFreeBinding(prev); 22239 } 22240 } 22241 22242 /** 22243 * xmlSchemaIDCFreeMatcherList: 22244 * @matcher: the first IDC matcher in the list 22245 * 22246 * Frees a list of IDC matchers. 22247 */ 22248 static void 22249 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22250 { 22251 xmlSchemaIDCMatcherPtr next; 22252 22253 while (matcher != NULL) { 22254 next = matcher->next; 22255 if (matcher->keySeqs != NULL) { 22256 int i; 22257 for (i = 0; i < matcher->sizeKeySeqs; i++) 22258 if (matcher->keySeqs[i] != NULL) 22259 xmlFree(matcher->keySeqs[i]); 22260 xmlFree(matcher->keySeqs); 22261 } 22262 if (matcher->targets != NULL) { 22263 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22264 int i; 22265 xmlSchemaPSVIIDCNodePtr idcNode; 22266 /* 22267 * Node-table items for keyrefs are not stored globally 22268 * to the validation context, since they are not bubbled. 22269 * We need to free them here. 22270 */ 22271 for (i = 0; i < matcher->targets->nbItems; i++) { 22272 idcNode = 22273 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22274 xmlFree(idcNode->keys); 22275 xmlFree(idcNode); 22276 } 22277 } 22278 xmlSchemaItemListFree(matcher->targets); 22279 } 22280 xmlFree(matcher); 22281 matcher = next; 22282 } 22283 } 22284 22285 /** 22286 * xmlSchemaIDCReleaseMatcherList: 22287 * @vctxt: the WXS validation context 22288 * @matcher: the first IDC matcher in the list 22289 * 22290 * Caches a list of IDC matchers for reuse. 22291 */ 22292 static void 22293 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22294 xmlSchemaIDCMatcherPtr matcher) 22295 { 22296 xmlSchemaIDCMatcherPtr next; 22297 22298 while (matcher != NULL) { 22299 next = matcher->next; 22300 if (matcher->keySeqs != NULL) { 22301 int i; 22302 /* 22303 * Don't free the array, but only the content. 22304 */ 22305 for (i = 0; i < matcher->sizeKeySeqs; i++) 22306 if (matcher->keySeqs[i] != NULL) { 22307 xmlFree(matcher->keySeqs[i]); 22308 matcher->keySeqs[i] = NULL; 22309 } 22310 } 22311 if (matcher->targets) { 22312 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22313 int i; 22314 xmlSchemaPSVIIDCNodePtr idcNode; 22315 /* 22316 * Node-table items for keyrefs are not stored globally 22317 * to the validation context, since they are not bubbled. 22318 * We need to free them here. 22319 */ 22320 for (i = 0; i < matcher->targets->nbItems; i++) { 22321 idcNode = 22322 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22323 xmlFree(idcNode->keys); 22324 xmlFree(idcNode); 22325 } 22326 } 22327 xmlSchemaItemListFree(matcher->targets); 22328 matcher->targets = NULL; 22329 } 22330 matcher->next = NULL; 22331 /* 22332 * Cache the matcher. 22333 */ 22334 if (vctxt->idcMatcherCache != NULL) 22335 matcher->nextCached = vctxt->idcMatcherCache; 22336 vctxt->idcMatcherCache = matcher; 22337 22338 matcher = next; 22339 } 22340 } 22341 22342 /** 22343 * xmlSchemaIDCAddStateObject: 22344 * @vctxt: the WXS validation context 22345 * @matcher: the IDC matcher 22346 * @sel: the XPath information 22347 * @parent: the parent "selector" state object if any 22348 * @type: "selector" or "field" 22349 * 22350 * Creates/reuses and activates state objects for the given 22351 * XPath information; if the XPath expression consists of unions, 22352 * multiple state objects are created for every unioned expression. 22353 * 22354 * Returns 0 on success and -1 on internal errors. 22355 */ 22356 static int 22357 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22358 xmlSchemaIDCMatcherPtr matcher, 22359 xmlSchemaIDCSelectPtr sel, 22360 int type) 22361 { 22362 xmlSchemaIDCStateObjPtr sto; 22363 22364 /* 22365 * Reuse the state objects from the pool. 22366 */ 22367 if (vctxt->xpathStatePool != NULL) { 22368 sto = vctxt->xpathStatePool; 22369 vctxt->xpathStatePool = sto->next; 22370 sto->next = NULL; 22371 } else { 22372 /* 22373 * Create a new state object. 22374 */ 22375 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22376 if (sto == NULL) { 22377 xmlSchemaVErrMemory(NULL, 22378 "allocating an IDC state object", NULL); 22379 return (-1); 22380 } 22381 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22382 } 22383 /* 22384 * Add to global list. 22385 */ 22386 if (vctxt->xpathStates != NULL) 22387 sto->next = vctxt->xpathStates; 22388 vctxt->xpathStates = sto; 22389 22390 /* 22391 * Free the old xpath validation context. 22392 */ 22393 if (sto->xpathCtxt != NULL) 22394 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22395 22396 /* 22397 * Create a new XPath (pattern) validation context. 22398 */ 22399 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22400 (xmlPatternPtr) sel->xpathComp); 22401 if (sto->xpathCtxt == NULL) { 22402 VERROR_INT("xmlSchemaIDCAddStateObject", 22403 "failed to create an XPath validation context"); 22404 return (-1); 22405 } 22406 sto->type = type; 22407 sto->depth = vctxt->depth; 22408 sto->matcher = matcher; 22409 sto->sel = sel; 22410 sto->nbHistory = 0; 22411 22412 #ifdef DEBUG_IDC 22413 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22414 sto->sel->xpath); 22415 #endif 22416 return (0); 22417 } 22418 22419 /** 22420 * xmlSchemaXPathEvaluate: 22421 * @vctxt: the WXS validation context 22422 * @nodeType: the nodeType of the current node 22423 * 22424 * Evaluates all active XPath state objects. 22425 * 22426 * Returns the number of IC "field" state objects which resolved to 22427 * this node, 0 if none resolved and -1 on internal errors. 22428 */ 22429 static int 22430 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22431 xmlElementType nodeType) 22432 { 22433 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22434 int res, resolved = 0, depth = vctxt->depth; 22435 22436 if (vctxt->xpathStates == NULL) 22437 return (0); 22438 22439 if (nodeType == XML_ATTRIBUTE_NODE) 22440 depth++; 22441 #ifdef DEBUG_IDC 22442 { 22443 xmlChar *str = NULL; 22444 xmlGenericError(xmlGenericErrorContext, 22445 "IDC: EVAL on %s, depth %d, type %d\n", 22446 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22447 vctxt->inode->localName), depth, nodeType); 22448 FREE_AND_NULL(str) 22449 } 22450 #endif 22451 /* 22452 * Process all active XPath state objects. 22453 */ 22454 first = vctxt->xpathStates; 22455 sto = first; 22456 while (sto != head) { 22457 #ifdef DEBUG_IDC 22458 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22459 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22460 sto->matcher->aidc->def->name, sto->sel->xpath); 22461 else 22462 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22463 sto->matcher->aidc->def->name, sto->sel->xpath); 22464 #endif 22465 if (nodeType == XML_ELEMENT_NODE) 22466 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22467 vctxt->inode->localName, vctxt->inode->nsName); 22468 else 22469 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22470 vctxt->inode->localName, vctxt->inode->nsName); 22471 22472 if (res == -1) { 22473 VERROR_INT("xmlSchemaXPathEvaluate", 22474 "calling xmlStreamPush()"); 22475 return (-1); 22476 } 22477 if (res == 0) 22478 goto next_sto; 22479 /* 22480 * Full match. 22481 */ 22482 #ifdef DEBUG_IDC 22483 xmlGenericError(xmlGenericErrorContext, "IDC: " 22484 "MATCH\n"); 22485 #endif 22486 /* 22487 * Register a match in the state object history. 22488 */ 22489 if (sto->history == NULL) { 22490 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22491 if (sto->history == NULL) { 22492 xmlSchemaVErrMemory(NULL, 22493 "allocating the state object history", NULL); 22494 return(-1); 22495 } 22496 sto->sizeHistory = 5; 22497 } else if (sto->sizeHistory <= sto->nbHistory) { 22498 sto->sizeHistory *= 2; 22499 sto->history = (int *) xmlRealloc(sto->history, 22500 sto->sizeHistory * sizeof(int)); 22501 if (sto->history == NULL) { 22502 xmlSchemaVErrMemory(NULL, 22503 "re-allocating the state object history", NULL); 22504 return(-1); 22505 } 22506 } 22507 sto->history[sto->nbHistory++] = depth; 22508 22509 #ifdef DEBUG_IDC 22510 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22511 vctxt->depth); 22512 #endif 22513 22514 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22515 xmlSchemaIDCSelectPtr sel; 22516 /* 22517 * Activate state objects for the IDC fields of 22518 * the IDC selector. 22519 */ 22520 #ifdef DEBUG_IDC 22521 xmlGenericError(xmlGenericErrorContext, "IDC: " 22522 "activating field states\n"); 22523 #endif 22524 sel = sto->matcher->aidc->def->fields; 22525 while (sel != NULL) { 22526 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22527 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22528 return (-1); 22529 sel = sel->next; 22530 } 22531 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22532 /* 22533 * An IDC key node was found by the IDC field. 22534 */ 22535 #ifdef DEBUG_IDC 22536 xmlGenericError(xmlGenericErrorContext, 22537 "IDC: key found\n"); 22538 #endif 22539 /* 22540 * Notify that the character value of this node is 22541 * needed. 22542 */ 22543 if (resolved == 0) { 22544 if ((vctxt->inode->flags & 22545 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22546 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22547 } 22548 resolved++; 22549 } 22550 next_sto: 22551 if (sto->next == NULL) { 22552 /* 22553 * Evaluate field state objects created on this node as well. 22554 */ 22555 head = first; 22556 sto = vctxt->xpathStates; 22557 } else 22558 sto = sto->next; 22559 } 22560 return (resolved); 22561 } 22562 22563 static const xmlChar * 22564 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22565 xmlChar **buf, 22566 xmlSchemaPSVIIDCKeyPtr *seq, 22567 int count) 22568 { 22569 int i, res; 22570 xmlChar *value = NULL; 22571 22572 *buf = xmlStrdup(BAD_CAST "["); 22573 for (i = 0; i < count; i++) { 22574 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22575 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22576 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22577 &value); 22578 if (res == 0) 22579 *buf = xmlStrcat(*buf, BAD_CAST value); 22580 else { 22581 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22582 "failed to compute a canonical value"); 22583 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22584 } 22585 if (i < count -1) 22586 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22587 else 22588 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22589 if (value != NULL) { 22590 xmlFree(value); 22591 value = NULL; 22592 } 22593 } 22594 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22595 22596 return (BAD_CAST *buf); 22597 } 22598 22599 /** 22600 * xmlSchemaXPathPop: 22601 * @vctxt: the WXS validation context 22602 * 22603 * Pops all XPath states. 22604 * 22605 * Returns 0 on success and -1 on internal errors. 22606 */ 22607 static int 22608 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22609 { 22610 xmlSchemaIDCStateObjPtr sto; 22611 int res; 22612 22613 if (vctxt->xpathStates == NULL) 22614 return(0); 22615 sto = vctxt->xpathStates; 22616 do { 22617 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22618 if (res == -1) 22619 return (-1); 22620 sto = sto->next; 22621 } while (sto != NULL); 22622 return(0); 22623 } 22624 22625 /** 22626 * xmlSchemaXPathProcessHistory: 22627 * @vctxt: the WXS validation context 22628 * @type: the simple/complex type of the current node if any at all 22629 * @val: the precompiled value 22630 * 22631 * Processes and pops the history items of the IDC state objects. 22632 * IDC key-sequences are validated/created on IDC bindings. 22633 * 22634 * Returns 0 on success and -1 on internal errors. 22635 */ 22636 static int 22637 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22638 int depth) 22639 { 22640 xmlSchemaIDCStateObjPtr sto, nextsto; 22641 int res, matchDepth; 22642 xmlSchemaPSVIIDCKeyPtr key = NULL; 22643 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22644 22645 if (vctxt->xpathStates == NULL) 22646 return (0); 22647 sto = vctxt->xpathStates; 22648 22649 #ifdef DEBUG_IDC 22650 { 22651 xmlChar *str = NULL; 22652 xmlGenericError(xmlGenericErrorContext, 22653 "IDC: BACK on %s, depth %d\n", 22654 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22655 vctxt->inode->localName), vctxt->depth); 22656 FREE_AND_NULL(str) 22657 } 22658 #endif 22659 /* 22660 * Evaluate the state objects. 22661 */ 22662 while (sto != NULL) { 22663 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22664 if (res == -1) { 22665 VERROR_INT("xmlSchemaXPathProcessHistory", 22666 "calling xmlStreamPop()"); 22667 return (-1); 22668 } 22669 #ifdef DEBUG_IDC 22670 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22671 sto->sel->xpath); 22672 #endif 22673 if (sto->nbHistory == 0) 22674 goto deregister_check; 22675 22676 matchDepth = sto->history[sto->nbHistory -1]; 22677 22678 /* 22679 * Only matches at the current depth are of interest. 22680 */ 22681 if (matchDepth != depth) { 22682 sto = sto->next; 22683 continue; 22684 } 22685 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22686 /* 22687 * NOTE: According to 22688 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22689 * ... the simple-content of complex types is also allowed. 22690 */ 22691 22692 if (WXS_IS_COMPLEX(type)) { 22693 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22694 /* 22695 * Sanity check for complex types with simple content. 22696 */ 22697 simpleType = type->contentTypeDef; 22698 if (simpleType == NULL) { 22699 VERROR_INT("xmlSchemaXPathProcessHistory", 22700 "field resolves to a CT with simple content " 22701 "but the CT is missing the ST definition"); 22702 return (-1); 22703 } 22704 } else 22705 simpleType = NULL; 22706 } else 22707 simpleType = type; 22708 if (simpleType == NULL) { 22709 xmlChar *str = NULL; 22710 22711 /* 22712 * Not qualified if the field resolves to a node of non 22713 * simple type. 22714 */ 22715 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22716 XML_SCHEMAV_CVC_IDC, NULL, 22717 WXS_BASIC_CAST sto->matcher->aidc->def, 22718 "The XPath '%s' of a field of %s does evaluate to a node of " 22719 "non-simple type", 22720 sto->sel->xpath, 22721 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22722 FREE_AND_NULL(str); 22723 sto->nbHistory--; 22724 goto deregister_check; 22725 } 22726 22727 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22728 /* 22729 * Failed to provide the normalized value; maybe 22730 * the value was invalid. 22731 */ 22732 VERROR(XML_SCHEMAV_CVC_IDC, 22733 WXS_BASIC_CAST sto->matcher->aidc->def, 22734 "Warning: No precomputed value available, the value " 22735 "was either invalid or something strange happend"); 22736 sto->nbHistory--; 22737 goto deregister_check; 22738 } else { 22739 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22740 xmlSchemaPSVIIDCKeyPtr *keySeq; 22741 int pos, idx; 22742 22743 /* 22744 * The key will be anchored on the matcher's list of 22745 * key-sequences. The position in this list is determined 22746 * by the target node's depth relative to the matcher's 22747 * depth of creation (i.e. the depth of the scope element). 22748 * 22749 * Element Depth Pos List-entries 22750 * <scope> 0 NULL 22751 * <bar> 1 NULL 22752 * <target/> 2 2 target 22753 * <bar> 22754 * </scope> 22755 * 22756 * The size of the list is only dependant on the depth of 22757 * the tree. 22758 * An entry will be NULLed in selector_leave, i.e. when 22759 * we hit the target's 22760 */ 22761 pos = sto->depth - matcher->depth; 22762 idx = sto->sel->index; 22763 22764 /* 22765 * Create/grow the array of key-sequences. 22766 */ 22767 if (matcher->keySeqs == NULL) { 22768 if (pos > 9) 22769 matcher->sizeKeySeqs = pos * 2; 22770 else 22771 matcher->sizeKeySeqs = 10; 22772 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22773 xmlMalloc(matcher->sizeKeySeqs * 22774 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22775 if (matcher->keySeqs == NULL) { 22776 xmlSchemaVErrMemory(NULL, 22777 "allocating an array of key-sequences", 22778 NULL); 22779 return(-1); 22780 } 22781 memset(matcher->keySeqs, 0, 22782 matcher->sizeKeySeqs * 22783 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22784 } else if (pos >= matcher->sizeKeySeqs) { 22785 int i = matcher->sizeKeySeqs; 22786 22787 matcher->sizeKeySeqs *= 2; 22788 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22789 xmlRealloc(matcher->keySeqs, 22790 matcher->sizeKeySeqs * 22791 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22792 if (matcher->keySeqs == NULL) { 22793 xmlSchemaVErrMemory(NULL, 22794 "reallocating an array of key-sequences", 22795 NULL); 22796 return (-1); 22797 } 22798 /* 22799 * The array needs to be NULLed. 22800 * TODO: Use memset? 22801 */ 22802 for (; i < matcher->sizeKeySeqs; i++) 22803 matcher->keySeqs[i] = NULL; 22804 } 22805 22806 /* 22807 * Get/create the key-sequence. 22808 */ 22809 keySeq = matcher->keySeqs[pos]; 22810 if (keySeq == NULL) { 22811 goto create_sequence; 22812 } else if (keySeq[idx] != NULL) { 22813 xmlChar *str = NULL; 22814 /* 22815 * cvc-identity-constraint: 22816 * 3 For each node in the target node set all 22817 * of the {fields}, with that node as the context 22818 * node, evaluate to either an empty node-set or 22819 * a node-set with exactly one member, which must 22820 * have a simple type. 22821 * 22822 * The key was already set; report an error. 22823 */ 22824 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22825 XML_SCHEMAV_CVC_IDC, NULL, 22826 WXS_BASIC_CAST matcher->aidc->def, 22827 "The XPath '%s' of a field of %s evaluates to a " 22828 "node-set with more than one member", 22829 sto->sel->xpath, 22830 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22831 FREE_AND_NULL(str); 22832 sto->nbHistory--; 22833 goto deregister_check; 22834 } else 22835 goto create_key; 22836 22837 create_sequence: 22838 /* 22839 * Create a key-sequence. 22840 */ 22841 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22842 matcher->aidc->def->nbFields * 22843 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22844 if (keySeq == NULL) { 22845 xmlSchemaVErrMemory(NULL, 22846 "allocating an IDC key-sequence", NULL); 22847 return(-1); 22848 } 22849 memset(keySeq, 0, matcher->aidc->def->nbFields * 22850 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22851 matcher->keySeqs[pos] = keySeq; 22852 create_key: 22853 /* 22854 * Create a key once per node only. 22855 */ 22856 if (key == NULL) { 22857 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22858 sizeof(xmlSchemaPSVIIDCKey)); 22859 if (key == NULL) { 22860 xmlSchemaVErrMemory(NULL, 22861 "allocating a IDC key", NULL); 22862 xmlFree(keySeq); 22863 matcher->keySeqs[pos] = NULL; 22864 return(-1); 22865 } 22866 /* 22867 * Consume the compiled value. 22868 */ 22869 key->type = simpleType; 22870 key->val = vctxt->inode->val; 22871 vctxt->inode->val = NULL; 22872 /* 22873 * Store the key in a global list. 22874 */ 22875 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22876 xmlSchemaIDCFreeKey(key); 22877 return (-1); 22878 } 22879 } 22880 keySeq[idx] = key; 22881 } 22882 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22883 22884 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22885 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22886 xmlSchemaPSVIIDCNodePtr ntItem; 22887 xmlSchemaIDCMatcherPtr matcher; 22888 xmlSchemaIDCPtr idc; 22889 xmlSchemaItemListPtr targets; 22890 int pos, i, j, nbKeys; 22891 /* 22892 * Here we have the following scenario: 22893 * An IDC 'selector' state object resolved to a target node, 22894 * during the time this target node was in the 22895 * ancestor-or-self axis, the 'field' state object(s) looked 22896 * out for matching nodes to create a key-sequence for this 22897 * target node. Now we are back to this target node and need 22898 * to put the key-sequence, together with the target node 22899 * itself, into the node-table of the corresponding IDC 22900 * binding. 22901 */ 22902 matcher = sto->matcher; 22903 idc = matcher->aidc->def; 22904 nbKeys = idc->nbFields; 22905 pos = depth - matcher->depth; 22906 /* 22907 * Check if the matcher has any key-sequences at all, plus 22908 * if it has a key-sequence for the current target node. 22909 */ 22910 if ((matcher->keySeqs == NULL) || 22911 (matcher->sizeKeySeqs <= pos)) { 22912 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22913 goto selector_key_error; 22914 else 22915 goto selector_leave; 22916 } 22917 22918 keySeq = &(matcher->keySeqs[pos]); 22919 if (*keySeq == NULL) { 22920 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22921 goto selector_key_error; 22922 else 22923 goto selector_leave; 22924 } 22925 22926 for (i = 0; i < nbKeys; i++) { 22927 if ((*keySeq)[i] == NULL) { 22928 /* 22929 * Not qualified, if not all fields did resolve. 22930 */ 22931 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22932 /* 22933 * All fields of a "key" IDC must resolve. 22934 */ 22935 goto selector_key_error; 22936 } 22937 goto selector_leave; 22938 } 22939 } 22940 /* 22941 * All fields did resolve. 22942 */ 22943 22944 /* 22945 * 4.1 If the {identity-constraint category} is unique(/key), 22946 * then no two members of the qualified node set have 22947 * key-sequences whose members are pairwise equal, as 22948 * defined by Equal in [XML Schemas: Datatypes]. 22949 * 22950 * Get the IDC binding from the matcher and check for 22951 * duplicate key-sequences. 22952 */ 22953 #if 0 22954 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 22955 #endif 22956 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 22957 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 22958 (targets->nbItems != 0)) { 22959 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 22960 22961 i = 0; 22962 res = 0; 22963 /* 22964 * Compare the key-sequences, key by key. 22965 */ 22966 do { 22967 bkeySeq = 22968 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 22969 for (j = 0; j < nbKeys; j++) { 22970 ckey = (*keySeq)[j]; 22971 bkey = bkeySeq[j]; 22972 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 22973 if (res == -1) { 22974 return (-1); 22975 } else if (res == 0) { 22976 /* 22977 * One of the keys differs, so the key-sequence 22978 * won't be equal; get out. 22979 */ 22980 break; 22981 } 22982 } 22983 if (res == 1) { 22984 /* 22985 * Duplicate key-sequence found. 22986 */ 22987 break; 22988 } 22989 i++; 22990 } while (i < targets->nbItems); 22991 if (i != targets->nbItems) { 22992 xmlChar *str = NULL, *strB = NULL; 22993 /* 22994 * TODO: Try to report the key-sequence. 22995 */ 22996 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22997 XML_SCHEMAV_CVC_IDC, NULL, 22998 WXS_BASIC_CAST idc, 22999 "Duplicate key-sequence %s in %s", 23000 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23001 (*keySeq), nbKeys), 23002 xmlSchemaGetIDCDesignation(&strB, idc)); 23003 FREE_AND_NULL(str); 23004 FREE_AND_NULL(strB); 23005 goto selector_leave; 23006 } 23007 } 23008 /* 23009 * Add a node-table item to the IDC binding. 23010 */ 23011 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23012 sizeof(xmlSchemaPSVIIDCNode)); 23013 if (ntItem == NULL) { 23014 xmlSchemaVErrMemory(NULL, 23015 "allocating an IDC node-table item", NULL); 23016 xmlFree(*keySeq); 23017 *keySeq = NULL; 23018 return(-1); 23019 } 23020 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23021 23022 /* 23023 * Store the node-table item in a global list. 23024 */ 23025 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23026 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23027 xmlFree(ntItem); 23028 xmlFree(*keySeq); 23029 *keySeq = NULL; 23030 return (-1); 23031 } 23032 ntItem->nodeQNameID = -1; 23033 } else { 23034 /* 23035 * Save a cached QName for this node on the IDC node, to be 23036 * able to report it, even if the node is not saved. 23037 */ 23038 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23039 vctxt->inode->localName, vctxt->inode->nsName); 23040 if (ntItem->nodeQNameID == -1) { 23041 xmlFree(ntItem); 23042 xmlFree(*keySeq); 23043 *keySeq = NULL; 23044 return (-1); 23045 } 23046 } 23047 /* 23048 * Init the node-table item: Save the node, position and 23049 * consume the key-sequence. 23050 */ 23051 ntItem->node = vctxt->node; 23052 ntItem->nodeLine = vctxt->inode->nodeLine; 23053 ntItem->keys = *keySeq; 23054 *keySeq = NULL; 23055 #if 0 23056 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23057 #endif 23058 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23059 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23060 /* 23061 * Free the item, since keyref items won't be 23062 * put on a global list. 23063 */ 23064 xmlFree(ntItem->keys); 23065 xmlFree(ntItem); 23066 } 23067 return (-1); 23068 } 23069 23070 goto selector_leave; 23071 selector_key_error: 23072 { 23073 xmlChar *str = NULL; 23074 /* 23075 * 4.2.1 (KEY) The target node set and the 23076 * qualified node set are equal, that is, every 23077 * member of the target node set is also a member 23078 * of the qualified node set and vice versa. 23079 */ 23080 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23081 XML_SCHEMAV_CVC_IDC, NULL, 23082 WXS_BASIC_CAST idc, 23083 "Not all fields of %s evaluate to a node", 23084 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23085 FREE_AND_NULL(str); 23086 } 23087 selector_leave: 23088 /* 23089 * Free the key-sequence if not added to the IDC table. 23090 */ 23091 if ((keySeq != NULL) && (*keySeq != NULL)) { 23092 xmlFree(*keySeq); 23093 *keySeq = NULL; 23094 } 23095 } /* if selector */ 23096 23097 sto->nbHistory--; 23098 23099 deregister_check: 23100 /* 23101 * Deregister state objects if they reach the depth of creation. 23102 */ 23103 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23104 #ifdef DEBUG_IDC 23105 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23106 sto->sel->xpath); 23107 #endif 23108 if (vctxt->xpathStates != sto) { 23109 VERROR_INT("xmlSchemaXPathProcessHistory", 23110 "The state object to be removed is not the first " 23111 "in the list"); 23112 } 23113 nextsto = sto->next; 23114 /* 23115 * Unlink from the list of active XPath state objects. 23116 */ 23117 vctxt->xpathStates = sto->next; 23118 sto->next = vctxt->xpathStatePool; 23119 /* 23120 * Link it to the pool of reusable state objects. 23121 */ 23122 vctxt->xpathStatePool = sto; 23123 sto = nextsto; 23124 } else 23125 sto = sto->next; 23126 } /* while (sto != NULL) */ 23127 return (0); 23128 } 23129 23130 /** 23131 * xmlSchemaIDCRegisterMatchers: 23132 * @vctxt: the WXS validation context 23133 * @elemDecl: the element declaration 23134 * 23135 * Creates helper objects to evaluate IDC selectors/fields 23136 * successively. 23137 * 23138 * Returns 0 if OK and -1 on internal errors. 23139 */ 23140 static int 23141 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23142 xmlSchemaElementPtr elemDecl) 23143 { 23144 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23145 xmlSchemaIDCPtr idc, refIdc; 23146 xmlSchemaIDCAugPtr aidc; 23147 23148 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23149 if (idc == NULL) 23150 return (0); 23151 23152 #ifdef DEBUG_IDC 23153 { 23154 xmlChar *str = NULL; 23155 xmlGenericError(xmlGenericErrorContext, 23156 "IDC: REGISTER on %s, depth %d\n", 23157 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23158 vctxt->inode->localName), vctxt->depth); 23159 FREE_AND_NULL(str) 23160 } 23161 #endif 23162 if (vctxt->inode->idcMatchers != NULL) { 23163 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23164 "The chain of IDC matchers is expected to be empty"); 23165 return (-1); 23166 } 23167 do { 23168 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23169 /* 23170 * Since IDCs bubbles are expensive we need to know the 23171 * depth at which the bubbles should stop; this will be 23172 * the depth of the top-most keyref IDC. If no keyref 23173 * references a key/unique IDC, the keyrefDepth will 23174 * be -1, indicating that no bubbles are needed. 23175 */ 23176 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23177 if (refIdc != NULL) { 23178 /* 23179 * Remember that we have keyrefs on this node. 23180 */ 23181 vctxt->inode->hasKeyrefs = 1; 23182 /* 23183 * Lookup the referenced augmented IDC info. 23184 */ 23185 aidc = vctxt->aidcs; 23186 while (aidc != NULL) { 23187 if (aidc->def == refIdc) 23188 break; 23189 aidc = aidc->next; 23190 } 23191 if (aidc == NULL) { 23192 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23193 "Could not find an augmented IDC item for an IDC " 23194 "definition"); 23195 return (-1); 23196 } 23197 if ((aidc->keyrefDepth == -1) || 23198 (vctxt->depth < aidc->keyrefDepth)) 23199 aidc->keyrefDepth = vctxt->depth; 23200 } 23201 } 23202 /* 23203 * Lookup the augmented IDC item for the IDC definition. 23204 */ 23205 aidc = vctxt->aidcs; 23206 while (aidc != NULL) { 23207 if (aidc->def == idc) 23208 break; 23209 aidc = aidc->next; 23210 } 23211 if (aidc == NULL) { 23212 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23213 "Could not find an augmented IDC item for an IDC definition"); 23214 return (-1); 23215 } 23216 /* 23217 * Create an IDC matcher for every IDC definition. 23218 */ 23219 if (vctxt->idcMatcherCache != NULL) { 23220 /* 23221 * Reuse a cached matcher. 23222 */ 23223 matcher = vctxt->idcMatcherCache; 23224 vctxt->idcMatcherCache = matcher->nextCached; 23225 matcher->nextCached = NULL; 23226 } else { 23227 matcher = (xmlSchemaIDCMatcherPtr) 23228 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23229 if (matcher == NULL) { 23230 xmlSchemaVErrMemory(vctxt, 23231 "allocating an IDC matcher", NULL); 23232 return (-1); 23233 } 23234 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23235 } 23236 if (last == NULL) 23237 vctxt->inode->idcMatchers = matcher; 23238 else 23239 last->next = matcher; 23240 last = matcher; 23241 23242 matcher->type = IDC_MATCHER; 23243 matcher->depth = vctxt->depth; 23244 matcher->aidc = aidc; 23245 matcher->idcType = aidc->def->type; 23246 #ifdef DEBUG_IDC 23247 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23248 #endif 23249 /* 23250 * Init the automaton state object. 23251 */ 23252 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23253 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23254 return (-1); 23255 23256 idc = idc->next; 23257 } while (idc != NULL); 23258 return (0); 23259 } 23260 23261 static int 23262 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23263 xmlSchemaNodeInfoPtr ielem) 23264 { 23265 xmlSchemaPSVIIDCBindingPtr bind; 23266 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23267 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23268 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23269 23270 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23271 /* vctxt->createIDCNodeTables */ 23272 while (matcher != NULL) { 23273 /* 23274 * Skip keyref IDCs and empty IDC target-lists. 23275 */ 23276 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23277 WXS_ILIST_IS_EMPTY(matcher->targets)) 23278 { 23279 matcher = matcher->next; 23280 continue; 23281 } 23282 /* 23283 * If we _want_ the IDC node-table to be created in any case 23284 * then do so. Otherwise create them only if keyrefs need them. 23285 */ 23286 if ((! vctxt->createIDCNodeTables) && 23287 ((matcher->aidc->keyrefDepth == -1) || 23288 (matcher->aidc->keyrefDepth > vctxt->depth))) 23289 { 23290 matcher = matcher->next; 23291 continue; 23292 } 23293 /* 23294 * Get/create the IDC binding on this element for the IDC definition. 23295 */ 23296 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23297 23298 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23299 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23300 nbDupls = bind->dupls->nbItems; 23301 } else { 23302 dupls = NULL; 23303 nbDupls = 0; 23304 } 23305 if (bind->nodeTable != NULL) { 23306 nbNodeTable = bind->nbNodes; 23307 } else { 23308 nbNodeTable = 0; 23309 } 23310 23311 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23312 /* 23313 * Transfer all IDC target-nodes to the IDC node-table. 23314 */ 23315 bind->nodeTable = 23316 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23317 bind->sizeNodes = matcher->targets->sizeItems; 23318 bind->nbNodes = matcher->targets->nbItems; 23319 23320 matcher->targets->items = NULL; 23321 matcher->targets->sizeItems = 0; 23322 matcher->targets->nbItems = 0; 23323 } else { 23324 /* 23325 * Compare the key-sequences and add to the IDC node-table. 23326 */ 23327 nbTargets = matcher->targets->nbItems; 23328 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23329 nbFields = matcher->aidc->def->nbFields; 23330 i = 0; 23331 do { 23332 keys = targets[i]->keys; 23333 if (nbDupls) { 23334 /* 23335 * Search in already found duplicates first. 23336 */ 23337 j = 0; 23338 do { 23339 if (nbFields == 1) { 23340 res = xmlSchemaAreValuesEqual(keys[0]->val, 23341 dupls[j]->keys[0]->val); 23342 if (res == -1) 23343 goto internal_error; 23344 if (res == 1) { 23345 /* 23346 * Equal key-sequence. 23347 */ 23348 goto next_target; 23349 } 23350 } else { 23351 res = 0; 23352 ntkeys = dupls[j]->keys; 23353 for (k = 0; k < nbFields; k++) { 23354 res = xmlSchemaAreValuesEqual(keys[k]->val, 23355 ntkeys[k]->val); 23356 if (res == -1) 23357 goto internal_error; 23358 if (res == 0) { 23359 /* 23360 * One of the keys differs. 23361 */ 23362 break; 23363 } 23364 } 23365 if (res == 1) { 23366 /* 23367 * Equal key-sequence found. 23368 */ 23369 goto next_target; 23370 } 23371 } 23372 j++; 23373 } while (j < nbDupls); 23374 } 23375 if (nbNodeTable) { 23376 j = 0; 23377 do { 23378 if (nbFields == 1) { 23379 res = xmlSchemaAreValuesEqual(keys[0]->val, 23380 bind->nodeTable[j]->keys[0]->val); 23381 if (res == -1) 23382 goto internal_error; 23383 if (res == 0) { 23384 /* 23385 * The key-sequence differs. 23386 */ 23387 goto next_node_table_entry; 23388 } 23389 } else { 23390 res = 0; 23391 ntkeys = bind->nodeTable[j]->keys; 23392 for (k = 0; k < nbFields; k++) { 23393 res = xmlSchemaAreValuesEqual(keys[k]->val, 23394 ntkeys[k]->val); 23395 if (res == -1) 23396 goto internal_error; 23397 if (res == 0) { 23398 /* 23399 * One of the keys differs. 23400 */ 23401 goto next_node_table_entry; 23402 } 23403 } 23404 } 23405 /* 23406 * Add the duplicate to the list of duplicates. 23407 */ 23408 if (bind->dupls == NULL) { 23409 bind->dupls = xmlSchemaItemListCreate(); 23410 if (bind->dupls == NULL) 23411 goto internal_error; 23412 } 23413 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23414 goto internal_error; 23415 /* 23416 * Remove the duplicate entry from the IDC node-table. 23417 */ 23418 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23419 bind->nbNodes--; 23420 23421 goto next_target; 23422 23423 next_node_table_entry: 23424 j++; 23425 } while (j < nbNodeTable); 23426 } 23427 /* 23428 * If everything is fine, then add the IDC target-node to 23429 * the IDC node-table. 23430 */ 23431 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23432 goto internal_error; 23433 23434 next_target: 23435 i++; 23436 } while (i < nbTargets); 23437 } 23438 matcher = matcher->next; 23439 } 23440 return(0); 23441 23442 internal_error: 23443 return(-1); 23444 } 23445 23446 /** 23447 * xmlSchemaBubbleIDCNodeTables: 23448 * @depth: the current tree depth 23449 * 23450 * Merges IDC bindings of an element at @depth into the corresponding IDC 23451 * bindings of its parent element. If a duplicate note-table entry is found, 23452 * both, the parent node-table entry and child entry are discarded from the 23453 * node-table of the parent. 23454 * 23455 * Returns 0 if OK and -1 on internal errors. 23456 */ 23457 static int 23458 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23459 { 23460 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23461 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23462 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23463 xmlSchemaIDCAugPtr aidc; 23464 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23465 23466 bind = vctxt->inode->idcTable; 23467 if (bind == NULL) { 23468 /* Fine, no table, no bubbles. */ 23469 return (0); 23470 } 23471 23472 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23473 /* 23474 * Walk all bindings; create new or add to existing bindings. 23475 * Remove duplicate key-sequences. 23476 */ 23477 while (bind != NULL) { 23478 23479 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23480 goto next_binding; 23481 /* 23482 * Check if the key/unique IDC table needs to be bubbled. 23483 */ 23484 if (! vctxt->createIDCNodeTables) { 23485 aidc = vctxt->aidcs; 23486 do { 23487 if (aidc->def == bind->definition) { 23488 if ((aidc->keyrefDepth == -1) || 23489 (aidc->keyrefDepth >= vctxt->depth)) { 23490 goto next_binding; 23491 } 23492 break; 23493 } 23494 aidc = aidc->next; 23495 } while (aidc != NULL); 23496 } 23497 23498 if (parTable != NULL) 23499 parBind = *parTable; 23500 /* 23501 * Search a matching parent binding for the 23502 * IDC definition. 23503 */ 23504 while (parBind != NULL) { 23505 if (parBind->definition == bind->definition) 23506 break; 23507 parBind = parBind->next; 23508 } 23509 23510 if (parBind != NULL) { 23511 /* 23512 * Compare every node-table entry of the child node, 23513 * i.e. the key-sequence within, ... 23514 */ 23515 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23516 23517 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23518 oldDupls = parBind->dupls->nbItems; 23519 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23520 } else { 23521 dupls = NULL; 23522 oldDupls = 0; 23523 } 23524 23525 parNodes = parBind->nodeTable; 23526 nbFields = bind->definition->nbFields; 23527 23528 for (i = 0; i < bind->nbNodes; i++) { 23529 node = bind->nodeTable[i]; 23530 if (node == NULL) 23531 continue; 23532 /* 23533 * ...with every key-sequence of the parent node, already 23534 * evaluated to be a duplicate key-sequence. 23535 */ 23536 if (oldDupls) { 23537 j = 0; 23538 while (j < oldDupls) { 23539 if (nbFields == 1) { 23540 ret = xmlSchemaAreValuesEqual( 23541 node->keys[0]->val, 23542 dupls[j]->keys[0]->val); 23543 if (ret == -1) 23544 goto internal_error; 23545 if (ret == 0) { 23546 j++; 23547 continue; 23548 } 23549 } else { 23550 parNode = dupls[j]; 23551 for (k = 0; k < nbFields; k++) { 23552 ret = xmlSchemaAreValuesEqual( 23553 node->keys[k]->val, 23554 parNode->keys[k]->val); 23555 if (ret == -1) 23556 goto internal_error; 23557 if (ret == 0) 23558 break; 23559 } 23560 } 23561 if (ret == 1) 23562 /* Duplicate found. */ 23563 break; 23564 j++; 23565 } 23566 if (j != oldDupls) { 23567 /* Duplicate found. Skip this entry. */ 23568 continue; 23569 } 23570 } 23571 /* 23572 * ... and with every key-sequence of the parent node. 23573 */ 23574 if (oldNum) { 23575 j = 0; 23576 while (j < oldNum) { 23577 parNode = parNodes[j]; 23578 if (nbFields == 1) { 23579 ret = xmlSchemaAreValuesEqual( 23580 node->keys[0]->val, 23581 parNode->keys[0]->val); 23582 if (ret == -1) 23583 goto internal_error; 23584 if (ret == 0) { 23585 j++; 23586 continue; 23587 } 23588 } else { 23589 for (k = 0; k < nbFields; k++) { 23590 ret = xmlSchemaAreValuesEqual( 23591 node->keys[k]->val, 23592 parNode->keys[k]->val); 23593 if (ret == -1) 23594 goto internal_error; 23595 if (ret == 0) 23596 break; 23597 } 23598 } 23599 if (ret == 1) 23600 /* Duplicate found. */ 23601 break; 23602 j++; 23603 } 23604 if (j != oldNum) { 23605 /* 23606 * Handle duplicates. Move the duplicate in 23607 * the parent's node-table to the list of 23608 * duplicates. 23609 */ 23610 oldNum--; 23611 parBind->nbNodes--; 23612 /* 23613 * Move last old item to pos of duplicate. 23614 */ 23615 parNodes[j] = parNodes[oldNum]; 23616 23617 if (parBind->nbNodes != oldNum) { 23618 /* 23619 * If new items exist, move last new item to 23620 * last of old items. 23621 */ 23622 parNodes[oldNum] = 23623 parNodes[parBind->nbNodes]; 23624 } 23625 if (parBind->dupls == NULL) { 23626 parBind->dupls = xmlSchemaItemListCreate(); 23627 if (parBind->dupls == NULL) 23628 goto internal_error; 23629 } 23630 xmlSchemaItemListAdd(parBind->dupls, parNode); 23631 } else { 23632 /* 23633 * Add the node-table entry (node and key-sequence) of 23634 * the child node to the node table of the parent node. 23635 */ 23636 if (parBind->nodeTable == NULL) { 23637 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23638 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23639 if (parBind->nodeTable == NULL) { 23640 xmlSchemaVErrMemory(NULL, 23641 "allocating IDC list of node-table items", NULL); 23642 goto internal_error; 23643 } 23644 parBind->sizeNodes = 1; 23645 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23646 parBind->sizeNodes *= 2; 23647 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23648 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23649 sizeof(xmlSchemaPSVIIDCNodePtr)); 23650 if (parBind->nodeTable == NULL) { 23651 xmlSchemaVErrMemory(NULL, 23652 "re-allocating IDC list of node-table items", NULL); 23653 goto internal_error; 23654 } 23655 } 23656 parNodes = parBind->nodeTable; 23657 /* 23658 * Append the new node-table entry to the 'new node-table 23659 * entries' section. 23660 */ 23661 parNodes[parBind->nbNodes++] = node; 23662 } 23663 23664 } 23665 23666 } 23667 } else { 23668 /* 23669 * No binding for the IDC was found: create a new one and 23670 * copy all node-tables. 23671 */ 23672 parBind = xmlSchemaIDCNewBinding(bind->definition); 23673 if (parBind == NULL) 23674 goto internal_error; 23675 23676 /* 23677 * TODO: Hmm, how to optimize the initial number of 23678 * allocated entries? 23679 */ 23680 if (bind->nbNodes != 0) { 23681 /* 23682 * Add all IDC node-table entries. 23683 */ 23684 if (! vctxt->psviExposeIDCNodeTables) { 23685 /* 23686 * Just move the entries. 23687 * NOTE: this is quite save here, since 23688 * all the keyref lookups have already been 23689 * performed. 23690 */ 23691 parBind->nodeTable = bind->nodeTable; 23692 bind->nodeTable = NULL; 23693 parBind->sizeNodes = bind->sizeNodes; 23694 bind->sizeNodes = 0; 23695 parBind->nbNodes = bind->nbNodes; 23696 bind->nbNodes = 0; 23697 } else { 23698 /* 23699 * Copy the entries. 23700 */ 23701 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23702 xmlMalloc(bind->nbNodes * 23703 sizeof(xmlSchemaPSVIIDCNodePtr)); 23704 if (parBind->nodeTable == NULL) { 23705 xmlSchemaVErrMemory(NULL, 23706 "allocating an array of IDC node-table " 23707 "items", NULL); 23708 xmlSchemaIDCFreeBinding(parBind); 23709 goto internal_error; 23710 } 23711 parBind->sizeNodes = bind->nbNodes; 23712 parBind->nbNodes = bind->nbNodes; 23713 memcpy(parBind->nodeTable, bind->nodeTable, 23714 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23715 } 23716 } 23717 if (bind->dupls) { 23718 /* 23719 * Move the duplicates. 23720 */ 23721 if (parBind->dupls != NULL) 23722 xmlSchemaItemListFree(parBind->dupls); 23723 parBind->dupls = bind->dupls; 23724 bind->dupls = NULL; 23725 } 23726 if (parTable != NULL) { 23727 if (*parTable == NULL) 23728 *parTable = parBind; 23729 else { 23730 parBind->next = *parTable; 23731 *parTable = parBind; 23732 } 23733 } 23734 } 23735 23736 next_binding: 23737 bind = bind->next; 23738 } 23739 return (0); 23740 23741 internal_error: 23742 return(-1); 23743 } 23744 23745 /** 23746 * xmlSchemaCheckCVCIDCKeyRef: 23747 * @vctxt: the WXS validation context 23748 * @elemDecl: the element declaration 23749 * 23750 * Check the cvc-idc-keyref constraints. 23751 */ 23752 static int 23753 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23754 { 23755 xmlSchemaIDCMatcherPtr matcher; 23756 xmlSchemaPSVIIDCBindingPtr bind; 23757 23758 matcher = vctxt->inode->idcMatchers; 23759 /* 23760 * Find a keyref. 23761 */ 23762 while (matcher != NULL) { 23763 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23764 matcher->targets && 23765 matcher->targets->nbItems) 23766 { 23767 int i, j, k, res, nbFields, hasDupls; 23768 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23769 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23770 23771 nbFields = matcher->aidc->def->nbFields; 23772 23773 /* 23774 * Find the IDC node-table for the referenced IDC key/unique. 23775 */ 23776 bind = vctxt->inode->idcTable; 23777 while (bind != NULL) { 23778 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23779 bind->definition) 23780 break; 23781 bind = bind->next; 23782 } 23783 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23784 /* 23785 * Search for a matching key-sequences. 23786 */ 23787 for (i = 0; i < matcher->targets->nbItems; i++) { 23788 res = 0; 23789 refNode = matcher->targets->items[i]; 23790 if (bind != NULL) { 23791 refKeys = refNode->keys; 23792 for (j = 0; j < bind->nbNodes; j++) { 23793 keys = bind->nodeTable[j]->keys; 23794 for (k = 0; k < nbFields; k++) { 23795 res = xmlSchemaAreValuesEqual(keys[k]->val, 23796 refKeys[k]->val); 23797 if (res == 0) 23798 break; 23799 else if (res == -1) { 23800 return (-1); 23801 } 23802 } 23803 if (res == 1) { 23804 /* 23805 * Match found. 23806 */ 23807 break; 23808 } 23809 } 23810 if ((res == 0) && hasDupls) { 23811 /* 23812 * Search in duplicates 23813 */ 23814 for (j = 0; j < bind->dupls->nbItems; j++) { 23815 keys = ((xmlSchemaPSVIIDCNodePtr) 23816 bind->dupls->items[j])->keys; 23817 for (k = 0; k < nbFields; k++) { 23818 res = xmlSchemaAreValuesEqual(keys[k]->val, 23819 refKeys[k]->val); 23820 if (res == 0) 23821 break; 23822 else if (res == -1) { 23823 return (-1); 23824 } 23825 } 23826 if (res == 1) { 23827 /* 23828 * Match in duplicates found. 23829 */ 23830 xmlChar *str = NULL, *strB = NULL; 23831 xmlSchemaKeyrefErr(vctxt, 23832 XML_SCHEMAV_CVC_IDC, refNode, 23833 (xmlSchemaTypePtr) matcher->aidc->def, 23834 "More than one match found for " 23835 "key-sequence %s of keyref '%s'", 23836 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23837 refNode->keys, nbFields), 23838 xmlSchemaGetComponentQName(&strB, 23839 matcher->aidc->def)); 23840 FREE_AND_NULL(str); 23841 FREE_AND_NULL(strB); 23842 break; 23843 } 23844 } 23845 } 23846 } 23847 23848 if (res == 0) { 23849 xmlChar *str = NULL, *strB = NULL; 23850 xmlSchemaKeyrefErr(vctxt, 23851 XML_SCHEMAV_CVC_IDC, refNode, 23852 (xmlSchemaTypePtr) matcher->aidc->def, 23853 "No match found for key-sequence %s of keyref '%s'", 23854 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23855 refNode->keys, nbFields), 23856 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23857 FREE_AND_NULL(str); 23858 FREE_AND_NULL(strB); 23859 } 23860 } 23861 } 23862 matcher = matcher->next; 23863 } 23864 /* TODO: Return an error if any error encountered. */ 23865 return (0); 23866 } 23867 23868 /************************************************************************ 23869 * * 23870 * XML Reader validation code * 23871 * * 23872 ************************************************************************/ 23873 23874 static xmlSchemaAttrInfoPtr 23875 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23876 { 23877 xmlSchemaAttrInfoPtr iattr; 23878 /* 23879 * Grow/create list of attribute infos. 23880 */ 23881 if (vctxt->attrInfos == NULL) { 23882 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23883 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23884 vctxt->sizeAttrInfos = 1; 23885 if (vctxt->attrInfos == NULL) { 23886 xmlSchemaVErrMemory(vctxt, 23887 "allocating attribute info list", NULL); 23888 return (NULL); 23889 } 23890 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23891 vctxt->sizeAttrInfos++; 23892 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23893 xmlRealloc(vctxt->attrInfos, 23894 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23895 if (vctxt->attrInfos == NULL) { 23896 xmlSchemaVErrMemory(vctxt, 23897 "re-allocating attribute info list", NULL); 23898 return (NULL); 23899 } 23900 } else { 23901 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23902 if (iattr->localName != NULL) { 23903 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23904 "attr info not cleared"); 23905 return (NULL); 23906 } 23907 iattr->nodeType = XML_ATTRIBUTE_NODE; 23908 return (iattr); 23909 } 23910 /* 23911 * Create an attribute info. 23912 */ 23913 iattr = (xmlSchemaAttrInfoPtr) 23914 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23915 if (iattr == NULL) { 23916 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23917 return (NULL); 23918 } 23919 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23920 iattr->nodeType = XML_ATTRIBUTE_NODE; 23921 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23922 23923 return (iattr); 23924 } 23925 23926 static int 23927 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23928 xmlNodePtr attrNode, 23929 int nodeLine, 23930 const xmlChar *localName, 23931 const xmlChar *nsName, 23932 int ownedNames, 23933 xmlChar *value, 23934 int ownedValue) 23935 { 23936 xmlSchemaAttrInfoPtr attr; 23937 23938 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23939 if (attr == NULL) { 23940 VERROR_INT("xmlSchemaPushAttribute", 23941 "calling xmlSchemaGetFreshAttrInfo()"); 23942 return (-1); 23943 } 23944 attr->node = attrNode; 23945 attr->nodeLine = nodeLine; 23946 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 23947 attr->localName = localName; 23948 attr->nsName = nsName; 23949 if (ownedNames) 23950 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 23951 /* 23952 * Evaluate if it's an XSI attribute. 23953 */ 23954 if (nsName != NULL) { 23955 if (xmlStrEqual(localName, BAD_CAST "nil")) { 23956 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23957 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 23958 } 23959 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 23960 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23961 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 23962 } 23963 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 23964 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23965 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 23966 } 23967 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 23968 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23969 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 23970 } 23971 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 23972 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 23973 } 23974 } 23975 attr->value = value; 23976 if (ownedValue) 23977 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 23978 if (attr->metaType != 0) 23979 attr->state = XML_SCHEMAS_ATTR_META; 23980 return (0); 23981 } 23982 23983 /** 23984 * xmlSchemaClearElemInfo: 23985 * @vctxt: the WXS validation context 23986 * @ielem: the element information item 23987 */ 23988 static void 23989 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 23990 xmlSchemaNodeInfoPtr ielem) 23991 { 23992 ielem->hasKeyrefs = 0; 23993 ielem->appliedXPath = 0; 23994 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 23995 FREE_AND_NULL(ielem->localName); 23996 FREE_AND_NULL(ielem->nsName); 23997 } else { 23998 ielem->localName = NULL; 23999 ielem->nsName = NULL; 24000 } 24001 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24002 FREE_AND_NULL(ielem->value); 24003 } else { 24004 ielem->value = NULL; 24005 } 24006 if (ielem->val != NULL) { 24007 /* 24008 * PSVI TODO: Be careful not to free it when the value is 24009 * exposed via PSVI. 24010 */ 24011 xmlSchemaFreeValue(ielem->val); 24012 ielem->val = NULL; 24013 } 24014 if (ielem->idcMatchers != NULL) { 24015 /* 24016 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24017 * Does it work? 24018 */ 24019 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24020 #if 0 24021 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24022 #endif 24023 ielem->idcMatchers = NULL; 24024 } 24025 if (ielem->idcTable != NULL) { 24026 /* 24027 * OPTIMIZE TODO: Use a pool of IDC tables??. 24028 */ 24029 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24030 ielem->idcTable = NULL; 24031 } 24032 if (ielem->regexCtxt != NULL) { 24033 xmlRegFreeExecCtxt(ielem->regexCtxt); 24034 ielem->regexCtxt = NULL; 24035 } 24036 if (ielem->nsBindings != NULL) { 24037 xmlFree((xmlChar **)ielem->nsBindings); 24038 ielem->nsBindings = NULL; 24039 ielem->nbNsBindings = 0; 24040 ielem->sizeNsBindings = 0; 24041 } 24042 } 24043 24044 /** 24045 * xmlSchemaGetFreshElemInfo: 24046 * @vctxt: the schema validation context 24047 * 24048 * Creates/reuses and initializes the element info item for 24049 * the currect tree depth. 24050 * 24051 * Returns the element info item or NULL on API or internal errors. 24052 */ 24053 static xmlSchemaNodeInfoPtr 24054 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24055 { 24056 xmlSchemaNodeInfoPtr info = NULL; 24057 24058 if (vctxt->depth > vctxt->sizeElemInfos) { 24059 VERROR_INT("xmlSchemaGetFreshElemInfo", 24060 "inconsistent depth encountered"); 24061 return (NULL); 24062 } 24063 if (vctxt->elemInfos == NULL) { 24064 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24065 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24066 if (vctxt->elemInfos == NULL) { 24067 xmlSchemaVErrMemory(vctxt, 24068 "allocating the element info array", NULL); 24069 return (NULL); 24070 } 24071 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24072 vctxt->sizeElemInfos = 10; 24073 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24074 int i = vctxt->sizeElemInfos; 24075 24076 vctxt->sizeElemInfos *= 2; 24077 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24078 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24079 sizeof(xmlSchemaNodeInfoPtr)); 24080 if (vctxt->elemInfos == NULL) { 24081 xmlSchemaVErrMemory(vctxt, 24082 "re-allocating the element info array", NULL); 24083 return (NULL); 24084 } 24085 /* 24086 * We need the new memory to be NULLed. 24087 * TODO: Use memset instead? 24088 */ 24089 for (; i < vctxt->sizeElemInfos; i++) 24090 vctxt->elemInfos[i] = NULL; 24091 } else 24092 info = vctxt->elemInfos[vctxt->depth]; 24093 24094 if (info == NULL) { 24095 info = (xmlSchemaNodeInfoPtr) 24096 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24097 if (info == NULL) { 24098 xmlSchemaVErrMemory(vctxt, 24099 "allocating an element info", NULL); 24100 return (NULL); 24101 } 24102 vctxt->elemInfos[vctxt->depth] = info; 24103 } else { 24104 if (info->localName != NULL) { 24105 VERROR_INT("xmlSchemaGetFreshElemInfo", 24106 "elem info has not been cleared"); 24107 return (NULL); 24108 } 24109 } 24110 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24111 info->nodeType = XML_ELEMENT_NODE; 24112 info->depth = vctxt->depth; 24113 24114 return (info); 24115 } 24116 24117 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24118 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24119 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24120 24121 static int 24122 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24123 xmlNodePtr node, 24124 xmlSchemaTypePtr type, 24125 xmlSchemaValType valType, 24126 const xmlChar * value, 24127 xmlSchemaValPtr val, 24128 unsigned long length, 24129 int fireErrors) 24130 { 24131 int ret, error = 0; 24132 24133 xmlSchemaTypePtr tmpType; 24134 xmlSchemaFacetLinkPtr facetLink; 24135 xmlSchemaFacetPtr facet; 24136 unsigned long len = 0; 24137 xmlSchemaWhitespaceValueType ws; 24138 24139 /* 24140 * In Libxml2, derived built-in types have currently no explicit facets. 24141 */ 24142 if (type->type == XML_SCHEMA_TYPE_BASIC) 24143 return (0); 24144 24145 /* 24146 * NOTE: Do not jump away, if the facetSet of the given type is 24147 * empty: until now, "pattern" and "enumeration" facets of the 24148 * *base types* need to be checked as well. 24149 */ 24150 if (type->facetSet == NULL) 24151 goto pattern_and_enum; 24152 24153 if (! WXS_IS_ATOMIC(type)) { 24154 if (WXS_IS_LIST(type)) 24155 goto WXS_IS_LIST; 24156 else 24157 goto pattern_and_enum; 24158 } 24159 /* 24160 * Whitespace handling is only of importance for string-based 24161 * types. 24162 */ 24163 tmpType = xmlSchemaGetPrimitiveType(type); 24164 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24165 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24166 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24167 } else 24168 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24169 /* 24170 * If the value was not computed (for string or 24171 * anySimpleType based types), then use the provided 24172 * type. 24173 */ 24174 if (val == NULL) 24175 valType = valType; 24176 else 24177 valType = xmlSchemaGetValType(val); 24178 24179 ret = 0; 24180 for (facetLink = type->facetSet; facetLink != NULL; 24181 facetLink = facetLink->next) { 24182 /* 24183 * Skip the pattern "whiteSpace": it is used to 24184 * format the character content beforehand. 24185 */ 24186 switch (facetLink->facet->type) { 24187 case XML_SCHEMA_FACET_WHITESPACE: 24188 case XML_SCHEMA_FACET_PATTERN: 24189 case XML_SCHEMA_FACET_ENUMERATION: 24190 continue; 24191 case XML_SCHEMA_FACET_LENGTH: 24192 case XML_SCHEMA_FACET_MINLENGTH: 24193 case XML_SCHEMA_FACET_MAXLENGTH: 24194 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24195 valType, value, val, &len, ws); 24196 break; 24197 default: 24198 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24199 valType, value, val, ws); 24200 break; 24201 } 24202 if (ret < 0) { 24203 AERROR_INT("xmlSchemaValidateFacets", 24204 "validating against a atomic type facet"); 24205 return (-1); 24206 } else if (ret > 0) { 24207 if (fireErrors) 24208 xmlSchemaFacetErr(actxt, ret, node, 24209 value, len, type, facetLink->facet, NULL, NULL, NULL); 24210 else 24211 return (ret); 24212 if (error == 0) 24213 error = ret; 24214 } 24215 ret = 0; 24216 } 24217 24218 WXS_IS_LIST: 24219 if (! WXS_IS_LIST(type)) 24220 goto pattern_and_enum; 24221 /* 24222 * "length", "minLength" and "maxLength" of list types. 24223 */ 24224 ret = 0; 24225 for (facetLink = type->facetSet; facetLink != NULL; 24226 facetLink = facetLink->next) { 24227 24228 switch (facetLink->facet->type) { 24229 case XML_SCHEMA_FACET_LENGTH: 24230 case XML_SCHEMA_FACET_MINLENGTH: 24231 case XML_SCHEMA_FACET_MAXLENGTH: 24232 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24233 value, length, NULL); 24234 break; 24235 default: 24236 continue; 24237 } 24238 if (ret < 0) { 24239 AERROR_INT("xmlSchemaValidateFacets", 24240 "validating against a list type facet"); 24241 return (-1); 24242 } else if (ret > 0) { 24243 if (fireErrors) 24244 xmlSchemaFacetErr(actxt, ret, node, 24245 value, length, type, facetLink->facet, NULL, NULL, NULL); 24246 else 24247 return (ret); 24248 if (error == 0) 24249 error = ret; 24250 } 24251 ret = 0; 24252 } 24253 24254 pattern_and_enum: 24255 if (error >= 0) { 24256 int found = 0; 24257 /* 24258 * Process enumerations. Facet values are in the value space 24259 * of the defining type's base type. This seems to be a bug in the 24260 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24261 * Only the first set of enumerations in the ancestor-or-self axis 24262 * is used for validation. 24263 */ 24264 ret = 0; 24265 tmpType = type; 24266 do { 24267 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24268 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24269 continue; 24270 found = 1; 24271 ret = xmlSchemaAreValuesEqual(facet->val, val); 24272 if (ret == 1) 24273 break; 24274 else if (ret < 0) { 24275 AERROR_INT("xmlSchemaValidateFacets", 24276 "validating against an enumeration facet"); 24277 return (-1); 24278 } 24279 } 24280 if (ret != 0) 24281 break; 24282 /* 24283 * Break on the first set of enumerations. Any additional 24284 * enumerations which might be existent on the ancestors 24285 * of the current type are restricted by this set; thus 24286 * *must* *not* be taken into account. 24287 */ 24288 if (found) 24289 break; 24290 tmpType = tmpType->baseType; 24291 } while ((tmpType != NULL) && 24292 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24293 if (found && (ret == 0)) { 24294 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24295 if (fireErrors) { 24296 xmlSchemaFacetErr(actxt, ret, node, 24297 value, 0, type, NULL, NULL, NULL, NULL); 24298 } else 24299 return (ret); 24300 if (error == 0) 24301 error = ret; 24302 } 24303 } 24304 24305 if (error >= 0) { 24306 int found; 24307 /* 24308 * Process patters. Pattern facets are ORed at type level 24309 * and ANDed if derived. Walk the base type axis. 24310 */ 24311 tmpType = type; 24312 facet = NULL; 24313 do { 24314 found = 0; 24315 for (facetLink = tmpType->facetSet; facetLink != NULL; 24316 facetLink = facetLink->next) { 24317 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24318 continue; 24319 found = 1; 24320 /* 24321 * NOTE that for patterns, @value needs to be the 24322 * normalized vaule. 24323 */ 24324 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24325 if (ret == 1) 24326 break; 24327 else if (ret < 0) { 24328 AERROR_INT("xmlSchemaValidateFacets", 24329 "validating against a pattern facet"); 24330 return (-1); 24331 } else { 24332 /* 24333 * Save the last non-validating facet. 24334 */ 24335 facet = facetLink->facet; 24336 } 24337 } 24338 if (found && (ret != 1)) { 24339 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24340 if (fireErrors) { 24341 xmlSchemaFacetErr(actxt, ret, node, 24342 value, 0, type, facet, NULL, NULL, NULL); 24343 } else 24344 return (ret); 24345 if (error == 0) 24346 error = ret; 24347 break; 24348 } 24349 tmpType = tmpType->baseType; 24350 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24351 } 24352 24353 return (error); 24354 } 24355 24356 static xmlChar * 24357 xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24358 const xmlChar *value) 24359 { 24360 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24361 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24362 return (xmlSchemaCollapseString(value)); 24363 case XML_SCHEMA_WHITESPACE_REPLACE: 24364 return (xmlSchemaWhiteSpaceReplace(value)); 24365 default: 24366 return (NULL); 24367 } 24368 } 24369 24370 static int 24371 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24372 const xmlChar *value, 24373 xmlSchemaValPtr *val, 24374 int valNeeded) 24375 { 24376 int ret; 24377 const xmlChar *nsName; 24378 xmlChar *local, *prefix = NULL; 24379 24380 ret = xmlValidateQName(value, 1); 24381 if (ret != 0) { 24382 if (ret == -1) { 24383 VERROR_INT("xmlSchemaValidateQName", 24384 "calling xmlValidateQName()"); 24385 return (-1); 24386 } 24387 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24388 } 24389 /* 24390 * NOTE: xmlSplitQName2 will always return a duplicated 24391 * strings. 24392 */ 24393 local = xmlSplitQName2(value, &prefix); 24394 if (local == NULL) 24395 local = xmlStrdup(value); 24396 /* 24397 * OPTIMIZE TODO: Use flags for: 24398 * - is there any namespace binding? 24399 * - is there a default namespace? 24400 */ 24401 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24402 24403 if (prefix != NULL) { 24404 xmlFree(prefix); 24405 /* 24406 * A namespace must be found if the prefix is 24407 * NOT NULL. 24408 */ 24409 if (nsName == NULL) { 24410 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24411 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24412 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24413 "The QName value '%s' has no " 24414 "corresponding namespace declaration in " 24415 "scope", value, NULL); 24416 if (local != NULL) 24417 xmlFree(local); 24418 return (ret); 24419 } 24420 } 24421 if (valNeeded && val) { 24422 if (nsName != NULL) 24423 *val = xmlSchemaNewQNameValue( 24424 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24425 else 24426 *val = xmlSchemaNewQNameValue(NULL, 24427 BAD_CAST local); 24428 } else 24429 xmlFree(local); 24430 return (0); 24431 } 24432 24433 /* 24434 * cvc-simple-type 24435 */ 24436 static int 24437 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24438 xmlNodePtr node, 24439 xmlSchemaTypePtr type, 24440 const xmlChar *value, 24441 xmlSchemaValPtr *retVal, 24442 int fireErrors, 24443 int normalize, 24444 int isNormalized) 24445 { 24446 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24447 xmlSchemaValPtr val = NULL; 24448 /* xmlSchemaWhitespaceValueType ws; */ 24449 xmlChar *normValue = NULL; 24450 24451 #define NORMALIZE(atype) \ 24452 if ((! isNormalized) && \ 24453 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24454 normValue = xmlSchemaNormalizeValue(atype, value); \ 24455 if (normValue != NULL) \ 24456 value = normValue; \ 24457 isNormalized = 1; \ 24458 } 24459 24460 if ((retVal != NULL) && (*retVal != NULL)) { 24461 xmlSchemaFreeValue(*retVal); 24462 *retVal = NULL; 24463 } 24464 /* 24465 * 3.14.4 Simple Type Definition Validation Rules 24466 * Validation Rule: String Valid 24467 */ 24468 /* 24469 * 1 It is schema-valid with respect to that definition as defined 24470 * by Datatype Valid in [XML Schemas: Datatypes]. 24471 */ 24472 /* 24473 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24474 * the empty set, as defined in Type Derivation OK (Simple) (3.14.6), then 24475 * the string must be a declared entity name. 24476 */ 24477 /* 24478 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24479 * given the empty set, as defined in Type Derivation OK (Simple) (3.14.6), 24480 * then every whitespace-delimited substring of the string must be a declared 24481 * entity name. 24482 */ 24483 /* 24484 * 2.3 otherwise no further condition applies. 24485 */ 24486 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24487 valNeeded = 1; 24488 if (value == NULL) 24489 value = BAD_CAST ""; 24490 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24491 xmlSchemaTypePtr biType; /* The built-in type. */ 24492 /* 24493 * SPEC (1.2.1) "if {variety} is atomic then the string must match 24494 * a literal in the lexical space of {base type definition}" 24495 */ 24496 /* 24497 * Whitespace-normalize. 24498 */ 24499 NORMALIZE(type); 24500 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24501 /* 24502 * Get the built-in type. 24503 */ 24504 biType = type->baseType; 24505 while ((biType != NULL) && 24506 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24507 biType = biType->baseType; 24508 24509 if (biType == NULL) { 24510 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24511 "could not get the built-in type"); 24512 goto internal_error; 24513 } 24514 } else 24515 biType = type; 24516 /* 24517 * NOTATIONs need to be processed here, since they need 24518 * to lookup in the hashtable of NOTATION declarations of the schema. 24519 */ 24520 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24521 switch (biType->builtInType) { 24522 case XML_SCHEMAS_NOTATION: 24523 ret = xmlSchemaValidateNotation( 24524 (xmlSchemaValidCtxtPtr) actxt, 24525 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24526 NULL, value, &val, valNeeded); 24527 break; 24528 case XML_SCHEMAS_QNAME: 24529 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24530 value, &val, valNeeded); 24531 break; 24532 default: 24533 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24534 if (valNeeded) 24535 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24536 value, &val, node); 24537 else 24538 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24539 value, NULL, node); 24540 break; 24541 } 24542 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24543 switch (biType->builtInType) { 24544 case XML_SCHEMAS_NOTATION: 24545 ret = xmlSchemaValidateNotation(NULL, 24546 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24547 value, &val, valNeeded); 24548 break; 24549 default: 24550 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24551 if (valNeeded) 24552 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24553 value, &val, node); 24554 else 24555 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24556 value, NULL, node); 24557 break; 24558 } 24559 } else { 24560 /* 24561 * Validation via a public API is not implemented yet. 24562 */ 24563 TODO 24564 goto internal_error; 24565 } 24566 if (ret != 0) { 24567 if (ret < 0) { 24568 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24569 "validating against a built-in type"); 24570 goto internal_error; 24571 } 24572 if (WXS_IS_LIST(type)) 24573 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24574 else 24575 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24576 } 24577 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24578 /* 24579 * Check facets. 24580 */ 24581 ret = xmlSchemaValidateFacets(actxt, node, type, 24582 (xmlSchemaValType) biType->builtInType, value, val, 24583 0, fireErrors); 24584 if (ret != 0) { 24585 if (ret < 0) { 24586 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24587 "validating facets of atomic simple type"); 24588 goto internal_error; 24589 } 24590 if (WXS_IS_LIST(type)) 24591 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24592 else 24593 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24594 } 24595 } 24596 if (fireErrors && (ret > 0)) 24597 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24598 } else if (WXS_IS_LIST(type)) { 24599 24600 xmlSchemaTypePtr itemType; 24601 const xmlChar *cur, *end; 24602 xmlChar *tmpValue = NULL; 24603 unsigned long len = 0; 24604 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24605 /* 1.2.2 if {variety} is list then the string must be a sequence 24606 * of white space separated tokens, each of which matches a literal 24607 * in the lexical space of {item type definition} 24608 */ 24609 /* 24610 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24611 * the list type has an enum or pattern facet. 24612 */ 24613 NORMALIZE(type); 24614 /* 24615 * VAL TODO: Optimize validation of empty values. 24616 * VAL TODO: We do not have computed values for lists. 24617 */ 24618 itemType = WXS_LIST_ITEMTYPE(type); 24619 cur = value; 24620 do { 24621 while (IS_BLANK_CH(*cur)) 24622 cur++; 24623 end = cur; 24624 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24625 end++; 24626 if (end == cur) 24627 break; 24628 tmpValue = xmlStrndup(cur, end - cur); 24629 len++; 24630 24631 if (valNeeded) 24632 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24633 tmpValue, &curVal, fireErrors, 0, 1); 24634 else 24635 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24636 tmpValue, NULL, fireErrors, 0, 1); 24637 FREE_AND_NULL(tmpValue); 24638 if (curVal != NULL) { 24639 /* 24640 * Add to list of computed values. 24641 */ 24642 if (val == NULL) 24643 val = curVal; 24644 else 24645 xmlSchemaValueAppend(prevVal, curVal); 24646 prevVal = curVal; 24647 curVal = NULL; 24648 } 24649 if (ret != 0) { 24650 if (ret < 0) { 24651 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24652 "validating an item of list simple type"); 24653 goto internal_error; 24654 } 24655 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24656 break; 24657 } 24658 cur = end; 24659 } while (*cur != 0); 24660 FREE_AND_NULL(tmpValue); 24661 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24662 /* 24663 * Apply facets (pattern, enumeration). 24664 */ 24665 ret = xmlSchemaValidateFacets(actxt, node, type, 24666 XML_SCHEMAS_UNKNOWN, value, val, 24667 len, fireErrors); 24668 if (ret != 0) { 24669 if (ret < 0) { 24670 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24671 "validating facets of list simple type"); 24672 goto internal_error; 24673 } 24674 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24675 } 24676 } 24677 if (fireErrors && (ret > 0)) { 24678 /* 24679 * Report the normalized value. 24680 */ 24681 normalize = 1; 24682 NORMALIZE(type); 24683 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24684 } 24685 } else if (WXS_IS_UNION(type)) { 24686 xmlSchemaTypeLinkPtr memberLink; 24687 /* 24688 * TODO: For all datatypes derived by union whiteSpace does 24689 * not apply directly; however, the normalization behavior of union 24690 * types is controlled by the value of whiteSpace on that one of the 24691 * memberTypes against which the union is successfully validated. 24692 * 24693 * This means that the value is normalized by the first validating 24694 * member type, then the facets of the union type are applied. This 24695 * needs changing of the value! 24696 */ 24697 24698 /* 24699 * 1.2.3 if {variety} is union then the string must match a 24700 * literal in the lexical space of at least one member of 24701 * {member type definitions} 24702 */ 24703 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24704 if (memberLink == NULL) { 24705 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24706 "union simple type has no member types"); 24707 goto internal_error; 24708 } 24709 /* 24710 * Always normalize union type values, since we currently 24711 * cannot store the whitespace information with the value 24712 * itself; otherwise a later value-comparison would be 24713 * not possible. 24714 */ 24715 while (memberLink != NULL) { 24716 if (valNeeded) 24717 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24718 memberLink->type, value, &val, 0, 1, 0); 24719 else 24720 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24721 memberLink->type, value, NULL, 0, 1, 0); 24722 if (ret <= 0) 24723 break; 24724 memberLink = memberLink->next; 24725 } 24726 if (ret != 0) { 24727 if (ret < 0) { 24728 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24729 "validating members of union simple type"); 24730 goto internal_error; 24731 } 24732 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24733 } 24734 /* 24735 * Apply facets (pattern, enumeration). 24736 */ 24737 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24738 /* 24739 * The normalization behavior of union types is controlled by 24740 * the value of whiteSpace on that one of the memberTypes 24741 * against which the union is successfully validated. 24742 */ 24743 NORMALIZE(memberLink->type); 24744 ret = xmlSchemaValidateFacets(actxt, node, type, 24745 XML_SCHEMAS_UNKNOWN, value, val, 24746 0, fireErrors); 24747 if (ret != 0) { 24748 if (ret < 0) { 24749 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24750 "validating facets of union simple type"); 24751 goto internal_error; 24752 } 24753 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24754 } 24755 } 24756 if (fireErrors && (ret > 0)) 24757 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24758 } 24759 24760 if (normValue != NULL) 24761 xmlFree(normValue); 24762 if (ret == 0) { 24763 if (retVal != NULL) 24764 *retVal = val; 24765 else if (val != NULL) 24766 xmlSchemaFreeValue(val); 24767 } else if (val != NULL) 24768 xmlSchemaFreeValue(val); 24769 return (ret); 24770 internal_error: 24771 if (normValue != NULL) 24772 xmlFree(normValue); 24773 if (val != NULL) 24774 xmlSchemaFreeValue(val); 24775 return (-1); 24776 } 24777 24778 static int 24779 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24780 const xmlChar *value, 24781 const xmlChar **nsName, 24782 const xmlChar **localName) 24783 { 24784 int ret = 0; 24785 24786 if ((nsName == NULL) || (localName == NULL)) 24787 return (-1); 24788 *nsName = NULL; 24789 *localName = NULL; 24790 24791 ret = xmlValidateQName(value, 1); 24792 if (ret == -1) 24793 return (-1); 24794 if (ret > 0) { 24795 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24796 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24797 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24798 return (1); 24799 } 24800 { 24801 xmlChar *local = NULL; 24802 xmlChar *prefix; 24803 24804 /* 24805 * NOTE: xmlSplitQName2 will return a duplicated 24806 * string. 24807 */ 24808 local = xmlSplitQName2(value, &prefix); 24809 if (local == NULL) 24810 *localName = xmlDictLookup(vctxt->dict, value, -1); 24811 else { 24812 *localName = xmlDictLookup(vctxt->dict, local, -1); 24813 xmlFree(local); 24814 } 24815 24816 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24817 24818 if (prefix != NULL) { 24819 xmlFree(prefix); 24820 /* 24821 * A namespace must be found if the prefix is NOT NULL. 24822 */ 24823 if (*nsName == NULL) { 24824 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24825 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24826 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24827 "The QName value '%s' has no " 24828 "corresponding namespace declaration in scope", 24829 value, NULL); 24830 return (2); 24831 } 24832 } 24833 } 24834 return (0); 24835 } 24836 24837 static int 24838 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24839 xmlSchemaAttrInfoPtr iattr, 24840 xmlSchemaTypePtr *localType, 24841 xmlSchemaElementPtr elemDecl) 24842 { 24843 int ret = 0; 24844 /* 24845 * cvc-elt (3.3.4) : (4) 24846 * AND 24847 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24848 * (1.2.1.2.1) - (1.2.1.2.4) 24849 * Handle 'xsi:type'. 24850 */ 24851 if (localType == NULL) 24852 return (-1); 24853 *localType = NULL; 24854 if (iattr == NULL) 24855 return (0); 24856 else { 24857 const xmlChar *nsName = NULL, *local = NULL; 24858 /* 24859 * TODO: We should report a *warning* that the type was overriden 24860 * by the instance. 24861 */ 24862 ACTIVATE_ATTRIBUTE(iattr); 24863 /* 24864 * (cvc-elt) (3.3.4) : (4.1) 24865 * (cvc-assess-elt) (1.2.1.2.2) 24866 */ 24867 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24868 &nsName, &local); 24869 if (ret != 0) { 24870 if (ret < 0) { 24871 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24872 "calling xmlSchemaQNameExpand() to validate the " 24873 "attribute 'xsi:type'"); 24874 goto internal_error; 24875 } 24876 goto exit; 24877 } 24878 /* 24879 * (cvc-elt) (3.3.4) : (4.2) 24880 * (cvc-assess-elt) (1.2.1.2.3) 24881 */ 24882 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24883 if (*localType == NULL) { 24884 xmlChar *str = NULL; 24885 24886 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24887 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24888 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24889 "The QName value '%s' of the xsi:type attribute does not " 24890 "resolve to a type definition", 24891 xmlSchemaFormatQName(&str, nsName, local), NULL); 24892 FREE_AND_NULL(str); 24893 ret = vctxt->err; 24894 goto exit; 24895 } 24896 if (elemDecl != NULL) { 24897 int set = 0; 24898 24899 /* 24900 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24901 * "The local type definition must be validly 24902 * derived from the {type definition} given the union of 24903 * the {disallowed substitutions} and the {type definition}'s 24904 * {prohibited substitutions}, as defined in 24905 * Type Derivation OK (Complex) (3.4.6) 24906 * (if it is a complex type definition), 24907 * or given {disallowed substitutions} as defined in Type 24908 * Derivation OK (Simple) (3.14.6) (if it is a simple type 24909 * definition)." 24910 * 24911 * {disallowed substitutions}: the "block" on the element decl. 24912 * {prohibited substitutions}: the "block" on the type def. 24913 */ 24914 /* 24915 * OPTIMIZE TODO: We could map types already evaluated 24916 * to be validly derived from other types to avoid checking 24917 * this over and over for the same types. 24918 */ 24919 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24920 (elemDecl->subtypes->flags & 24921 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24922 set |= SUBSET_EXTENSION; 24923 24924 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24925 (elemDecl->subtypes->flags & 24926 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24927 set |= SUBSET_RESTRICTION; 24928 24929 /* 24930 * REMOVED and CHANGED since this produced a parser context 24931 * which adds to the string dict of the schema. So this would 24932 * change the schema and we don't want this. We don't need 24933 * the parser context anymore. 24934 * 24935 * if ((vctxt->pctxt == NULL) && 24936 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24937 * return (-1); 24938 */ 24939 24940 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24941 elemDecl->subtypes, set) != 0) { 24942 xmlChar *str = NULL; 24943 24944 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24945 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 24946 "The type definition '%s', specified by xsi:type, is " 24947 "blocked or not validly derived from the type definition " 24948 "of the element declaration", 24949 xmlSchemaFormatQName(&str, 24950 (*localType)->targetNamespace, 24951 (*localType)->name), 24952 NULL); 24953 FREE_AND_NULL(str); 24954 ret = vctxt->err; 24955 *localType = NULL; 24956 } 24957 } 24958 } 24959 exit: 24960 ACTIVATE_ELEM; 24961 return (ret); 24962 internal_error: 24963 ACTIVATE_ELEM; 24964 return (-1); 24965 } 24966 24967 static int 24968 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 24969 { 24970 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 24971 xmlSchemaTypePtr actualType; 24972 24973 /* 24974 * cvc-elt (3.3.4) : 1 24975 */ 24976 if (elemDecl == NULL) { 24977 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 24978 "No matching declaration available"); 24979 return (vctxt->err); 24980 } 24981 actualType = WXS_ELEM_TYPEDEF(elemDecl); 24982 /* 24983 * cvc-elt (3.3.4) : 2 24984 */ 24985 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 24986 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 24987 "The element declaration is abstract"); 24988 return (vctxt->err); 24989 } 24990 if (actualType == NULL) { 24991 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 24992 "The type definition is absent"); 24993 return (XML_SCHEMAV_CVC_TYPE_1); 24994 } 24995 if (vctxt->nbAttrInfos != 0) { 24996 int ret; 24997 xmlSchemaAttrInfoPtr iattr; 24998 /* 24999 * cvc-elt (3.3.4) : 3 25000 * Handle 'xsi:nil'. 25001 */ 25002 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25003 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25004 if (iattr) { 25005 ACTIVATE_ATTRIBUTE(iattr); 25006 /* 25007 * Validate the value. 25008 */ 25009 ret = xmlSchemaVCheckCVCSimpleType( 25010 ACTXT_CAST vctxt, NULL, 25011 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25012 iattr->value, &(iattr->val), 1, 0, 0); 25013 ACTIVATE_ELEM; 25014 if (ret < 0) { 25015 VERROR_INT("xmlSchemaValidateElemDecl", 25016 "calling xmlSchemaVCheckCVCSimpleType() to " 25017 "validate the attribute 'xsi:nil'"); 25018 return (-1); 25019 } 25020 if (ret == 0) { 25021 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25022 /* 25023 * cvc-elt (3.3.4) : 3.1 25024 */ 25025 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25026 "The element is not 'nillable'"); 25027 /* Does not return an error on purpose. */ 25028 } else { 25029 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25030 /* 25031 * cvc-elt (3.3.4) : 3.2.2 25032 */ 25033 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25034 (elemDecl->value != NULL)) { 25035 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25036 "The element cannot be 'nilled' because " 25037 "there is a fixed value constraint defined " 25038 "for it"); 25039 /* Does not return an error on purpose. */ 25040 } else 25041 vctxt->inode->flags |= 25042 XML_SCHEMA_ELEM_INFO_NILLED; 25043 } 25044 } 25045 } 25046 } 25047 /* 25048 * cvc-elt (3.3.4) : 4 25049 * Handle 'xsi:type'. 25050 */ 25051 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25052 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25053 if (iattr) { 25054 xmlSchemaTypePtr localType = NULL; 25055 25056 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25057 elemDecl); 25058 if (ret != 0) { 25059 if (ret == -1) { 25060 VERROR_INT("xmlSchemaValidateElemDecl", 25061 "calling xmlSchemaProcessXSIType() to " 25062 "process the attribute 'xsi:type'"); 25063 return (-1); 25064 } 25065 /* Does not return an error on purpose. */ 25066 } 25067 if (localType != NULL) { 25068 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25069 actualType = localType; 25070 } 25071 } 25072 } 25073 /* 25074 * IDC: Register identity-constraint XPath matchers. 25075 */ 25076 if ((elemDecl->idcs != NULL) && 25077 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25078 return (-1); 25079 /* 25080 * No actual type definition. 25081 */ 25082 if (actualType == NULL) { 25083 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25084 "The type definition is absent"); 25085 return (XML_SCHEMAV_CVC_TYPE_1); 25086 } 25087 /* 25088 * Remember the actual type definition. 25089 */ 25090 vctxt->inode->typeDef = actualType; 25091 25092 return (0); 25093 } 25094 25095 static int 25096 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25097 { 25098 xmlSchemaAttrInfoPtr iattr; 25099 int ret = 0, i; 25100 25101 /* 25102 * SPEC cvc-type (3.1.1) 25103 * "The attributes of must be empty, excepting those whose namespace 25104 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25105 * whose local name is one of type, nil, schemaLocation or 25106 * noNamespaceSchemaLocation." 25107 */ 25108 if (vctxt->nbAttrInfos == 0) 25109 return (0); 25110 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25111 iattr = vctxt->attrInfos[i]; 25112 if (! iattr->metaType) { 25113 ACTIVATE_ATTRIBUTE(iattr) 25114 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25115 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25116 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25117 } 25118 } 25119 ACTIVATE_ELEM 25120 return (ret); 25121 } 25122 25123 /* 25124 * Cleanup currently used attribute infos. 25125 */ 25126 static void 25127 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25128 { 25129 int i; 25130 xmlSchemaAttrInfoPtr attr; 25131 25132 if (vctxt->nbAttrInfos == 0) 25133 return; 25134 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25135 attr = vctxt->attrInfos[i]; 25136 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25137 if (attr->localName != NULL) 25138 xmlFree((xmlChar *) attr->localName); 25139 if (attr->nsName != NULL) 25140 xmlFree((xmlChar *) attr->nsName); 25141 } 25142 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25143 if (attr->value != NULL) 25144 xmlFree((xmlChar *) attr->value); 25145 } 25146 if (attr->val != NULL) { 25147 xmlSchemaFreeValue(attr->val); 25148 attr->val = NULL; 25149 } 25150 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25151 } 25152 vctxt->nbAttrInfos = 0; 25153 } 25154 25155 /* 25156 * 3.4.4 Complex Type Definition Validation Rules 25157 * Element Locally Valid (Complex Type) (cvc-complex-type) 25158 * 3.2.4 Attribute Declaration Validation Rules 25159 * Validation Rule: Attribute Locally Valid (cvc-attribute) 25160 * Attribute Locally Valid (Use) (cvc-au) 25161 * 25162 * Only "assessed" attribute information items will be visible to 25163 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25164 */ 25165 static int 25166 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25167 { 25168 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25169 xmlSchemaItemListPtr attrUseList; 25170 xmlSchemaAttributeUsePtr attrUse = NULL; 25171 xmlSchemaAttributePtr attrDecl = NULL; 25172 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25173 int i, j, found, nbAttrs, nbUses; 25174 int xpathRes = 0, res, wildIDs = 0, fixed; 25175 xmlNodePtr defAttrOwnerElem = NULL; 25176 25177 /* 25178 * SPEC (cvc-attribute) 25179 * (1) "The declaration must not be absent (see Missing 25180 * Sub-components (5.3) for how this can fail to be 25181 * the case)." 25182 * (2) "Its {type definition} must not be absent." 25183 * 25184 * NOTE (1) + (2): This is not handled here, since we currently do not 25185 * allow validation against schemas which have missing sub-components. 25186 * 25187 * SPEC (cvc-complex-type) 25188 * (3) "For each attribute information item in the element information 25189 * item's [attributes] excepting those whose [namespace name] is 25190 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25191 * [local name] is one of type, nil, schemaLocation or 25192 * noNamespaceSchemaLocation, the appropriate case among the following 25193 * must be true: 25194 * 25195 */ 25196 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25197 /* 25198 * @nbAttrs is the number of attributes present in the instance. 25199 */ 25200 nbAttrs = vctxt->nbAttrInfos; 25201 if (attrUseList != NULL) 25202 nbUses = attrUseList->nbItems; 25203 else 25204 nbUses = 0; 25205 for (i = 0; i < nbUses; i++) { 25206 found = 0; 25207 attrUse = attrUseList->items[i]; 25208 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25209 for (j = 0; j < nbAttrs; j++) { 25210 iattr = vctxt->attrInfos[j]; 25211 /* 25212 * SPEC (cvc-complex-type) (3) 25213 * Skip meta attributes. 25214 */ 25215 if (iattr->metaType) 25216 continue; 25217 if (iattr->localName[0] != attrDecl->name[0]) 25218 continue; 25219 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25220 continue; 25221 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25222 continue; 25223 found = 1; 25224 /* 25225 * SPEC (cvc-complex-type) 25226 * (3.1) "If there is among the {attribute uses} an attribute 25227 * use with an {attribute declaration} whose {name} matches 25228 * the attribute information item's [local name] and whose 25229 * {target namespace} is identical to the attribute information 25230 * item's [namespace name] (where an absent {target namespace} 25231 * is taken to be identical to a [namespace name] with no value), 25232 * then the attribute information must be valid with respect 25233 * to that attribute use as per Attribute Locally Valid (Use) 25234 * (3.5.4). In this case the {attribute declaration} of that 25235 * attribute use is the context-determined declaration for the 25236 * attribute information item with respect to Schema-Validity 25237 * Assessment (Attribute) (3.2.4) and 25238 * Assessment Outcome (Attribute) (3.2.5). 25239 */ 25240 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25241 iattr->use = attrUse; 25242 /* 25243 * Context-determined declaration. 25244 */ 25245 iattr->decl = attrDecl; 25246 iattr->typeDef = attrDecl->subtypes; 25247 break; 25248 } 25249 25250 if (found) 25251 continue; 25252 25253 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25254 /* 25255 * Handle non-existent, required attributes. 25256 * 25257 * SPEC (cvc-complex-type) 25258 * (4) "The {attribute declaration} of each attribute use in 25259 * the {attribute uses} whose {required} is true matches one 25260 * of the attribute information items in the element information 25261 * item's [attributes] as per clause 3.1 above." 25262 */ 25263 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25264 if (tmpiattr == NULL) { 25265 VERROR_INT( 25266 "xmlSchemaVAttributesComplex", 25267 "calling xmlSchemaGetFreshAttrInfo()"); 25268 return (-1); 25269 } 25270 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25271 tmpiattr->use = attrUse; 25272 tmpiattr->decl = attrDecl; 25273 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25274 ((attrUse->defValue != NULL) || 25275 (attrDecl->defValue != NULL))) { 25276 /* 25277 * Handle non-existent, optional, default/fixed attributes. 25278 */ 25279 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25280 if (tmpiattr == NULL) { 25281 VERROR_INT( 25282 "xmlSchemaVAttributesComplex", 25283 "calling xmlSchemaGetFreshAttrInfo()"); 25284 return (-1); 25285 } 25286 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25287 tmpiattr->use = attrUse; 25288 tmpiattr->decl = attrDecl; 25289 tmpiattr->typeDef = attrDecl->subtypes; 25290 tmpiattr->localName = attrDecl->name; 25291 tmpiattr->nsName = attrDecl->targetNamespace; 25292 } 25293 } 25294 25295 if (vctxt->nbAttrInfos == 0) 25296 return (0); 25297 /* 25298 * Validate against the wildcard. 25299 */ 25300 if (type->attributeWildcard != NULL) { 25301 /* 25302 * SPEC (cvc-complex-type) 25303 * (3.2.1) "There must be an {attribute wildcard}." 25304 */ 25305 for (i = 0; i < nbAttrs; i++) { 25306 iattr = vctxt->attrInfos[i]; 25307 /* 25308 * SPEC (cvc-complex-type) (3) 25309 * Skip meta attributes. 25310 */ 25311 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25312 continue; 25313 /* 25314 * SPEC (cvc-complex-type) 25315 * (3.2.2) "The attribute information item must be valid with 25316 * respect to it as defined in Item Valid (Wildcard) (3.10.4)." 25317 * 25318 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25319 * "... its [namespace name] must be valid with respect to 25320 * the wildcard constraint, as defined in Wildcard allows 25321 * Namespace Name (3.10.4)." 25322 */ 25323 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25324 iattr->nsName) == 0) { 25325 /* 25326 * Handle processContents. 25327 * 25328 * SPEC (cvc-wildcard): 25329 * processContents | context-determined declaration: 25330 * "strict" "mustFind" 25331 * "lax" "none" 25332 * "skip" "skip" 25333 */ 25334 if (type->attributeWildcard->processContents == 25335 XML_SCHEMAS_ANY_SKIP) { 25336 /* 25337 * context-determined declaration = "skip" 25338 * 25339 * SPEC PSVI Assessment Outcome (Attribute) 25340 * [validity] = "notKnown" 25341 * [validation attempted] = "none" 25342 */ 25343 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25344 continue; 25345 } 25346 /* 25347 * Find an attribute declaration. 25348 */ 25349 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25350 iattr->localName, iattr->nsName); 25351 if (iattr->decl != NULL) { 25352 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25353 /* 25354 * SPEC (cvc-complex-type) 25355 * (5) "Let [Definition:] the wild IDs be the set of 25356 * all attribute information item to which clause 3.2 25357 * applied and whose validation resulted in a 25358 * context-determined declaration of mustFind or no 25359 * context-determined declaration at all, and whose 25360 * [local name] and [namespace name] resolve (as 25361 * defined by QName resolution (Instance) (3.15.4)) to 25362 * an attribute declaration whose {type definition} is 25363 * or is derived from ID. Then all of the following 25364 * must be true:" 25365 */ 25366 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25367 if (xmlSchemaIsDerivedFromBuiltInType( 25368 iattr->typeDef, XML_SCHEMAS_ID)) { 25369 /* 25370 * SPEC (5.1) "There must be no more than one 25371 * item in wild IDs." 25372 */ 25373 if (wildIDs != 0) { 25374 /* VAL TODO */ 25375 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25376 TODO 25377 continue; 25378 } 25379 wildIDs++; 25380 /* 25381 * SPEC (cvc-complex-type) 25382 * (5.2) "If wild IDs is non-empty, there must not 25383 * be any attribute uses among the {attribute uses} 25384 * whose {attribute declaration}'s {type definition} 25385 * is or is derived from ID." 25386 */ 25387 if (attrUseList != NULL) { 25388 for (j = 0; j < attrUseList->nbItems; j++) { 25389 if (xmlSchemaIsDerivedFromBuiltInType( 25390 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25391 XML_SCHEMAS_ID)) { 25392 /* URGENT VAL TODO: implement */ 25393 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25394 TODO 25395 break; 25396 } 25397 } 25398 } 25399 } 25400 } else if (type->attributeWildcard->processContents == 25401 XML_SCHEMAS_ANY_LAX) { 25402 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25403 /* 25404 * SPEC PSVI Assessment Outcome (Attribute) 25405 * [validity] = "notKnown" 25406 * [validation attempted] = "none" 25407 */ 25408 } else { 25409 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25410 } 25411 } 25412 } 25413 } 25414 25415 if (vctxt->nbAttrInfos == 0) 25416 return (0); 25417 25418 /* 25419 * Get the owner element; needed for creation of default attributes. 25420 * This fixes bug #341337, reported by David Grohmann. 25421 */ 25422 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25423 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25424 if (ielem && ielem->node && ielem->node->doc) 25425 defAttrOwnerElem = ielem->node; 25426 } 25427 /* 25428 * Validate values, create default attributes, evaluate IDCs. 25429 */ 25430 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25431 iattr = vctxt->attrInfos[i]; 25432 /* 25433 * VAL TODO: Note that we won't try to resolve IDCs to 25434 * "lax" and "skip" validated attributes. Check what to 25435 * do in this case. 25436 */ 25437 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25438 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25439 continue; 25440 /* 25441 * VAL TODO: What to do if the type definition is missing? 25442 */ 25443 if (iattr->typeDef == NULL) { 25444 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25445 continue; 25446 } 25447 25448 ACTIVATE_ATTRIBUTE(iattr); 25449 fixed = 0; 25450 xpathRes = 0; 25451 25452 if (vctxt->xpathStates != NULL) { 25453 /* 25454 * Evaluate IDCs. 25455 */ 25456 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25457 XML_ATTRIBUTE_NODE); 25458 if (xpathRes == -1) { 25459 VERROR_INT("xmlSchemaVAttributesComplex", 25460 "calling xmlSchemaXPathEvaluate()"); 25461 goto internal_error; 25462 } 25463 } 25464 25465 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25466 /* 25467 * Default/fixed attributes. 25468 * We need the value only if we need to resolve IDCs or 25469 * will create default attributes. 25470 */ 25471 if ((xpathRes) || (defAttrOwnerElem)) { 25472 if (iattr->use->defValue != NULL) { 25473 iattr->value = (xmlChar *) iattr->use->defValue; 25474 iattr->val = iattr->use->defVal; 25475 } else { 25476 iattr->value = (xmlChar *) iattr->decl->defValue; 25477 iattr->val = iattr->decl->defVal; 25478 } 25479 /* 25480 * IDCs will consume the precomputed default value, 25481 * so we need to clone it. 25482 */ 25483 if (iattr->val == NULL) { 25484 VERROR_INT("xmlSchemaVAttributesComplex", 25485 "default/fixed value on an attribute use was " 25486 "not precomputed"); 25487 goto internal_error; 25488 } 25489 iattr->val = xmlSchemaCopyValue(iattr->val); 25490 if (iattr->val == NULL) { 25491 VERROR_INT("xmlSchemaVAttributesComplex", 25492 "calling xmlSchemaCopyValue()"); 25493 goto internal_error; 25494 } 25495 } 25496 /* 25497 * PSVI: Add the default attribute to the current element. 25498 * VAL TODO: Should we use the *normalized* value? This currently 25499 * uses the *initial* value. 25500 */ 25501 25502 if (defAttrOwnerElem) { 25503 xmlChar *normValue; 25504 const xmlChar *value; 25505 25506 value = iattr->value; 25507 /* 25508 * Normalize the value. 25509 */ 25510 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25511 iattr->value); 25512 if (normValue != NULL) 25513 value = BAD_CAST normValue; 25514 25515 if (iattr->nsName == NULL) { 25516 if (xmlNewProp(defAttrOwnerElem, 25517 iattr->localName, value) == NULL) { 25518 VERROR_INT("xmlSchemaVAttributesComplex", 25519 "callling xmlNewProp()"); 25520 if (normValue != NULL) 25521 xmlFree(normValue); 25522 goto internal_error; 25523 } 25524 } else { 25525 xmlNsPtr ns; 25526 25527 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25528 defAttrOwnerElem, iattr->nsName); 25529 if (ns == NULL) { 25530 xmlChar prefix[12]; 25531 int counter = 0; 25532 25533 /* 25534 * Create a namespace declaration on the validation 25535 * root node if no namespace declaration is in scope. 25536 */ 25537 do { 25538 snprintf((char *) prefix, 12, "p%d", counter++); 25539 ns = xmlSearchNs(defAttrOwnerElem->doc, 25540 defAttrOwnerElem, BAD_CAST prefix); 25541 if (counter > 1000) { 25542 VERROR_INT( 25543 "xmlSchemaVAttributesComplex", 25544 "could not compute a ns prefix for a " 25545 "default/fixed attribute"); 25546 if (normValue != NULL) 25547 xmlFree(normValue); 25548 goto internal_error; 25549 } 25550 } while (ns != NULL); 25551 ns = xmlNewNs(vctxt->validationRoot, 25552 iattr->nsName, BAD_CAST prefix); 25553 } 25554 /* 25555 * TODO: 25556 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25557 * If we have QNames: do we need to ensure there's a 25558 * prefix defined for the QName? 25559 */ 25560 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25561 } 25562 if (normValue != NULL) 25563 xmlFree(normValue); 25564 } 25565 /* 25566 * Go directly to IDC evaluation. 25567 */ 25568 goto eval_idcs; 25569 } 25570 /* 25571 * Validate the value. 25572 */ 25573 if (vctxt->value != NULL) { 25574 /* 25575 * Free last computed value; just for safety reasons. 25576 */ 25577 xmlSchemaFreeValue(vctxt->value); 25578 vctxt->value = NULL; 25579 } 25580 /* 25581 * Note that the attribute *use* can be unavailable, if 25582 * the attribute was a wild attribute. 25583 */ 25584 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25585 ((iattr->use != NULL) && 25586 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25587 fixed = 1; 25588 else 25589 fixed = 0; 25590 /* 25591 * SPEC (cvc-attribute) 25592 * (3) "The item's normalized value must be locally valid 25593 * with respect to that {type definition} as per 25594 * String Valid (3.14.4)." 25595 * 25596 * VAL TODO: Do we already have the 25597 * "normalized attribute value" here? 25598 */ 25599 if (xpathRes || fixed) { 25600 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25601 /* 25602 * Request a computed value. 25603 */ 25604 res = xmlSchemaVCheckCVCSimpleType( 25605 ACTXT_CAST vctxt, 25606 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25607 1, 1, 0); 25608 } else { 25609 res = xmlSchemaVCheckCVCSimpleType( 25610 ACTXT_CAST vctxt, 25611 iattr->node, iattr->typeDef, iattr->value, NULL, 25612 1, 0, 0); 25613 } 25614 25615 if (res != 0) { 25616 if (res == -1) { 25617 VERROR_INT("xmlSchemaVAttributesComplex", 25618 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25619 goto internal_error; 25620 } 25621 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25622 /* 25623 * SPEC PSVI Assessment Outcome (Attribute) 25624 * [validity] = "invalid" 25625 */ 25626 goto eval_idcs; 25627 } 25628 25629 if (fixed) { 25630 /* 25631 * SPEC Attribute Locally Valid (Use) (cvc-au) 25632 * "For an attribute information item to bevalid 25633 * with respect to an attribute use its *normalized* 25634 * value must match the *canonical* lexical 25635 * representation of the attribute use's {value 25636 * constraint}value, if it is present and fixed." 25637 * 25638 * VAL TODO: The requirement for the *canonical* value 25639 * will be removed in XML Schema 1.1. 25640 */ 25641 /* 25642 * SPEC Attribute Locally Valid (cvc-attribute) 25643 * (4) "The item's *actual* value must match the *value* of 25644 * the {value constraint}, if it is present and fixed." 25645 */ 25646 if (iattr->val == NULL) { 25647 /* VAL TODO: A value was not precomputed. */ 25648 TODO 25649 goto eval_idcs; 25650 } 25651 if ((iattr->use != NULL) && 25652 (iattr->use->defValue != NULL)) { 25653 if (iattr->use->defVal == NULL) { 25654 /* VAL TODO: A default value was not precomputed. */ 25655 TODO 25656 goto eval_idcs; 25657 } 25658 iattr->vcValue = iattr->use->defValue; 25659 /* 25660 if (xmlSchemaCompareValuesWhtsp(attr->val, 25661 (xmlSchemaWhitespaceValueType) ws, 25662 attr->use->defVal, 25663 (xmlSchemaWhitespaceValueType) ws) != 0) { 25664 */ 25665 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25666 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25667 } else { 25668 if (iattr->decl->defVal == NULL) { 25669 /* VAL TODO: A default value was not precomputed. */ 25670 TODO 25671 goto eval_idcs; 25672 } 25673 iattr->vcValue = iattr->decl->defValue; 25674 /* 25675 if (xmlSchemaCompareValuesWhtsp(attr->val, 25676 (xmlSchemaWhitespaceValueType) ws, 25677 attrDecl->defVal, 25678 (xmlSchemaWhitespaceValueType) ws) != 0) { 25679 */ 25680 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25681 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25682 } 25683 /* 25684 * [validity] = "valid" 25685 */ 25686 } 25687 eval_idcs: 25688 /* 25689 * Evaluate IDCs. 25690 */ 25691 if (xpathRes) { 25692 if (xmlSchemaXPathProcessHistory(vctxt, 25693 vctxt->depth +1) == -1) { 25694 VERROR_INT("xmlSchemaVAttributesComplex", 25695 "calling xmlSchemaXPathEvaluate()"); 25696 goto internal_error; 25697 } 25698 } else if (vctxt->xpathStates != NULL) 25699 xmlSchemaXPathPop(vctxt); 25700 } 25701 25702 /* 25703 * Report errors. 25704 */ 25705 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25706 iattr = vctxt->attrInfos[i]; 25707 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25708 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25709 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25710 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25711 continue; 25712 ACTIVATE_ATTRIBUTE(iattr); 25713 switch (iattr->state) { 25714 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25715 xmlChar *str = NULL; 25716 ACTIVATE_ELEM; 25717 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25718 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25719 "The attribute '%s' is required but missing", 25720 xmlSchemaFormatQName(&str, 25721 iattr->decl->targetNamespace, 25722 iattr->decl->name), 25723 NULL); 25724 FREE_AND_NULL(str) 25725 break; 25726 } 25727 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25728 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25729 "The type definition is absent"); 25730 break; 25731 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25732 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25733 XML_SCHEMAV_CVC_AU, NULL, NULL, 25734 "The value '%s' does not match the fixed " 25735 "value constraint '%s'", 25736 iattr->value, iattr->vcValue); 25737 break; 25738 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25739 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25740 "No matching global attribute declaration available, but " 25741 "demanded by the strict wildcard"); 25742 break; 25743 case XML_SCHEMAS_ATTR_UNKNOWN: 25744 if (iattr->metaType) 25745 break; 25746 /* 25747 * MAYBE VAL TODO: One might report different error messages 25748 * for the following errors. 25749 */ 25750 if (type->attributeWildcard == NULL) { 25751 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25752 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25753 } else { 25754 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25755 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25756 } 25757 break; 25758 default: 25759 break; 25760 } 25761 } 25762 25763 ACTIVATE_ELEM; 25764 return (0); 25765 internal_error: 25766 ACTIVATE_ELEM; 25767 return (-1); 25768 } 25769 25770 static int 25771 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25772 int *skip) 25773 { 25774 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25775 /* 25776 * The namespace of the element was already identified to be 25777 * matching the wildcard. 25778 */ 25779 if ((skip == NULL) || (wild == NULL) || 25780 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25781 VERROR_INT("xmlSchemaValidateElemWildcard", 25782 "bad arguments"); 25783 return (-1); 25784 } 25785 *skip = 0; 25786 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25787 /* 25788 * URGENT VAL TODO: Either we need to position the stream to the 25789 * next sibling, or walk the whole subtree. 25790 */ 25791 *skip = 1; 25792 return (0); 25793 } 25794 { 25795 xmlSchemaElementPtr decl = NULL; 25796 25797 decl = xmlSchemaGetElem(vctxt->schema, 25798 vctxt->inode->localName, vctxt->inode->nsName); 25799 if (decl != NULL) { 25800 vctxt->inode->decl = decl; 25801 return (0); 25802 } 25803 } 25804 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25805 /* VAL TODO: Change to proper error code. */ 25806 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25807 "No matching global element declaration available, but " 25808 "demanded by the strict wildcard"); 25809 return (vctxt->err); 25810 } 25811 if (vctxt->nbAttrInfos != 0) { 25812 xmlSchemaAttrInfoPtr iattr; 25813 /* 25814 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25815 * (1.2.1.2.1) - (1.2.1.2.3 ) 25816 * 25817 * Use the xsi:type attribute for the type definition. 25818 */ 25819 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25820 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25821 if (iattr != NULL) { 25822 if (xmlSchemaProcessXSIType(vctxt, iattr, 25823 &(vctxt->inode->typeDef), NULL) == -1) { 25824 VERROR_INT("xmlSchemaValidateElemWildcard", 25825 "calling xmlSchemaProcessXSIType() to " 25826 "process the attribute 'xsi:nil'"); 25827 return (-1); 25828 } 25829 /* 25830 * Don't return an error on purpose. 25831 */ 25832 return (0); 25833 } 25834 } 25835 /* 25836 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25837 * 25838 * Fallback to "anyType". 25839 */ 25840 vctxt->inode->typeDef = 25841 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25842 return (0); 25843 } 25844 25845 /* 25846 * xmlSchemaCheckCOSValidDefault: 25847 * 25848 * This will be called if: not nilled, no content and a default/fixed 25849 * value is provided. 25850 */ 25851 25852 static int 25853 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25854 const xmlChar *value, 25855 xmlSchemaValPtr *val) 25856 { 25857 int ret = 0; 25858 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25859 25860 /* 25861 * cos-valid-default: 25862 * Schema Component Constraint: Element Default Valid (Immediate) 25863 * For a string to be a valid default with respect to a type 25864 * definition the appropriate case among the following must be true: 25865 */ 25866 if WXS_IS_COMPLEX(inode->typeDef) { 25867 /* 25868 * Complex type. 25869 * 25870 * SPEC (2.1) "its {content type} must be a simple type definition 25871 * or mixed." 25872 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25873 * type}'s particle must be emptiable as defined by 25874 * Particle Emptiable (3.9.6)." 25875 */ 25876 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25877 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25878 (! WXS_EMPTIABLE(inode->typeDef)))) { 25879 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25880 /* NOTE that this covers (2.2.2) as well. */ 25881 VERROR(ret, NULL, 25882 "For a string to be a valid default, the type definition " 25883 "must be a simple type or a complex type with simple content " 25884 "or mixed content and a particle emptiable"); 25885 return(ret); 25886 } 25887 } 25888 /* 25889 * 1 If the type definition is a simple type definition, then the string 25890 * must be valid with respect to that definition as defined by String 25891 * Valid (3.14.4). 25892 * 25893 * AND 25894 * 25895 * 2.2.1 If the {content type} is a simple type definition, then the 25896 * string must be valid with respect to that simple type definition 25897 * as defined by String Valid (3.14.4). 25898 */ 25899 if (WXS_IS_SIMPLE(inode->typeDef)) { 25900 25901 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25902 NULL, inode->typeDef, value, val, 1, 1, 0); 25903 25904 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25905 25906 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25907 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25908 } 25909 if (ret < 0) { 25910 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25911 "calling xmlSchemaVCheckCVCSimpleType()"); 25912 } 25913 return (ret); 25914 } 25915 25916 static void 25917 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 25918 const xmlChar * name ATTRIBUTE_UNUSED, 25919 xmlSchemaElementPtr item, 25920 xmlSchemaNodeInfoPtr inode) 25921 { 25922 inode->decl = item; 25923 #ifdef DEBUG_CONTENT 25924 { 25925 xmlChar *str = NULL; 25926 25927 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25928 xmlGenericError(xmlGenericErrorContext, 25929 "AUTOMATON callback for '%s' [declaration]\n", 25930 xmlSchemaFormatQName(&str, 25931 inode->localName, inode->nsName)); 25932 } else { 25933 xmlGenericError(xmlGenericErrorContext, 25934 "AUTOMATON callback for '%s' [wildcard]\n", 25935 xmlSchemaFormatQName(&str, 25936 inode->localName, inode->nsName)); 25937 25938 } 25939 FREE_AND_NULL(str) 25940 } 25941 #endif 25942 } 25943 25944 static int 25945 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 25946 { 25947 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 25948 if (vctxt->inode == NULL) { 25949 VERROR_INT("xmlSchemaValidatorPushElem", 25950 "calling xmlSchemaGetFreshElemInfo()"); 25951 return (-1); 25952 } 25953 vctxt->nbAttrInfos = 0; 25954 return (0); 25955 } 25956 25957 static int 25958 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 25959 xmlSchemaNodeInfoPtr inode, 25960 xmlSchemaTypePtr type, 25961 const xmlChar *value) 25962 { 25963 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 25964 return (xmlSchemaVCheckCVCSimpleType( 25965 ACTXT_CAST vctxt, NULL, 25966 type, value, &(inode->val), 1, 1, 0)); 25967 else 25968 return (xmlSchemaVCheckCVCSimpleType( 25969 ACTXT_CAST vctxt, NULL, 25970 type, value, NULL, 1, 0, 0)); 25971 } 25972 25973 25974 25975 /* 25976 * Process END of element. 25977 */ 25978 static int 25979 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 25980 { 25981 int ret = 0; 25982 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25983 25984 if (vctxt->nbAttrInfos != 0) 25985 xmlSchemaClearAttrInfos(vctxt); 25986 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 25987 /* 25988 * This element was not expected; 25989 * we will not validate child elements of broken parents. 25990 * Skip validation of all content of the parent. 25991 */ 25992 vctxt->skipDepth = vctxt->depth -1; 25993 goto end_elem; 25994 } 25995 if ((inode->typeDef == NULL) || 25996 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 25997 /* 25998 * 1. the type definition might be missing if the element was 25999 * error prone 26000 * 2. it might be abstract. 26001 */ 26002 goto end_elem; 26003 } 26004 /* 26005 * Check the content model. 26006 */ 26007 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26008 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26009 26010 /* 26011 * Workaround for "anyType". 26012 */ 26013 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26014 goto character_content; 26015 26016 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26017 xmlChar *values[10]; 26018 int terminal, nbval = 10, nbneg; 26019 26020 if (inode->regexCtxt == NULL) { 26021 /* 26022 * Create the regex context. 26023 */ 26024 inode->regexCtxt = 26025 xmlRegNewExecCtxt(inode->typeDef->contModel, 26026 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26027 vctxt); 26028 if (inode->regexCtxt == NULL) { 26029 VERROR_INT("xmlSchemaValidatorPopElem", 26030 "failed to create a regex context"); 26031 goto internal_error; 26032 } 26033 #ifdef DEBUG_AUTOMATA 26034 xmlGenericError(xmlGenericErrorContext, 26035 "AUTOMATON create on '%s'\n", inode->localName); 26036 #endif 26037 } 26038 /* 26039 * Get hold of the still expected content, since a further 26040 * call to xmlRegExecPushString() will loose this information. 26041 */ 26042 xmlRegExecNextValues(inode->regexCtxt, 26043 &nbval, &nbneg, &values[0], &terminal); 26044 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26045 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26046 /* 26047 * Still missing something. 26048 */ 26049 ret = 1; 26050 inode->flags |= 26051 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26052 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26053 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26054 "Missing child element(s)", 26055 nbval, nbneg, values); 26056 #ifdef DEBUG_AUTOMATA 26057 xmlGenericError(xmlGenericErrorContext, 26058 "AUTOMATON missing ERROR on '%s'\n", 26059 inode->localName); 26060 #endif 26061 } else { 26062 /* 26063 * Content model is satisfied. 26064 */ 26065 ret = 0; 26066 #ifdef DEBUG_AUTOMATA 26067 xmlGenericError(xmlGenericErrorContext, 26068 "AUTOMATON succeeded on '%s'\n", 26069 inode->localName); 26070 #endif 26071 } 26072 26073 } 26074 } 26075 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26076 goto end_elem; 26077 26078 character_content: 26079 26080 if (vctxt->value != NULL) { 26081 xmlSchemaFreeValue(vctxt->value); 26082 vctxt->value = NULL; 26083 } 26084 /* 26085 * Check character content. 26086 */ 26087 if (inode->decl == NULL) { 26088 /* 26089 * Speedup if no declaration exists. 26090 */ 26091 if (WXS_IS_SIMPLE(inode->typeDef)) { 26092 ret = xmlSchemaVCheckINodeDataType(vctxt, 26093 inode, inode->typeDef, inode->value); 26094 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26095 ret = xmlSchemaVCheckINodeDataType(vctxt, 26096 inode, inode->typeDef->contentTypeDef, 26097 inode->value); 26098 } 26099 if (ret < 0) { 26100 VERROR_INT("xmlSchemaValidatorPopElem", 26101 "calling xmlSchemaVCheckCVCSimpleType()"); 26102 goto internal_error; 26103 } 26104 goto end_elem; 26105 } 26106 /* 26107 * cvc-elt (3.3.4) : 5 26108 * The appropriate case among the following must be true: 26109 */ 26110 /* 26111 * cvc-elt (3.3.4) : 5.1 26112 * If the declaration has a {value constraint}, 26113 * the item has neither element nor character [children] and 26114 * clause 3.2 has not applied, then all of the following must be true: 26115 */ 26116 if ((inode->decl->value != NULL) && 26117 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26118 (! INODE_NILLED(inode))) { 26119 /* 26120 * cvc-elt (3.3.4) : 5.1.1 26121 * If the actual type definition is a local type definition 26122 * then the canonical lexical representation of the {value constraint} 26123 * value must be a valid default for the actual type definition as 26124 * defined in Element Default Valid (Immediate) (3.3.6). 26125 */ 26126 /* 26127 * NOTE: 'local' above means types acquired by xsi:type. 26128 * NOTE: Although the *canonical* value is stated, it is not 26129 * relevant if canonical or not. Additionally XML Schema 1.1 26130 * will removed this requirement as well. 26131 */ 26132 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26133 26134 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26135 inode->decl->value, &(inode->val)); 26136 if (ret != 0) { 26137 if (ret < 0) { 26138 VERROR_INT("xmlSchemaValidatorPopElem", 26139 "calling xmlSchemaCheckCOSValidDefault()"); 26140 goto internal_error; 26141 } 26142 goto end_elem; 26143 } 26144 /* 26145 * Stop here, to avoid redundant validation of the value 26146 * (see following). 26147 */ 26148 goto default_psvi; 26149 } 26150 /* 26151 * cvc-elt (3.3.4) : 5.1.2 26152 * The element information item with the canonical lexical 26153 * representation of the {value constraint} value used as its 26154 * normalized value must be valid with respect to the 26155 * actual type definition as defined by Element Locally Valid (Type) 26156 * (3.3.4). 26157 */ 26158 if (WXS_IS_SIMPLE(inode->typeDef)) { 26159 ret = xmlSchemaVCheckINodeDataType(vctxt, 26160 inode, inode->typeDef, inode->decl->value); 26161 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26162 ret = xmlSchemaVCheckINodeDataType(vctxt, 26163 inode, inode->typeDef->contentTypeDef, 26164 inode->decl->value); 26165 } 26166 if (ret != 0) { 26167 if (ret < 0) { 26168 VERROR_INT("xmlSchemaValidatorPopElem", 26169 "calling xmlSchemaVCheckCVCSimpleType()"); 26170 goto internal_error; 26171 } 26172 goto end_elem; 26173 } 26174 26175 default_psvi: 26176 /* 26177 * PSVI: Create a text node on the instance element. 26178 */ 26179 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26180 (inode->node != NULL)) { 26181 xmlNodePtr textChild; 26182 xmlChar *normValue; 26183 /* 26184 * VAL TODO: Normalize the value. 26185 */ 26186 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26187 inode->decl->value); 26188 if (normValue != NULL) { 26189 textChild = xmlNewText(BAD_CAST normValue); 26190 xmlFree(normValue); 26191 } else 26192 textChild = xmlNewText(inode->decl->value); 26193 if (textChild == NULL) { 26194 VERROR_INT("xmlSchemaValidatorPopElem", 26195 "calling xmlNewText()"); 26196 goto internal_error; 26197 } else 26198 xmlAddChild(inode->node, textChild); 26199 } 26200 26201 } else if (! INODE_NILLED(inode)) { 26202 /* 26203 * 5.2.1 The element information item must be valid with respect 26204 * to the actual type definition as defined by Element Locally 26205 * Valid (Type) (3.3.4). 26206 */ 26207 if (WXS_IS_SIMPLE(inode->typeDef)) { 26208 /* 26209 * SPEC (cvc-type) (3.1) 26210 * "If the type definition is a simple type definition, ..." 26211 * (3.1.3) "If clause 3.2 of Element Locally Valid 26212 * (Element) (3.3.4) did not apply, then the normalized value 26213 * must be valid with respect to the type definition as defined 26214 * by String Valid (3.14.4). 26215 */ 26216 ret = xmlSchemaVCheckINodeDataType(vctxt, 26217 inode, inode->typeDef, inode->value); 26218 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26219 /* 26220 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26221 * definition, then the element information item must be 26222 * valid with respect to the type definition as per 26223 * Element Locally Valid (Complex Type) (3.4.4);" 26224 * 26225 * SPEC (cvc-complex-type) (2.2) 26226 * "If the {content type} is a simple type definition, ... 26227 * the normalized value of the element information item is 26228 * valid with respect to that simple type definition as 26229 * defined by String Valid (3.14.4)." 26230 */ 26231 ret = xmlSchemaVCheckINodeDataType(vctxt, 26232 inode, inode->typeDef->contentTypeDef, inode->value); 26233 } 26234 if (ret != 0) { 26235 if (ret < 0) { 26236 VERROR_INT("xmlSchemaValidatorPopElem", 26237 "calling xmlSchemaVCheckCVCSimpleType()"); 26238 goto internal_error; 26239 } 26240 goto end_elem; 26241 } 26242 /* 26243 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26244 * not applied, all of the following must be true: 26245 */ 26246 if ((inode->decl->value != NULL) && 26247 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26248 26249 /* 26250 * TODO: We will need a computed value, when comparison is 26251 * done on computed values. 26252 */ 26253 /* 26254 * 5.2.2.1 The element information item must have no element 26255 * information item [children]. 26256 */ 26257 if (inode->flags & 26258 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26259 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26260 VERROR(ret, NULL, 26261 "The content must not containt element nodes since " 26262 "there is a fixed value constraint"); 26263 goto end_elem; 26264 } else { 26265 /* 26266 * 5.2.2.2 The appropriate case among the following must 26267 * be true: 26268 */ 26269 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26270 /* 26271 * 5.2.2.2.1 If the {content type} of the actual type 26272 * definition is mixed, then the *initial value* of the 26273 * item must match the canonical lexical representation 26274 * of the {value constraint} value. 26275 * 26276 * ... the *initial value* of an element information 26277 * item is the string composed of, in order, the 26278 * [character code] of each character information item in 26279 * the [children] of that element information item. 26280 */ 26281 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26282 /* 26283 * VAL TODO: Report invalid & expected values as well. 26284 * VAL TODO: Implement the canonical stuff. 26285 */ 26286 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26287 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26288 ret, NULL, NULL, 26289 "The initial value '%s' does not match the fixed " 26290 "value constraint '%s'", 26291 inode->value, inode->decl->value); 26292 goto end_elem; 26293 } 26294 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26295 /* 26296 * 5.2.2.2.2 If the {content type} of the actual type 26297 * definition is a simple type definition, then the 26298 * *actual value* of the item must match the canonical 26299 * lexical representation of the {value constraint} value. 26300 */ 26301 /* 26302 * VAL TODO: *actual value* is the normalized value, impl. 26303 * this. 26304 * VAL TODO: Report invalid & expected values as well. 26305 * VAL TODO: Implement a comparison with the computed values. 26306 */ 26307 if (! xmlStrEqual(inode->value, 26308 inode->decl->value)) { 26309 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26310 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26311 ret, NULL, NULL, 26312 "The actual value '%s' does not match the fixed " 26313 "value constraint '%s'", 26314 inode->value, 26315 inode->decl->value); 26316 goto end_elem; 26317 } 26318 } 26319 } 26320 } 26321 } 26322 26323 end_elem: 26324 if (vctxt->depth < 0) { 26325 /* TODO: raise error? */ 26326 return (0); 26327 } 26328 if (vctxt->depth == vctxt->skipDepth) 26329 vctxt->skipDepth = -1; 26330 /* 26331 * Evaluate the history of XPath state objects. 26332 */ 26333 if (inode->appliedXPath && 26334 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26335 goto internal_error; 26336 /* 26337 * MAYBE TODO: 26338 * SPEC (6) "The element information item must be valid with 26339 * respect to each of the {identity-constraint definitions} as per 26340 * Identity-constraint Satisfied (3.11.4)." 26341 */ 26342 /* 26343 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26344 * need to be built in any case. 26345 * We will currently build IDC node-tables and bubble them only if 26346 * keyrefs do exist. 26347 */ 26348 26349 /* 26350 * Add the current IDC target-nodes to the IDC node-tables. 26351 */ 26352 if ((inode->idcMatchers != NULL) && 26353 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26354 { 26355 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26356 goto internal_error; 26357 } 26358 /* 26359 * Validate IDC keyrefs. 26360 */ 26361 if (vctxt->inode->hasKeyrefs) 26362 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26363 goto internal_error; 26364 /* 26365 * Merge/free the IDC table. 26366 */ 26367 if (inode->idcTable != NULL) { 26368 #ifdef DEBUG_IDC_NODE_TABLE 26369 xmlSchemaDebugDumpIDCTable(stdout, 26370 inode->nsName, 26371 inode->localName, 26372 inode->idcTable); 26373 #endif 26374 if ((vctxt->depth > 0) && 26375 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26376 { 26377 /* 26378 * Merge the IDC node table with the table of the parent node. 26379 */ 26380 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26381 goto internal_error; 26382 } 26383 } 26384 /* 26385 * Clear the current ielem. 26386 * VAL TODO: Don't free the PSVI IDC tables if they are 26387 * requested for the PSVI. 26388 */ 26389 xmlSchemaClearElemInfo(vctxt, inode); 26390 /* 26391 * Skip further processing if we are on the validation root. 26392 */ 26393 if (vctxt->depth == 0) { 26394 vctxt->depth--; 26395 vctxt->inode = NULL; 26396 return (0); 26397 } 26398 /* 26399 * Reset the keyrefDepth if needed. 26400 */ 26401 if (vctxt->aidcs != NULL) { 26402 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26403 do { 26404 if (aidc->keyrefDepth == vctxt->depth) { 26405 /* 26406 * A 'keyrefDepth' of a key/unique IDC matches the current 26407 * depth, this means that we are leaving the scope of the 26408 * top-most keyref IDC which refers to this IDC. 26409 */ 26410 aidc->keyrefDepth = -1; 26411 } 26412 aidc = aidc->next; 26413 } while (aidc != NULL); 26414 } 26415 vctxt->depth--; 26416 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26417 /* 26418 * VAL TODO: 7 If the element information item is the validation root, it must be 26419 * valid per Validation Root Valid (ID/IDREF) (3.3.4). 26420 */ 26421 return (ret); 26422 26423 internal_error: 26424 vctxt->err = -1; 26425 return (-1); 26426 } 26427 26428 /* 26429 * 3.4.4 Complex Type Definition Validation Rules 26430 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26431 */ 26432 static int 26433 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26434 { 26435 xmlSchemaNodeInfoPtr pielem; 26436 xmlSchemaTypePtr ptype; 26437 int ret = 0; 26438 26439 if (vctxt->depth <= 0) { 26440 VERROR_INT("xmlSchemaValidateChildElem", 26441 "not intended for the validation root"); 26442 return (-1); 26443 } 26444 pielem = vctxt->elemInfos[vctxt->depth -1]; 26445 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26446 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26447 /* 26448 * Handle 'nilled' elements. 26449 */ 26450 if (INODE_NILLED(pielem)) { 26451 /* 26452 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26453 */ 26454 ACTIVATE_PARENT_ELEM; 26455 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26456 VERROR(ret, NULL, 26457 "Neither character nor element content is allowed, " 26458 "because the element was 'nilled'"); 26459 ACTIVATE_ELEM; 26460 goto unexpected_elem; 26461 } 26462 26463 ptype = pielem->typeDef; 26464 26465 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26466 /* 26467 * Workaround for "anyType": we have currently no content model 26468 * assigned for "anyType", so handle it explicitely. 26469 * "anyType" has an unbounded, lax "any" wildcard. 26470 */ 26471 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26472 vctxt->inode->localName, 26473 vctxt->inode->nsName); 26474 26475 if (vctxt->inode->decl == NULL) { 26476 xmlSchemaAttrInfoPtr iattr; 26477 /* 26478 * Process "xsi:type". 26479 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26480 */ 26481 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26482 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26483 if (iattr != NULL) { 26484 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26485 &(vctxt->inode->typeDef), NULL); 26486 if (ret != 0) { 26487 if (ret == -1) { 26488 VERROR_INT("xmlSchemaValidateChildElem", 26489 "calling xmlSchemaProcessXSIType() to " 26490 "process the attribute 'xsi:nil'"); 26491 return (-1); 26492 } 26493 return (ret); 26494 } 26495 } else { 26496 /* 26497 * Fallback to "anyType". 26498 * 26499 * SPEC (cvc-assess-elt) 26500 * "If the item cannot be strictly assessed, [...] 26501 * an element information item's schema validity may be laxly 26502 * assessed if its context-determined declaration is not 26503 * skip by validating with respect to the ur-type 26504 * definition as per Element Locally Valid (Type) (3.3.4)." 26505 */ 26506 vctxt->inode->typeDef = 26507 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26508 } 26509 } 26510 return (0); 26511 } 26512 26513 switch (ptype->contentType) { 26514 case XML_SCHEMA_CONTENT_EMPTY: 26515 /* 26516 * SPEC (2.1) "If the {content type} is empty, then the 26517 * element information item has no character or element 26518 * information item [children]." 26519 */ 26520 ACTIVATE_PARENT_ELEM 26521 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26522 VERROR(ret, NULL, 26523 "Element content is not allowed, " 26524 "because the content type is empty"); 26525 ACTIVATE_ELEM 26526 goto unexpected_elem; 26527 break; 26528 26529 case XML_SCHEMA_CONTENT_MIXED: 26530 case XML_SCHEMA_CONTENT_ELEMENTS: { 26531 xmlRegExecCtxtPtr regexCtxt; 26532 xmlChar *values[10]; 26533 int terminal, nbval = 10, nbneg; 26534 26535 /* VAL TODO: Optimized "anyType" validation.*/ 26536 26537 if (ptype->contModel == NULL) { 26538 VERROR_INT("xmlSchemaValidateChildElem", 26539 "type has elem content but no content model"); 26540 return (-1); 26541 } 26542 /* 26543 * Safety belf for evaluation if the cont. model was already 26544 * examined to be invalid. 26545 */ 26546 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26547 VERROR_INT("xmlSchemaValidateChildElem", 26548 "validating elem, but elem content is already invalid"); 26549 return (-1); 26550 } 26551 26552 regexCtxt = pielem->regexCtxt; 26553 if (regexCtxt == NULL) { 26554 /* 26555 * Create the regex context. 26556 */ 26557 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26558 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26559 vctxt); 26560 if (regexCtxt == NULL) { 26561 VERROR_INT("xmlSchemaValidateChildElem", 26562 "failed to create a regex context"); 26563 return (-1); 26564 } 26565 pielem->regexCtxt = regexCtxt; 26566 #ifdef DEBUG_AUTOMATA 26567 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26568 pielem->localName); 26569 #endif 26570 } 26571 26572 /* 26573 * SPEC (2.4) "If the {content type} is element-only or mixed, 26574 * then the sequence of the element information item's 26575 * element information item [children], if any, taken in 26576 * order, is valid with respect to the {content type}'s 26577 * particle, as defined in Element Sequence Locally Valid 26578 * (Particle) (3.9.4)." 26579 */ 26580 ret = xmlRegExecPushString2(regexCtxt, 26581 vctxt->inode->localName, 26582 vctxt->inode->nsName, 26583 vctxt->inode); 26584 #ifdef DEBUG_AUTOMATA 26585 if (ret < 0) 26586 xmlGenericError(xmlGenericErrorContext, 26587 "AUTOMATON push ERROR for '%s' on '%s'\n", 26588 vctxt->inode->localName, pielem->localName); 26589 else 26590 xmlGenericError(xmlGenericErrorContext, 26591 "AUTOMATON push OK for '%s' on '%s'\n", 26592 vctxt->inode->localName, pielem->localName); 26593 #endif 26594 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26595 VERROR_INT("xmlSchemaValidateChildElem", 26596 "calling xmlRegExecPushString2()"); 26597 return (-1); 26598 } 26599 if (ret < 0) { 26600 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26601 &values[0], &terminal); 26602 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26603 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26604 "This element is not expected", 26605 nbval, nbneg, values); 26606 ret = vctxt->err; 26607 goto unexpected_elem; 26608 } else 26609 ret = 0; 26610 } 26611 break; 26612 case XML_SCHEMA_CONTENT_SIMPLE: 26613 case XML_SCHEMA_CONTENT_BASIC: 26614 ACTIVATE_PARENT_ELEM 26615 if (WXS_IS_COMPLEX(ptype)) { 26616 /* 26617 * SPEC (cvc-complex-type) (2.2) 26618 * "If the {content type} is a simple type definition, then 26619 * the element information item has no element information 26620 * item [children], ..." 26621 */ 26622 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26623 VERROR(ret, NULL, "Element content is not allowed, " 26624 "because the content type is a simple type definition"); 26625 } else { 26626 /* 26627 * SPEC (cvc-type) (3.1.2) "The element information item must 26628 * have no element information item [children]." 26629 */ 26630 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26631 VERROR(ret, NULL, "Element content is not allowed, " 26632 "because the type definition is simple"); 26633 } 26634 ACTIVATE_ELEM 26635 ret = vctxt->err; 26636 goto unexpected_elem; 26637 break; 26638 26639 default: 26640 break; 26641 } 26642 return (ret); 26643 unexpected_elem: 26644 /* 26645 * Pop this element and set the skipDepth to skip 26646 * all further content of the parent element. 26647 */ 26648 vctxt->skipDepth = vctxt->depth; 26649 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26650 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26651 return (ret); 26652 } 26653 26654 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26655 #define XML_SCHEMA_PUSH_TEXT_CREATED 2 26656 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26657 26658 static int 26659 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26660 int nodeType, const xmlChar *value, int len, 26661 int mode, int *consumed) 26662 { 26663 /* 26664 * Unfortunately we have to duplicate the text sometimes. 26665 * OPTIMIZE: Maybe we could skip it, if: 26666 * 1. content type is simple 26667 * 2. whitespace is "collapse" 26668 * 3. it consists of whitespace only 26669 * 26670 * Process character content. 26671 */ 26672 if (consumed != NULL) 26673 *consumed = 0; 26674 if (INODE_NILLED(vctxt->inode)) { 26675 /* 26676 * SPEC cvc-elt (3.3.4 - 3.2.1) 26677 * "The element information item must have no character or 26678 * element information item [children]." 26679 */ 26680 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26681 "Neither character nor element content is allowed " 26682 "because the element is 'nilled'"); 26683 return (vctxt->err); 26684 } 26685 /* 26686 * SPEC (2.1) "If the {content type} is empty, then the 26687 * element information item has no character or element 26688 * information item [children]." 26689 */ 26690 if (vctxt->inode->typeDef->contentType == 26691 XML_SCHEMA_CONTENT_EMPTY) { 26692 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26693 "Character content is not allowed, " 26694 "because the content type is empty"); 26695 return (vctxt->err); 26696 } 26697 26698 if (vctxt->inode->typeDef->contentType == 26699 XML_SCHEMA_CONTENT_ELEMENTS) { 26700 if ((nodeType != XML_TEXT_NODE) || 26701 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26702 /* 26703 * SPEC cvc-complex-type (2.3) 26704 * "If the {content type} is element-only, then the 26705 * element information item has no character information 26706 * item [children] other than those whose [character 26707 * code] is defined as a white space in [XML 1.0 (Second 26708 * Edition)]." 26709 */ 26710 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26711 "Character content other than whitespace is not allowed " 26712 "because the content type is 'element-only'"); 26713 return (vctxt->err); 26714 } 26715 return (0); 26716 } 26717 26718 if ((value == NULL) || (value[0] == 0)) 26719 return (0); 26720 /* 26721 * Save the value. 26722 * NOTE that even if the content type is *mixed*, we need the 26723 * *initial value* for default/fixed value constraints. 26724 */ 26725 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26726 ((vctxt->inode->decl == NULL) || 26727 (vctxt->inode->decl->value == NULL))) 26728 return (0); 26729 26730 if (vctxt->inode->value == NULL) { 26731 /* 26732 * Set the value. 26733 */ 26734 switch (mode) { 26735 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26736 /* 26737 * When working on a tree. 26738 */ 26739 vctxt->inode->value = value; 26740 break; 26741 case XML_SCHEMA_PUSH_TEXT_CREATED: 26742 /* 26743 * When working with the reader. 26744 * The value will be freed by the element info. 26745 */ 26746 vctxt->inode->value = value; 26747 if (consumed != NULL) 26748 *consumed = 1; 26749 vctxt->inode->flags |= 26750 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26751 break; 26752 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26753 /* 26754 * When working with SAX. 26755 * The value will be freed by the element info. 26756 */ 26757 if (len != -1) 26758 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26759 else 26760 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26761 vctxt->inode->flags |= 26762 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26763 break; 26764 default: 26765 break; 26766 } 26767 } else { 26768 if (len < 0) 26769 len = xmlStrlen(value); 26770 /* 26771 * Concat the value. 26772 */ 26773 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26774 vctxt->inode->value = BAD_CAST xmlStrncat( 26775 (xmlChar *) vctxt->inode->value, value, len); 26776 } else { 26777 vctxt->inode->value = 26778 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26779 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26780 } 26781 } 26782 26783 return (0); 26784 } 26785 26786 static int 26787 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26788 { 26789 int ret = 0; 26790 26791 if ((vctxt->skipDepth != -1) && 26792 (vctxt->depth >= vctxt->skipDepth)) { 26793 VERROR_INT("xmlSchemaValidateElem", 26794 "in skip-state"); 26795 goto internal_error; 26796 } 26797 if (vctxt->xsiAssemble) { 26798 /* 26799 * We will stop validation if there was an error during 26800 * dynamic schema construction. 26801 * Note that we simply set @skipDepth to 0, this could 26802 * mean that a streaming document via SAX would be 26803 * still read to the end but it won't be validated any more. 26804 * TODO: If we are sure how to stop the validation at once 26805 * for all input scenarios, then this should be changed to 26806 * instantly stop the validation. 26807 */ 26808 ret = xmlSchemaAssembleByXSI(vctxt); 26809 if (ret != 0) { 26810 if (ret == -1) 26811 goto internal_error; 26812 vctxt->skipDepth = 0; 26813 return(ret); 26814 } 26815 /* 26816 * Augment the IDC definitions for the main schema and all imported ones 26817 * NOTE: main schema is the first in the imported list 26818 */ 26819 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 26820 } 26821 if (vctxt->depth > 0) { 26822 /* 26823 * Validate this element against the content model 26824 * of the parent. 26825 */ 26826 ret = xmlSchemaValidateChildElem(vctxt); 26827 if (ret != 0) { 26828 if (ret < 0) { 26829 VERROR_INT("xmlSchemaValidateElem", 26830 "calling xmlSchemaStreamValidateChildElement()"); 26831 goto internal_error; 26832 } 26833 goto exit; 26834 } 26835 if (vctxt->depth == vctxt->skipDepth) 26836 goto exit; 26837 if ((vctxt->inode->decl == NULL) && 26838 (vctxt->inode->typeDef == NULL)) { 26839 VERROR_INT("xmlSchemaValidateElem", 26840 "the child element was valid but neither the " 26841 "declaration nor the type was set"); 26842 goto internal_error; 26843 } 26844 } else { 26845 /* 26846 * Get the declaration of the validation root. 26847 */ 26848 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26849 vctxt->inode->localName, 26850 vctxt->inode->nsName); 26851 if (vctxt->inode->decl == NULL) { 26852 ret = XML_SCHEMAV_CVC_ELT_1; 26853 VERROR(ret, NULL, 26854 "No matching global declaration available " 26855 "for the validation root"); 26856 goto exit; 26857 } 26858 } 26859 26860 if (vctxt->inode->decl == NULL) 26861 goto type_validation; 26862 26863 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26864 int skip; 26865 /* 26866 * Wildcards. 26867 */ 26868 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26869 if (ret != 0) { 26870 if (ret < 0) { 26871 VERROR_INT("xmlSchemaValidateElem", 26872 "calling xmlSchemaValidateElemWildcard()"); 26873 goto internal_error; 26874 } 26875 goto exit; 26876 } 26877 if (skip) { 26878 vctxt->skipDepth = vctxt->depth; 26879 goto exit; 26880 } 26881 /* 26882 * The declaration might be set by the wildcard validation, 26883 * when the processContents is "lax" or "strict". 26884 */ 26885 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26886 /* 26887 * Clear the "decl" field to not confuse further processing. 26888 */ 26889 vctxt->inode->decl = NULL; 26890 goto type_validation; 26891 } 26892 } 26893 /* 26894 * Validate against the declaration. 26895 */ 26896 ret = xmlSchemaValidateElemDecl(vctxt); 26897 if (ret != 0) { 26898 if (ret < 0) { 26899 VERROR_INT("xmlSchemaValidateElem", 26900 "calling xmlSchemaValidateElemDecl()"); 26901 goto internal_error; 26902 } 26903 goto exit; 26904 } 26905 /* 26906 * Validate against the type definition. 26907 */ 26908 type_validation: 26909 26910 if (vctxt->inode->typeDef == NULL) { 26911 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26912 ret = XML_SCHEMAV_CVC_TYPE_1; 26913 VERROR(ret, NULL, 26914 "The type definition is absent"); 26915 goto exit; 26916 } 26917 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26918 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26919 ret = XML_SCHEMAV_CVC_TYPE_2; 26920 VERROR(ret, NULL, 26921 "The type definition is abstract"); 26922 goto exit; 26923 } 26924 /* 26925 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26926 * during validation against the declaration. This must be done 26927 * _before_ attribute validation. 26928 */ 26929 if (vctxt->xpathStates != NULL) { 26930 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 26931 vctxt->inode->appliedXPath = 1; 26932 if (ret == -1) { 26933 VERROR_INT("xmlSchemaValidateElem", 26934 "calling xmlSchemaXPathEvaluate()"); 26935 goto internal_error; 26936 } 26937 } 26938 /* 26939 * Validate attributes. 26940 */ 26941 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 26942 if ((vctxt->nbAttrInfos != 0) || 26943 (vctxt->inode->typeDef->attrUses != NULL)) { 26944 26945 ret = xmlSchemaVAttributesComplex(vctxt); 26946 } 26947 } else if (vctxt->nbAttrInfos != 0) { 26948 26949 ret = xmlSchemaVAttributesSimple(vctxt); 26950 } 26951 /* 26952 * Clear registered attributes. 26953 */ 26954 if (vctxt->nbAttrInfos != 0) 26955 xmlSchemaClearAttrInfos(vctxt); 26956 if (ret == -1) { 26957 VERROR_INT("xmlSchemaValidateElem", 26958 "calling attributes validation"); 26959 goto internal_error; 26960 } 26961 /* 26962 * Don't return an error if attributes are invalid on purpose. 26963 */ 26964 ret = 0; 26965 26966 exit: 26967 if (ret != 0) 26968 vctxt->skipDepth = vctxt->depth; 26969 return (ret); 26970 internal_error: 26971 return (-1); 26972 } 26973 26974 #ifdef XML_SCHEMA_READER_ENABLED 26975 static int 26976 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 26977 { 26978 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 26979 int depth, nodeType, ret = 0, consumed; 26980 xmlSchemaNodeInfoPtr ielem; 26981 26982 vctxt->depth = -1; 26983 ret = xmlTextReaderRead(vctxt->reader); 26984 /* 26985 * Move to the document element. 26986 */ 26987 while (ret == 1) { 26988 nodeType = xmlTextReaderNodeType(vctxt->reader); 26989 if (nodeType == XML_ELEMENT_NODE) 26990 goto root_found; 26991 ret = xmlTextReaderRead(vctxt->reader); 26992 } 26993 goto exit; 26994 26995 root_found: 26996 26997 do { 26998 depth = xmlTextReaderDepth(vctxt->reader); 26999 nodeType = xmlTextReaderNodeType(vctxt->reader); 27000 27001 if (nodeType == XML_ELEMENT_NODE) { 27002 27003 vctxt->depth++; 27004 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27005 VERROR_INT("xmlSchemaVReaderWalk", 27006 "calling xmlSchemaValidatorPushElem()"); 27007 goto internal_error; 27008 } 27009 ielem = vctxt->inode; 27010 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27011 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27012 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27013 /* 27014 * Is the element empty? 27015 */ 27016 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27017 if (ret == -1) { 27018 VERROR_INT("xmlSchemaVReaderWalk", 27019 "calling xmlTextReaderIsEmptyElement()"); 27020 goto internal_error; 27021 } 27022 if (ret) { 27023 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27024 } 27025 /* 27026 * Register attributes. 27027 */ 27028 vctxt->nbAttrInfos = 0; 27029 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27030 if (ret == -1) { 27031 VERROR_INT("xmlSchemaVReaderWalk", 27032 "calling xmlTextReaderMoveToFirstAttribute()"); 27033 goto internal_error; 27034 } 27035 if (ret == 1) { 27036 do { 27037 /* 27038 * VAL TODO: How do we know that the reader works on a 27039 * node tree, to be able to pass a node here? 27040 */ 27041 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27042 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27043 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27044 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27045 27046 VERROR_INT("xmlSchemaVReaderWalk", 27047 "calling xmlSchemaValidatorPushAttribute()"); 27048 goto internal_error; 27049 } 27050 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27051 if (ret == -1) { 27052 VERROR_INT("xmlSchemaVReaderWalk", 27053 "calling xmlTextReaderMoveToFirstAttribute()"); 27054 goto internal_error; 27055 } 27056 } while (ret == 1); 27057 /* 27058 * Back to element position. 27059 */ 27060 ret = xmlTextReaderMoveToElement(vctxt->reader); 27061 if (ret == -1) { 27062 VERROR_INT("xmlSchemaVReaderWalk", 27063 "calling xmlTextReaderMoveToElement()"); 27064 goto internal_error; 27065 } 27066 } 27067 /* 27068 * Validate the element. 27069 */ 27070 ret= xmlSchemaValidateElem(vctxt); 27071 if (ret != 0) { 27072 if (ret == -1) { 27073 VERROR_INT("xmlSchemaVReaderWalk", 27074 "calling xmlSchemaValidateElem()"); 27075 goto internal_error; 27076 } 27077 goto exit; 27078 } 27079 if (vctxt->depth == vctxt->skipDepth) { 27080 int curDepth; 27081 /* 27082 * Skip all content. 27083 */ 27084 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27085 ret = xmlTextReaderRead(vctxt->reader); 27086 curDepth = xmlTextReaderDepth(vctxt->reader); 27087 while ((ret == 1) && (curDepth != depth)) { 27088 ret = xmlTextReaderRead(vctxt->reader); 27089 curDepth = xmlTextReaderDepth(vctxt->reader); 27090 } 27091 if (ret < 0) { 27092 /* 27093 * VAL TODO: A reader error occured; what to do here? 27094 */ 27095 ret = 1; 27096 goto exit; 27097 } 27098 } 27099 goto leave_elem; 27100 } 27101 /* 27102 * READER VAL TODO: Is an END_ELEM really never called 27103 * if the elem is empty? 27104 */ 27105 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27106 goto leave_elem; 27107 } else if (nodeType == END_ELEM) { 27108 /* 27109 * Process END of element. 27110 */ 27111 leave_elem: 27112 ret = xmlSchemaValidatorPopElem(vctxt); 27113 if (ret != 0) { 27114 if (ret < 0) { 27115 VERROR_INT("xmlSchemaVReaderWalk", 27116 "calling xmlSchemaValidatorPopElem()"); 27117 goto internal_error; 27118 } 27119 goto exit; 27120 } 27121 if (vctxt->depth >= 0) 27122 ielem = vctxt->inode; 27123 else 27124 ielem = NULL; 27125 } else if ((nodeType == XML_TEXT_NODE) || 27126 (nodeType == XML_CDATA_SECTION_NODE) || 27127 (nodeType == WHTSP) || 27128 (nodeType == SIGN_WHTSP)) { 27129 /* 27130 * Process character content. 27131 */ 27132 xmlChar *value; 27133 27134 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27135 nodeType = XML_TEXT_NODE; 27136 27137 value = xmlTextReaderValue(vctxt->reader); 27138 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27139 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27140 if (! consumed) 27141 xmlFree(value); 27142 if (ret == -1) { 27143 VERROR_INT("xmlSchemaVReaderWalk", 27144 "calling xmlSchemaVPushText()"); 27145 goto internal_error; 27146 } 27147 } else if ((nodeType == XML_ENTITY_NODE) || 27148 (nodeType == XML_ENTITY_REF_NODE)) { 27149 /* 27150 * VAL TODO: What to do with entities? 27151 */ 27152 TODO 27153 } 27154 /* 27155 * Read next node. 27156 */ 27157 ret = xmlTextReaderRead(vctxt->reader); 27158 } while (ret == 1); 27159 27160 exit: 27161 return (ret); 27162 internal_error: 27163 return (-1); 27164 } 27165 #endif 27166 27167 /************************************************************************ 27168 * * 27169 * SAX validation handlers * 27170 * * 27171 ************************************************************************/ 27172 27173 /* 27174 * Process text content. 27175 */ 27176 static void 27177 xmlSchemaSAXHandleText(void *ctx, 27178 const xmlChar * ch, 27179 int len) 27180 { 27181 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27182 27183 if (vctxt->depth < 0) 27184 return; 27185 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27186 return; 27187 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27188 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27189 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27190 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27191 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27192 "calling xmlSchemaVPushText()"); 27193 vctxt->err = -1; 27194 xmlStopParser(vctxt->parserCtxt); 27195 } 27196 } 27197 27198 /* 27199 * Process CDATA content. 27200 */ 27201 static void 27202 xmlSchemaSAXHandleCDataSection(void *ctx, 27203 const xmlChar * ch, 27204 int len) 27205 { 27206 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27207 27208 if (vctxt->depth < 0) 27209 return; 27210 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27211 return; 27212 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27213 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27214 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27215 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27216 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27217 "calling xmlSchemaVPushText()"); 27218 vctxt->err = -1; 27219 xmlStopParser(vctxt->parserCtxt); 27220 } 27221 } 27222 27223 static void 27224 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27225 const xmlChar * name ATTRIBUTE_UNUSED) 27226 { 27227 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27228 27229 if (vctxt->depth < 0) 27230 return; 27231 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27232 return; 27233 /* SAX VAL TODO: What to do here? */ 27234 TODO 27235 } 27236 27237 static void 27238 xmlSchemaSAXHandleStartElementNs(void *ctx, 27239 const xmlChar * localname, 27240 const xmlChar * prefix ATTRIBUTE_UNUSED, 27241 const xmlChar * URI, 27242 int nb_namespaces, 27243 const xmlChar ** namespaces, 27244 int nb_attributes, 27245 int nb_defaulted ATTRIBUTE_UNUSED, 27246 const xmlChar ** attributes) 27247 { 27248 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27249 int ret; 27250 xmlSchemaNodeInfoPtr ielem; 27251 int i, j; 27252 27253 /* 27254 * SAX VAL TODO: What to do with nb_defaulted? 27255 */ 27256 /* 27257 * Skip elements if inside a "skip" wildcard or invalid. 27258 */ 27259 vctxt->depth++; 27260 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27261 return; 27262 /* 27263 * Push the element. 27264 */ 27265 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27266 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27267 "calling xmlSchemaValidatorPushElem()"); 27268 goto internal_error; 27269 } 27270 ielem = vctxt->inode; 27271 /* 27272 * TODO: Is this OK? 27273 */ 27274 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27275 ielem->localName = localname; 27276 ielem->nsName = URI; 27277 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27278 /* 27279 * Register namespaces on the elem info. 27280 */ 27281 if (nb_namespaces != 0) { 27282 /* 27283 * Although the parser builds its own namespace list, 27284 * we have no access to it, so we'll use an own one. 27285 */ 27286 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27287 /* 27288 * Store prefix and namespace name. 27289 */ 27290 if (ielem->nsBindings == NULL) { 27291 ielem->nsBindings = 27292 (const xmlChar **) xmlMalloc(10 * 27293 sizeof(const xmlChar *)); 27294 if (ielem->nsBindings == NULL) { 27295 xmlSchemaVErrMemory(vctxt, 27296 "allocating namespace bindings for SAX validation", 27297 NULL); 27298 goto internal_error; 27299 } 27300 ielem->nbNsBindings = 0; 27301 ielem->sizeNsBindings = 5; 27302 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27303 ielem->sizeNsBindings *= 2; 27304 ielem->nsBindings = 27305 (const xmlChar **) xmlRealloc( 27306 (void *) ielem->nsBindings, 27307 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27308 if (ielem->nsBindings == NULL) { 27309 xmlSchemaVErrMemory(vctxt, 27310 "re-allocating namespace bindings for SAX validation", 27311 NULL); 27312 goto internal_error; 27313 } 27314 } 27315 27316 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27317 if (namespaces[j+1][0] == 0) { 27318 /* 27319 * Handle xmlns="". 27320 */ 27321 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27322 } else 27323 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27324 namespaces[j+1]; 27325 ielem->nbNsBindings++; 27326 } 27327 } 27328 /* 27329 * Register attributes. 27330 * SAX VAL TODO: We are not adding namespace declaration 27331 * attributes yet. 27332 */ 27333 if (nb_attributes != 0) { 27334 xmlChar *value; 27335 27336 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27337 /* 27338 * Duplicate the value. 27339 */ 27340 value = xmlStrndup(attributes[j+3], 27341 attributes[j+4] - attributes[j+3]); 27342 /* 27343 * TODO: Set the node line. 27344 */ 27345 ret = xmlSchemaValidatorPushAttribute(vctxt, 27346 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27347 value, 1); 27348 if (ret == -1) { 27349 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27350 "calling xmlSchemaValidatorPushAttribute()"); 27351 goto internal_error; 27352 } 27353 } 27354 } 27355 /* 27356 * Validate the element. 27357 */ 27358 ret = xmlSchemaValidateElem(vctxt); 27359 if (ret != 0) { 27360 if (ret == -1) { 27361 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27362 "calling xmlSchemaValidateElem()"); 27363 goto internal_error; 27364 } 27365 goto exit; 27366 } 27367 27368 exit: 27369 return; 27370 internal_error: 27371 vctxt->err = -1; 27372 xmlStopParser(vctxt->parserCtxt); 27373 return; 27374 } 27375 27376 static void 27377 xmlSchemaSAXHandleEndElementNs(void *ctx, 27378 const xmlChar * localname ATTRIBUTE_UNUSED, 27379 const xmlChar * prefix ATTRIBUTE_UNUSED, 27380 const xmlChar * URI ATTRIBUTE_UNUSED) 27381 { 27382 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27383 int res; 27384 27385 /* 27386 * Skip elements if inside a "skip" wildcard or if invalid. 27387 */ 27388 if (vctxt->skipDepth != -1) { 27389 if (vctxt->depth > vctxt->skipDepth) { 27390 vctxt->depth--; 27391 return; 27392 } else 27393 vctxt->skipDepth = -1; 27394 } 27395 /* 27396 * SAX VAL TODO: Just a temporary check. 27397 */ 27398 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27399 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27400 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27401 "elem pop mismatch"); 27402 } 27403 res = xmlSchemaValidatorPopElem(vctxt); 27404 if (res != 0) { 27405 if (res < 0) { 27406 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27407 "calling xmlSchemaValidatorPopElem()"); 27408 goto internal_error; 27409 } 27410 goto exit; 27411 } 27412 exit: 27413 return; 27414 internal_error: 27415 vctxt->err = -1; 27416 xmlStopParser(vctxt->parserCtxt); 27417 return; 27418 } 27419 27420 /************************************************************************ 27421 * * 27422 * Validation interfaces * 27423 * * 27424 ************************************************************************/ 27425 27426 /** 27427 * xmlSchemaNewValidCtxt: 27428 * @schema: a precompiled XML Schemas 27429 * 27430 * Create an XML Schemas validation context based on the given schema. 27431 * 27432 * Returns the validation context or NULL in case of error 27433 */ 27434 xmlSchemaValidCtxtPtr 27435 xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27436 { 27437 xmlSchemaValidCtxtPtr ret; 27438 27439 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27440 if (ret == NULL) { 27441 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27442 return (NULL); 27443 } 27444 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27445 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27446 ret->dict = xmlDictCreate(); 27447 ret->nodeQNames = xmlSchemaItemListCreate(); 27448 ret->schema = schema; 27449 return (ret); 27450 } 27451 27452 /** 27453 * xmlSchemaClearValidCtxt: 27454 * @ctxt: the schema validation context 27455 * 27456 * Free the resources associated to the schema validation context; 27457 * leaves some fields alive intended for reuse of the context. 27458 */ 27459 static void 27460 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27461 { 27462 if (vctxt == NULL) 27463 return; 27464 27465 /* 27466 * TODO: Should we clear the flags? 27467 * Might be problematic if one reuses the context 27468 * and assumes that the options remain the same. 27469 */ 27470 vctxt->flags = 0; 27471 vctxt->validationRoot = NULL; 27472 vctxt->doc = NULL; 27473 #ifdef LIBXML_READER_ENABLED 27474 vctxt->reader = NULL; 27475 #endif 27476 vctxt->hasKeyrefs = 0; 27477 27478 if (vctxt->value != NULL) { 27479 xmlSchemaFreeValue(vctxt->value); 27480 vctxt->value = NULL; 27481 } 27482 /* 27483 * Augmented IDC information. 27484 */ 27485 if (vctxt->aidcs != NULL) { 27486 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27487 do { 27488 next = cur->next; 27489 xmlFree(cur); 27490 cur = next; 27491 } while (cur != NULL); 27492 vctxt->aidcs = NULL; 27493 } 27494 if (vctxt->idcMatcherCache != NULL) { 27495 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27496 27497 while (matcher) { 27498 tmp = matcher; 27499 matcher = matcher->nextCached; 27500 xmlSchemaIDCFreeMatcherList(tmp); 27501 } 27502 vctxt->idcMatcherCache = NULL; 27503 } 27504 27505 27506 if (vctxt->idcNodes != NULL) { 27507 int i; 27508 xmlSchemaPSVIIDCNodePtr item; 27509 27510 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27511 item = vctxt->idcNodes[i]; 27512 xmlFree(item->keys); 27513 xmlFree(item); 27514 } 27515 xmlFree(vctxt->idcNodes); 27516 vctxt->idcNodes = NULL; 27517 vctxt->nbIdcNodes = 0; 27518 vctxt->sizeIdcNodes = 0; 27519 } 27520 /* 27521 * Note that we won't delete the XPath state pool here. 27522 */ 27523 if (vctxt->xpathStates != NULL) { 27524 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27525 vctxt->xpathStates = NULL; 27526 } 27527 /* 27528 * Attribute info. 27529 */ 27530 if (vctxt->nbAttrInfos != 0) { 27531 xmlSchemaClearAttrInfos(vctxt); 27532 } 27533 /* 27534 * Element info. 27535 */ 27536 if (vctxt->elemInfos != NULL) { 27537 int i; 27538 xmlSchemaNodeInfoPtr ei; 27539 27540 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27541 ei = vctxt->elemInfos[i]; 27542 if (ei == NULL) 27543 break; 27544 xmlSchemaClearElemInfo(vctxt, ei); 27545 } 27546 } 27547 xmlSchemaItemListClear(vctxt->nodeQNames); 27548 /* Recreate the dict. */ 27549 xmlDictFree(vctxt->dict); 27550 /* 27551 * TODO: Is is save to recreate it? Do we have a scenario 27552 * where the user provides the dict? 27553 */ 27554 vctxt->dict = xmlDictCreate(); 27555 } 27556 27557 /** 27558 * xmlSchemaFreeValidCtxt: 27559 * @ctxt: the schema validation context 27560 * 27561 * Free the resources associated to the schema validation context 27562 */ 27563 void 27564 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27565 { 27566 if (ctxt == NULL) 27567 return; 27568 if (ctxt->value != NULL) 27569 xmlSchemaFreeValue(ctxt->value); 27570 if (ctxt->pctxt != NULL) 27571 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27572 if (ctxt->idcNodes != NULL) { 27573 int i; 27574 xmlSchemaPSVIIDCNodePtr item; 27575 27576 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27577 item = ctxt->idcNodes[i]; 27578 xmlFree(item->keys); 27579 xmlFree(item); 27580 } 27581 xmlFree(ctxt->idcNodes); 27582 } 27583 if (ctxt->idcKeys != NULL) { 27584 int i; 27585 for (i = 0; i < ctxt->nbIdcKeys; i++) 27586 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27587 xmlFree(ctxt->idcKeys); 27588 } 27589 27590 if (ctxt->xpathStates != NULL) { 27591 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27592 ctxt->xpathStates = NULL; 27593 } 27594 if (ctxt->xpathStatePool != NULL) { 27595 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27596 ctxt->xpathStatePool = NULL; 27597 } 27598 27599 /* 27600 * Augmented IDC information. 27601 */ 27602 if (ctxt->aidcs != NULL) { 27603 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27604 do { 27605 next = cur->next; 27606 xmlFree(cur); 27607 cur = next; 27608 } while (cur != NULL); 27609 } 27610 if (ctxt->attrInfos != NULL) { 27611 int i; 27612 xmlSchemaAttrInfoPtr attr; 27613 27614 /* Just a paranoid call to the cleanup. */ 27615 if (ctxt->nbAttrInfos != 0) 27616 xmlSchemaClearAttrInfos(ctxt); 27617 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27618 attr = ctxt->attrInfos[i]; 27619 xmlFree(attr); 27620 } 27621 xmlFree(ctxt->attrInfos); 27622 } 27623 if (ctxt->elemInfos != NULL) { 27624 int i; 27625 xmlSchemaNodeInfoPtr ei; 27626 27627 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27628 ei = ctxt->elemInfos[i]; 27629 if (ei == NULL) 27630 break; 27631 xmlSchemaClearElemInfo(ctxt, ei); 27632 xmlFree(ei); 27633 } 27634 xmlFree(ctxt->elemInfos); 27635 } 27636 if (ctxt->nodeQNames != NULL) 27637 xmlSchemaItemListFree(ctxt->nodeQNames); 27638 if (ctxt->dict != NULL) 27639 xmlDictFree(ctxt->dict); 27640 xmlFree(ctxt); 27641 } 27642 27643 /** 27644 * xmlSchemaIsValid: 27645 * @ctxt: the schema validation context 27646 * 27647 * Check if any error was detected during validation. 27648 * 27649 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27650 * of internal error. 27651 */ 27652 int 27653 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27654 { 27655 if (ctxt == NULL) 27656 return(-1); 27657 return(ctxt->err == 0); 27658 } 27659 27660 /** 27661 * xmlSchemaSetValidErrors: 27662 * @ctxt: a schema validation context 27663 * @err: the error function 27664 * @warn: the warning function 27665 * @ctx: the functions context 27666 * 27667 * Set the error and warning callback informations 27668 */ 27669 void 27670 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27671 xmlSchemaValidityErrorFunc err, 27672 xmlSchemaValidityWarningFunc warn, void *ctx) 27673 { 27674 if (ctxt == NULL) 27675 return; 27676 ctxt->error = err; 27677 ctxt->warning = warn; 27678 ctxt->errCtxt = ctx; 27679 if (ctxt->pctxt != NULL) 27680 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27681 } 27682 27683 /** 27684 * xmlSchemaSetValidStructuredErrors: 27685 * @ctxt: a schema validation context 27686 * @serror: the structured error function 27687 * @ctx: the functions context 27688 * 27689 * Set the structured error callback 27690 */ 27691 void 27692 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27693 xmlStructuredErrorFunc serror, void *ctx) 27694 { 27695 if (ctxt == NULL) 27696 return; 27697 ctxt->serror = serror; 27698 ctxt->error = NULL; 27699 ctxt->warning = NULL; 27700 ctxt->errCtxt = ctx; 27701 if (ctxt->pctxt != NULL) 27702 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27703 } 27704 27705 /** 27706 * xmlSchemaGetValidErrors: 27707 * @ctxt: a XML-Schema validation context 27708 * @err: the error function result 27709 * @warn: the warning function result 27710 * @ctx: the functions context result 27711 * 27712 * Get the error and warning callback informations 27713 * 27714 * Returns -1 in case of error and 0 otherwise 27715 */ 27716 int 27717 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27718 xmlSchemaValidityErrorFunc * err, 27719 xmlSchemaValidityWarningFunc * warn, void **ctx) 27720 { 27721 if (ctxt == NULL) 27722 return (-1); 27723 if (err != NULL) 27724 *err = ctxt->error; 27725 if (warn != NULL) 27726 *warn = ctxt->warning; 27727 if (ctx != NULL) 27728 *ctx = ctxt->errCtxt; 27729 return (0); 27730 } 27731 27732 27733 /** 27734 * xmlSchemaSetValidOptions: 27735 * @ctxt: a schema validation context 27736 * @options: a combination of xmlSchemaValidOption 27737 * 27738 * Sets the options to be used during the validation. 27739 * 27740 * Returns 0 in case of success, -1 in case of an 27741 * API error. 27742 */ 27743 int 27744 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27745 int options) 27746 27747 { 27748 int i; 27749 27750 if (ctxt == NULL) 27751 return (-1); 27752 /* 27753 * WARNING: Change the start value if adding to the 27754 * xmlSchemaValidOption. 27755 * TODO: Is there an other, more easy to maintain, 27756 * way? 27757 */ 27758 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27759 if (options & 1<<i) 27760 return (-1); 27761 } 27762 ctxt->options = options; 27763 return (0); 27764 } 27765 27766 /** 27767 * xmlSchemaValidCtxtGetOptions: 27768 * @ctxt: a schema validation context 27769 * 27770 * Get the validation context options. 27771 * 27772 * Returns the option combination or -1 on error. 27773 */ 27774 int 27775 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27776 27777 { 27778 if (ctxt == NULL) 27779 return (-1); 27780 else 27781 return (ctxt->options); 27782 } 27783 27784 static int 27785 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27786 { 27787 xmlAttrPtr attr; 27788 int ret = 0; 27789 xmlSchemaNodeInfoPtr ielem = NULL; 27790 xmlNodePtr node, valRoot; 27791 const xmlChar *nsName; 27792 27793 /* DOC VAL TODO: Move this to the start function. */ 27794 valRoot = xmlDocGetRootElement(vctxt->doc); 27795 if (valRoot == NULL) { 27796 /* VAL TODO: Error code? */ 27797 VERROR(1, NULL, "The document has no document element"); 27798 return (1); 27799 } 27800 vctxt->depth = -1; 27801 vctxt->validationRoot = valRoot; 27802 node = valRoot; 27803 while (node != NULL) { 27804 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27805 goto next_sibling; 27806 if (node->type == XML_ELEMENT_NODE) { 27807 27808 /* 27809 * Init the node-info. 27810 */ 27811 vctxt->depth++; 27812 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27813 goto internal_error; 27814 ielem = vctxt->inode; 27815 ielem->node = node; 27816 ielem->nodeLine = node->line; 27817 ielem->localName = node->name; 27818 if (node->ns != NULL) 27819 ielem->nsName = node->ns->href; 27820 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27821 /* 27822 * Register attributes. 27823 * DOC VAL TODO: We do not register namespace declaration 27824 * attributes yet. 27825 */ 27826 vctxt->nbAttrInfos = 0; 27827 if (node->properties != NULL) { 27828 attr = node->properties; 27829 do { 27830 if (attr->ns != NULL) 27831 nsName = attr->ns->href; 27832 else 27833 nsName = NULL; 27834 ret = xmlSchemaValidatorPushAttribute(vctxt, 27835 (xmlNodePtr) attr, 27836 /* 27837 * Note that we give it the line number of the 27838 * parent element. 27839 */ 27840 ielem->nodeLine, 27841 attr->name, nsName, 0, 27842 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27843 if (ret == -1) { 27844 VERROR_INT("xmlSchemaDocWalk", 27845 "calling xmlSchemaValidatorPushAttribute()"); 27846 goto internal_error; 27847 } 27848 attr = attr->next; 27849 } while (attr); 27850 } 27851 /* 27852 * Validate the element. 27853 */ 27854 ret = xmlSchemaValidateElem(vctxt); 27855 if (ret != 0) { 27856 if (ret == -1) { 27857 VERROR_INT("xmlSchemaDocWalk", 27858 "calling xmlSchemaValidateElem()"); 27859 goto internal_error; 27860 } 27861 /* 27862 * Don't stop validation; just skip the content 27863 * of this element. 27864 */ 27865 goto leave_node; 27866 } 27867 if ((vctxt->skipDepth != -1) && 27868 (vctxt->depth >= vctxt->skipDepth)) 27869 goto leave_node; 27870 } else if ((node->type == XML_TEXT_NODE) || 27871 (node->type == XML_CDATA_SECTION_NODE)) { 27872 /* 27873 * Process character content. 27874 */ 27875 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 27876 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27877 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 27878 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 27879 if (ret < 0) { 27880 VERROR_INT("xmlSchemaVDocWalk", 27881 "calling xmlSchemaVPushText()"); 27882 goto internal_error; 27883 } 27884 /* 27885 * DOC VAL TODO: Should we skip further validation of the 27886 * element content here? 27887 */ 27888 } else if ((node->type == XML_ENTITY_NODE) || 27889 (node->type == XML_ENTITY_REF_NODE)) { 27890 /* 27891 * DOC VAL TODO: What to do with entities? 27892 */ 27893 VERROR_INT("xmlSchemaVDocWalk", 27894 "there is at least one entity reference in the node-tree " 27895 "currently being validated. Processing of entities with " 27896 "this XML Schema processor is not supported (yet). Please " 27897 "substitute entities before validation."); 27898 goto internal_error; 27899 } else { 27900 goto leave_node; 27901 /* 27902 * DOC VAL TODO: XInclude nodes, etc. 27903 */ 27904 } 27905 /* 27906 * Walk the doc. 27907 */ 27908 if (node->children != NULL) { 27909 node = node->children; 27910 continue; 27911 } 27912 leave_node: 27913 if (node->type == XML_ELEMENT_NODE) { 27914 /* 27915 * Leaving the scope of an element. 27916 */ 27917 if (node != vctxt->inode->node) { 27918 VERROR_INT("xmlSchemaVDocWalk", 27919 "element position mismatch"); 27920 goto internal_error; 27921 } 27922 ret = xmlSchemaValidatorPopElem(vctxt); 27923 if (ret != 0) { 27924 if (ret < 0) { 27925 VERROR_INT("xmlSchemaVDocWalk", 27926 "calling xmlSchemaValidatorPopElem()"); 27927 goto internal_error; 27928 } 27929 } 27930 if (node == valRoot) 27931 goto exit; 27932 } 27933 next_sibling: 27934 if (node->next != NULL) 27935 node = node->next; 27936 else { 27937 node = node->parent; 27938 goto leave_node; 27939 } 27940 } 27941 27942 exit: 27943 return (ret); 27944 internal_error: 27945 return (-1); 27946 } 27947 27948 static int 27949 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 27950 /* 27951 * Some initialization. 27952 */ 27953 vctxt->err = 0; 27954 vctxt->nberrors = 0; 27955 vctxt->depth = -1; 27956 vctxt->skipDepth = -1; 27957 vctxt->xsiAssemble = 0; 27958 vctxt->hasKeyrefs = 0; 27959 #ifdef ENABLE_IDC_NODE_TABLES_TEST 27960 vctxt->createIDCNodeTables = 1; 27961 #else 27962 vctxt->createIDCNodeTables = 0; 27963 #endif 27964 /* 27965 * Create a schema + parser if necessary. 27966 */ 27967 if (vctxt->schema == NULL) { 27968 xmlSchemaParserCtxtPtr pctxt; 27969 27970 vctxt->xsiAssemble = 1; 27971 /* 27972 * If not schema was given then we will create a schema 27973 * dynamically using XSI schema locations. 27974 * 27975 * Create the schema parser context. 27976 */ 27977 if ((vctxt->pctxt == NULL) && 27978 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 27979 return (-1); 27980 pctxt = vctxt->pctxt; 27981 pctxt->xsiAssemble = 1; 27982 /* 27983 * Create the schema. 27984 */ 27985 vctxt->schema = xmlSchemaNewSchema(pctxt); 27986 if (vctxt->schema == NULL) 27987 return (-1); 27988 /* 27989 * Create the schema construction context. 27990 */ 27991 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 27992 if (pctxt->constructor == NULL) 27993 return(-1); 27994 pctxt->constructor->mainSchema = vctxt->schema; 27995 /* 27996 * Take ownership of the constructor to be able to free it. 27997 */ 27998 pctxt->ownsConstructor = 1; 27999 } 28000 /* 28001 * Augment the IDC definitions for the main schema and all imported ones 28002 * NOTE: main schema if the first in the imported list 28003 */ 28004 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 28005 28006 return(0); 28007 } 28008 28009 static void 28010 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28011 if (vctxt->xsiAssemble) { 28012 if (vctxt->schema != NULL) { 28013 xmlSchemaFree(vctxt->schema); 28014 vctxt->schema = NULL; 28015 } 28016 } 28017 xmlSchemaClearValidCtxt(vctxt); 28018 } 28019 28020 static int 28021 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28022 { 28023 int ret = 0; 28024 28025 if (xmlSchemaPreRun(vctxt) < 0) 28026 return(-1); 28027 28028 if (vctxt->doc != NULL) { 28029 /* 28030 * Tree validation. 28031 */ 28032 ret = xmlSchemaVDocWalk(vctxt); 28033 #ifdef LIBXML_READER_ENABLED 28034 } else if (vctxt->reader != NULL) { 28035 /* 28036 * XML Reader validation. 28037 */ 28038 #ifdef XML_SCHEMA_READER_ENABLED 28039 ret = xmlSchemaVReaderWalk(vctxt); 28040 #endif 28041 #endif 28042 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28043 /* 28044 * SAX validation. 28045 */ 28046 ret = xmlParseDocument(vctxt->parserCtxt); 28047 } else { 28048 VERROR_INT("xmlSchemaVStart", 28049 "no instance to validate"); 28050 ret = -1; 28051 } 28052 28053 xmlSchemaPostRun(vctxt); 28054 if (ret == 0) 28055 ret = vctxt->err; 28056 return (ret); 28057 } 28058 28059 /** 28060 * xmlSchemaValidateOneElement: 28061 * @ctxt: a schema validation context 28062 * @elem: an element node 28063 * 28064 * Validate a branch of a tree, starting with the given @elem. 28065 * 28066 * Returns 0 if the element and its subtree is valid, a positive error 28067 * code number otherwise and -1 in case of an internal or API error. 28068 */ 28069 int 28070 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28071 { 28072 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28073 return (-1); 28074 28075 if (ctxt->schema == NULL) 28076 return (-1); 28077 28078 ctxt->doc = elem->doc; 28079 ctxt->node = elem; 28080 ctxt->validationRoot = elem; 28081 return(xmlSchemaVStart(ctxt)); 28082 } 28083 28084 /** 28085 * xmlSchemaValidateDoc: 28086 * @ctxt: a schema validation context 28087 * @doc: a parsed document tree 28088 * 28089 * Validate a document tree in memory. 28090 * 28091 * Returns 0 if the document is schemas valid, a positive error code 28092 * number otherwise and -1 in case of internal or API error. 28093 */ 28094 int 28095 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28096 { 28097 if ((ctxt == NULL) || (doc == NULL)) 28098 return (-1); 28099 28100 ctxt->doc = doc; 28101 ctxt->node = xmlDocGetRootElement(doc); 28102 if (ctxt->node == NULL) { 28103 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28104 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28105 (xmlNodePtr) doc, NULL, 28106 "The document has no document element", NULL, NULL); 28107 return (ctxt->err); 28108 } 28109 ctxt->validationRoot = ctxt->node; 28110 return (xmlSchemaVStart(ctxt)); 28111 } 28112 28113 28114 /************************************************************************ 28115 * * 28116 * Function and data for SAX streaming API * 28117 * * 28118 ************************************************************************/ 28119 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28120 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28121 28122 struct _xmlSchemaSplitSAXData { 28123 xmlSAXHandlerPtr user_sax; 28124 void *user_data; 28125 xmlSchemaValidCtxtPtr ctxt; 28126 xmlSAXHandlerPtr schemas_sax; 28127 }; 28128 28129 #define XML_SAX_PLUG_MAGIC 0xdc43ba21 28130 28131 struct _xmlSchemaSAXPlug { 28132 unsigned int magic; 28133 28134 /* the original callbacks informations */ 28135 xmlSAXHandlerPtr *user_sax_ptr; 28136 xmlSAXHandlerPtr user_sax; 28137 void **user_data_ptr; 28138 void *user_data; 28139 28140 /* the block plugged back and validation informations */ 28141 xmlSAXHandler schemas_sax; 28142 xmlSchemaValidCtxtPtr ctxt; 28143 }; 28144 28145 /* All those functions just bounces to the user provided SAX handlers */ 28146 static void 28147 internalSubsetSplit(void *ctx, const xmlChar *name, 28148 const xmlChar *ExternalID, const xmlChar *SystemID) 28149 { 28150 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28151 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28152 (ctxt->user_sax->internalSubset != NULL)) 28153 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28154 SystemID); 28155 } 28156 28157 static int 28158 isStandaloneSplit(void *ctx) 28159 { 28160 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28161 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28162 (ctxt->user_sax->isStandalone != NULL)) 28163 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28164 return(0); 28165 } 28166 28167 static int 28168 hasInternalSubsetSplit(void *ctx) 28169 { 28170 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28171 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28172 (ctxt->user_sax->hasInternalSubset != NULL)) 28173 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28174 return(0); 28175 } 28176 28177 static int 28178 hasExternalSubsetSplit(void *ctx) 28179 { 28180 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28181 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28182 (ctxt->user_sax->hasExternalSubset != NULL)) 28183 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28184 return(0); 28185 } 28186 28187 static void 28188 externalSubsetSplit(void *ctx, const xmlChar *name, 28189 const xmlChar *ExternalID, const xmlChar *SystemID) 28190 { 28191 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28192 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28193 (ctxt->user_sax->externalSubset != NULL)) 28194 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28195 SystemID); 28196 } 28197 28198 static xmlParserInputPtr 28199 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28200 { 28201 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28202 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28203 (ctxt->user_sax->resolveEntity != NULL)) 28204 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28205 systemId)); 28206 return(NULL); 28207 } 28208 28209 static xmlEntityPtr 28210 getEntitySplit(void *ctx, const xmlChar *name) 28211 { 28212 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28213 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28214 (ctxt->user_sax->getEntity != NULL)) 28215 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28216 return(NULL); 28217 } 28218 28219 static xmlEntityPtr 28220 getParameterEntitySplit(void *ctx, const xmlChar *name) 28221 { 28222 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28223 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28224 (ctxt->user_sax->getParameterEntity != NULL)) 28225 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28226 return(NULL); 28227 } 28228 28229 28230 static void 28231 entityDeclSplit(void *ctx, const xmlChar *name, int type, 28232 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28233 { 28234 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28235 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28236 (ctxt->user_sax->entityDecl != NULL)) 28237 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28238 systemId, content); 28239 } 28240 28241 static void 28242 attributeDeclSplit(void *ctx, const xmlChar * elem, 28243 const xmlChar * name, int type, int def, 28244 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28245 { 28246 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28247 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28248 (ctxt->user_sax->attributeDecl != NULL)) { 28249 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28250 def, defaultValue, tree); 28251 } else { 28252 xmlFreeEnumeration(tree); 28253 } 28254 } 28255 28256 static void 28257 elementDeclSplit(void *ctx, const xmlChar *name, int type, 28258 xmlElementContentPtr content) 28259 { 28260 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28261 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28262 (ctxt->user_sax->elementDecl != NULL)) 28263 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28264 } 28265 28266 static void 28267 notationDeclSplit(void *ctx, const xmlChar *name, 28268 const xmlChar *publicId, const xmlChar *systemId) 28269 { 28270 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28271 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28272 (ctxt->user_sax->notationDecl != NULL)) 28273 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28274 systemId); 28275 } 28276 28277 static void 28278 unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28279 const xmlChar *publicId, const xmlChar *systemId, 28280 const xmlChar *notationName) 28281 { 28282 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28283 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28284 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28285 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28286 systemId, notationName); 28287 } 28288 28289 static void 28290 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28291 { 28292 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28293 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28294 (ctxt->user_sax->setDocumentLocator != NULL)) 28295 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28296 } 28297 28298 static void 28299 startDocumentSplit(void *ctx) 28300 { 28301 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28302 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28303 (ctxt->user_sax->startDocument != NULL)) 28304 ctxt->user_sax->startDocument(ctxt->user_data); 28305 } 28306 28307 static void 28308 endDocumentSplit(void *ctx) 28309 { 28310 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28311 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28312 (ctxt->user_sax->endDocument != NULL)) 28313 ctxt->user_sax->endDocument(ctxt->user_data); 28314 } 28315 28316 static void 28317 processingInstructionSplit(void *ctx, const xmlChar *target, 28318 const xmlChar *data) 28319 { 28320 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28321 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28322 (ctxt->user_sax->processingInstruction != NULL)) 28323 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28324 } 28325 28326 static void 28327 commentSplit(void *ctx, const xmlChar *value) 28328 { 28329 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28330 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28331 (ctxt->user_sax->comment != NULL)) 28332 ctxt->user_sax->comment(ctxt->user_data, value); 28333 } 28334 28335 /* 28336 * Varargs error callbacks to the user application, harder ... 28337 */ 28338 28339 static void XMLCDECL 28340 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28341 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28342 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28343 (ctxt->user_sax->warning != NULL)) { 28344 TODO 28345 } 28346 } 28347 static void XMLCDECL 28348 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28349 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28350 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28351 (ctxt->user_sax->error != NULL)) { 28352 TODO 28353 } 28354 } 28355 static void XMLCDECL 28356 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28357 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28358 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28359 (ctxt->user_sax->fatalError != NULL)) { 28360 TODO 28361 } 28362 } 28363 28364 /* 28365 * Those are function where both the user handler and the schemas handler 28366 * need to be called. 28367 */ 28368 static void 28369 charactersSplit(void *ctx, const xmlChar *ch, int len) 28370 { 28371 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28372 if (ctxt == NULL) 28373 return; 28374 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28375 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28376 if (ctxt->ctxt != NULL) 28377 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28378 } 28379 28380 static void 28381 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28382 { 28383 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28384 if (ctxt == NULL) 28385 return; 28386 if ((ctxt->user_sax != NULL) && 28387 (ctxt->user_sax->ignorableWhitespace != NULL)) 28388 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28389 if (ctxt->ctxt != NULL) 28390 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28391 } 28392 28393 static void 28394 cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28395 { 28396 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28397 if (ctxt == NULL) 28398 return; 28399 if ((ctxt->user_sax != NULL) && 28400 (ctxt->user_sax->cdataBlock != NULL)) 28401 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28402 if (ctxt->ctxt != NULL) 28403 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28404 } 28405 28406 static void 28407 referenceSplit(void *ctx, const xmlChar *name) 28408 { 28409 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28410 if (ctxt == NULL) 28411 return; 28412 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28413 (ctxt->user_sax->reference != NULL)) 28414 ctxt->user_sax->reference(ctxt->user_data, name); 28415 if (ctxt->ctxt != NULL) 28416 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28417 } 28418 28419 static void 28420 startElementNsSplit(void *ctx, const xmlChar * localname, 28421 const xmlChar * prefix, const xmlChar * URI, 28422 int nb_namespaces, const xmlChar ** namespaces, 28423 int nb_attributes, int nb_defaulted, 28424 const xmlChar ** attributes) { 28425 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28426 if (ctxt == NULL) 28427 return; 28428 if ((ctxt->user_sax != NULL) && 28429 (ctxt->user_sax->startElementNs != NULL)) 28430 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28431 URI, nb_namespaces, namespaces, 28432 nb_attributes, nb_defaulted, 28433 attributes); 28434 if (ctxt->ctxt != NULL) 28435 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28436 URI, nb_namespaces, namespaces, 28437 nb_attributes, nb_defaulted, 28438 attributes); 28439 } 28440 28441 static void 28442 endElementNsSplit(void *ctx, const xmlChar * localname, 28443 const xmlChar * prefix, const xmlChar * URI) { 28444 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28445 if (ctxt == NULL) 28446 return; 28447 if ((ctxt->user_sax != NULL) && 28448 (ctxt->user_sax->endElementNs != NULL)) 28449 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28450 if (ctxt->ctxt != NULL) 28451 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28452 } 28453 28454 /** 28455 * xmlSchemaSAXPlug: 28456 * @ctxt: a schema validation context 28457 * @sax: a pointer to the original xmlSAXHandlerPtr 28458 * @user_data: a pointer to the original SAX user data pointer 28459 * 28460 * Plug a SAX based validation layer in a SAX parsing event flow. 28461 * The original @saxptr and @dataptr data are replaced by new pointers 28462 * but the calls to the original will be maintained. 28463 * 28464 * Returns a pointer to a data structure needed to unplug the validation layer 28465 * or NULL in case of errors. 28466 */ 28467 xmlSchemaSAXPlugPtr 28468 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28469 xmlSAXHandlerPtr *sax, void **user_data) 28470 { 28471 xmlSchemaSAXPlugPtr ret; 28472 xmlSAXHandlerPtr old_sax; 28473 28474 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28475 return(NULL); 28476 28477 /* 28478 * We only allow to plug into SAX2 event streams 28479 */ 28480 old_sax = *sax; 28481 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28482 return(NULL); 28483 if ((old_sax != NULL) && 28484 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28485 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28486 return(NULL); 28487 28488 /* 28489 * everything seems right allocate the local data needed for that layer 28490 */ 28491 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28492 if (ret == NULL) { 28493 return(NULL); 28494 } 28495 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28496 ret->magic = XML_SAX_PLUG_MAGIC; 28497 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28498 ret->ctxt = ctxt; 28499 ret->user_sax_ptr = sax; 28500 ret->user_sax = old_sax; 28501 if (old_sax == NULL) { 28502 /* 28503 * go direct, no need for the split block and functions. 28504 */ 28505 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28506 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28507 /* 28508 * Note that we use the same text-function for both, to prevent 28509 * the parser from testing for ignorable whitespace. 28510 */ 28511 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28512 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28513 28514 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28515 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28516 28517 ret->user_data = ctxt; 28518 *user_data = ctxt; 28519 } else { 28520 /* 28521 * for each callback unused by Schemas initialize it to the Split 28522 * routine only if non NULL in the user block, this can speed up 28523 * things at the SAX level. 28524 */ 28525 if (old_sax->internalSubset != NULL) 28526 ret->schemas_sax.internalSubset = internalSubsetSplit; 28527 if (old_sax->isStandalone != NULL) 28528 ret->schemas_sax.isStandalone = isStandaloneSplit; 28529 if (old_sax->hasInternalSubset != NULL) 28530 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28531 if (old_sax->hasExternalSubset != NULL) 28532 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28533 if (old_sax->resolveEntity != NULL) 28534 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28535 if (old_sax->getEntity != NULL) 28536 ret->schemas_sax.getEntity = getEntitySplit; 28537 if (old_sax->entityDecl != NULL) 28538 ret->schemas_sax.entityDecl = entityDeclSplit; 28539 if (old_sax->notationDecl != NULL) 28540 ret->schemas_sax.notationDecl = notationDeclSplit; 28541 if (old_sax->attributeDecl != NULL) 28542 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28543 if (old_sax->elementDecl != NULL) 28544 ret->schemas_sax.elementDecl = elementDeclSplit; 28545 if (old_sax->unparsedEntityDecl != NULL) 28546 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28547 if (old_sax->setDocumentLocator != NULL) 28548 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28549 if (old_sax->startDocument != NULL) 28550 ret->schemas_sax.startDocument = startDocumentSplit; 28551 if (old_sax->endDocument != NULL) 28552 ret->schemas_sax.endDocument = endDocumentSplit; 28553 if (old_sax->processingInstruction != NULL) 28554 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28555 if (old_sax->comment != NULL) 28556 ret->schemas_sax.comment = commentSplit; 28557 if (old_sax->warning != NULL) 28558 ret->schemas_sax.warning = warningSplit; 28559 if (old_sax->error != NULL) 28560 ret->schemas_sax.error = errorSplit; 28561 if (old_sax->fatalError != NULL) 28562 ret->schemas_sax.fatalError = fatalErrorSplit; 28563 if (old_sax->getParameterEntity != NULL) 28564 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28565 if (old_sax->externalSubset != NULL) 28566 ret->schemas_sax.externalSubset = externalSubsetSplit; 28567 28568 /* 28569 * the 6 schemas callback have to go to the splitter functions 28570 * Note that we use the same text-function for ignorableWhitespace 28571 * if possible, to prevent the parser from testing for ignorable 28572 * whitespace. 28573 */ 28574 ret->schemas_sax.characters = charactersSplit; 28575 if ((old_sax->ignorableWhitespace != NULL) && 28576 (old_sax->ignorableWhitespace != old_sax->characters)) 28577 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28578 else 28579 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28580 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28581 ret->schemas_sax.reference = referenceSplit; 28582 ret->schemas_sax.startElementNs = startElementNsSplit; 28583 ret->schemas_sax.endElementNs = endElementNsSplit; 28584 28585 ret->user_data_ptr = user_data; 28586 ret->user_data = *user_data; 28587 *user_data = ret; 28588 } 28589 28590 /* 28591 * plug the pointers back. 28592 */ 28593 *sax = &(ret->schemas_sax); 28594 ctxt->sax = *sax; 28595 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28596 xmlSchemaPreRun(ctxt); 28597 return(ret); 28598 } 28599 28600 /** 28601 * xmlSchemaSAXUnplug: 28602 * @plug: a data structure returned by xmlSchemaSAXPlug 28603 * 28604 * Unplug a SAX based validation layer in a SAX parsing event flow. 28605 * The original pointers used in the call are restored. 28606 * 28607 * Returns 0 in case of success and -1 in case of failure. 28608 */ 28609 int 28610 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28611 { 28612 xmlSAXHandlerPtr *sax; 28613 void **user_data; 28614 28615 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28616 return(-1); 28617 plug->magic = 0; 28618 28619 xmlSchemaPostRun(plug->ctxt); 28620 /* restore the data */ 28621 sax = plug->user_sax_ptr; 28622 *sax = plug->user_sax; 28623 if (plug->user_sax != NULL) { 28624 user_data = plug->user_data_ptr; 28625 *user_data = plug->user_data; 28626 } 28627 28628 /* free and return */ 28629 xmlFree(plug); 28630 return(0); 28631 } 28632 28633 /** 28634 * xmlSchemaValidateStream: 28635 * @ctxt: a schema validation context 28636 * @input: the input to use for reading the data 28637 * @enc: an optional encoding information 28638 * @sax: a SAX handler for the resulting events 28639 * @user_data: the context to provide to the SAX handler. 28640 * 28641 * Validate an input based on a flow of SAX event from the parser 28642 * and forward the events to the @sax handler with the provided @user_data 28643 * the user provided @sax handler must be a SAX2 one. 28644 * 28645 * Returns 0 if the document is schemas valid, a positive error code 28646 * number otherwise and -1 in case of internal or API error. 28647 */ 28648 int 28649 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28650 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28651 xmlSAXHandlerPtr sax, void *user_data) 28652 { 28653 xmlSchemaSAXPlugPtr plug = NULL; 28654 xmlSAXHandlerPtr old_sax = NULL; 28655 xmlParserCtxtPtr pctxt = NULL; 28656 xmlParserInputPtr inputStream = NULL; 28657 int ret; 28658 28659 if ((ctxt == NULL) || (input == NULL)) 28660 return (-1); 28661 28662 /* 28663 * prepare the parser 28664 */ 28665 pctxt = xmlNewParserCtxt(); 28666 if (pctxt == NULL) 28667 return (-1); 28668 old_sax = pctxt->sax; 28669 pctxt->sax = sax; 28670 pctxt->userData = user_data; 28671 #if 0 28672 if (options) 28673 xmlCtxtUseOptions(pctxt, options); 28674 #endif 28675 pctxt->linenumbers = 1; 28676 28677 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28678 if (inputStream == NULL) { 28679 ret = -1; 28680 goto done; 28681 } 28682 inputPush(pctxt, inputStream); 28683 ctxt->parserCtxt = pctxt; 28684 ctxt->input = input; 28685 28686 /* 28687 * Plug the validation and launch the parsing 28688 */ 28689 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28690 if (plug == NULL) { 28691 ret = -1; 28692 goto done; 28693 } 28694 ctxt->input = input; 28695 ctxt->enc = enc; 28696 ctxt->sax = pctxt->sax; 28697 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28698 ret = xmlSchemaVStart(ctxt); 28699 28700 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28701 ret = ctxt->parserCtxt->errNo; 28702 if (ret == 0) 28703 ret = 1; 28704 } 28705 28706 done: 28707 ctxt->parserCtxt = NULL; 28708 ctxt->sax = NULL; 28709 ctxt->input = NULL; 28710 if (plug != NULL) { 28711 xmlSchemaSAXUnplug(plug); 28712 } 28713 /* cleanup */ 28714 if (pctxt != NULL) { 28715 pctxt->sax = old_sax; 28716 xmlFreeParserCtxt(pctxt); 28717 } 28718 return (ret); 28719 } 28720 28721 /** 28722 * xmlSchemaValidateFile: 28723 * @ctxt: a schema validation context 28724 * @filename: the URI of the instance 28725 * @options: a future set of options, currently unused 28726 * 28727 * Do a schemas validation of the given resource, it will use the 28728 * SAX streamable validation internally. 28729 * 28730 * Returns 0 if the document is valid, a positive error code 28731 * number otherwise and -1 in case of an internal or API error. 28732 */ 28733 int 28734 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28735 const char * filename, 28736 int options ATTRIBUTE_UNUSED) 28737 { 28738 int ret; 28739 xmlParserInputBufferPtr input; 28740 28741 if ((ctxt == NULL) || (filename == NULL)) 28742 return (-1); 28743 28744 input = xmlParserInputBufferCreateFilename(filename, 28745 XML_CHAR_ENCODING_NONE); 28746 if (input == NULL) 28747 return (-1); 28748 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28749 NULL, NULL); 28750 return (ret); 28751 } 28752 28753 /** 28754 * xmlSchemaValidCtxtGetParserCtxt: 28755 * @ctxt: a schema validation context 28756 * 28757 * allow access to the parser context of the schema validation context 28758 * 28759 * Returns the parser context of the schema validation context or NULL 28760 * in case of error. 28761 */ 28762 xmlParserCtxtPtr 28763 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28764 { 28765 if (ctxt == NULL) 28766 return(NULL); 28767 return (ctxt->parserCtxt); 28768 } 28769 28770 #define bottom_xmlschemas 28771 #include "elfgcchack.h" 28772 #endif /* LIBXML_SCHEMAS_ENABLED */ 28773