1 /* 2 * schemas.c : implementation of the XML Schema handling and 3 * schema validity checking 4 * 5 * See Copyright for the status of this software. 6 * 7 * Daniel Veillard <veillard (at) redhat.com> 8 */ 9 10 /* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - if we don't intend to use the schema for schemas, we 16 * need to validate all schema attributes (ref, type, name) 17 * against their types. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 #define IN_LIBXML 48 #include "libxml.h" 49 50 #ifdef LIBXML_SCHEMAS_ENABLED 51 52 #include <string.h> 53 #include <libxml/xmlmemory.h> 54 #include <libxml/parser.h> 55 #include <libxml/parserInternals.h> 56 #include <libxml/hash.h> 57 #include <libxml/uri.h> 58 #include <libxml/xmlschemas.h> 59 #include <libxml/schemasInternals.h> 60 #include <libxml/xmlschemastypes.h> 61 #include <libxml/xmlautomata.h> 62 #include <libxml/xmlregexp.h> 63 #include <libxml/dict.h> 64 #include <libxml/encoding.h> 65 #include <libxml/xmlIO.h> 66 #ifdef LIBXML_PATTERN_ENABLED 67 #include <libxml/pattern.h> 68 #endif 69 #ifdef LIBXML_READER_ENABLED 70 #include <libxml/xmlreader.h> 71 #endif 72 73 /* #define DEBUG 1 */ 74 75 /* #define DEBUG_CONTENT 1 */ 76 77 /* #define DEBUG_TYPE 1 */ 78 79 /* #define DEBUG_CONTENT_REGEXP 1 */ 80 81 /* #define DEBUG_AUTOMATA 1 */ 82 83 /* #define DEBUG_IDC */ 84 85 /* #define DEBUG_IDC_NODE_TABLE */ 86 87 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 88 89 #ifdef DEBUG_IDC 90 #ifndef DEBUG_IDC_NODE_TABLE 91 #define DEBUG_IDC_NODE_TABLE 92 #endif 93 #endif 94 95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 96 97 #define ENABLE_REDEFINE 98 99 /* #define ENABLE_NAMED_LOCALS */ 100 101 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 102 103 #define DUMP_CONTENT_MODEL 104 105 #ifdef LIBXML_READER_ENABLED 106 /* #define XML_SCHEMA_READER_ENABLED */ 107 #endif 108 109 #define UNBOUNDED (1 << 30) 110 #define TODO \ 111 xmlGenericError(xmlGenericErrorContext, \ 112 "Unimplemented block at %s:%d\n", \ 113 __FILE__, __LINE__); 114 115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 116 117 /* 118 * The XML Schemas namespaces 119 */ 120 static const xmlChar *xmlSchemaNs = (const xmlChar *) 121 "http://www.w3.org/2001/XMLSchema"; 122 123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 124 "http://www.w3.org/2001/XMLSchema-instance"; 125 126 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 127 "http://www.w3.org/2000/xmlns/"; 128 129 /* 130 * Come casting macros. 131 */ 132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 137 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 138 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 139 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 146 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 148 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 149 150 /* 151 * Macros to query common properties of components. 152 */ 153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 154 155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 156 /* 157 * Macros for element declarations. 158 */ 159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 160 161 #define WXS_SUBST_HEAD(item) (item)->refDecl 162 /* 163 * Macros for attribute declarations. 164 */ 165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 166 /* 167 * Macros for attribute uses. 168 */ 169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 170 171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 172 173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 174 175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 176 /* 177 * Macros for attribute groups. 178 */ 179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 181 /* 182 * Macros for particles. 183 */ 184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 185 186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 187 188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 189 190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 191 /* 192 * Macros for model groups definitions. 193 */ 194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 195 /* 196 * Macros for model groups. 197 */ 198 #define WXS_IS_MODEL_GROUP(i) \ 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 202 203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 204 /* 205 * Macros for schema buckets. 206 */ 207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 209 210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 212 213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 214 215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 216 /* 217 * Macros for complex/simple types. 218 */ 219 #define WXS_IS_ANYTYPE(i) \ 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 222 223 #define WXS_IS_COMPLEX(i) \ 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 226 227 #define WXS_IS_SIMPLE(item) \ 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 231 232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 235 236 #define WXS_IS_RESTRICTION(t) \ 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 238 239 #define WXS_IS_EXTENSION(t) \ 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 241 242 #define WXS_IS_TYPE_NOT_FIXED(i) \ 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 245 246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 249 250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 251 252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 253 /* 254 * Macros for exclusively for complex types. 255 */ 256 #define WXS_HAS_COMPLEX_CONTENT(item) \ 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 260 261 #define WXS_HAS_SIMPLE_CONTENT(item) \ 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 264 265 #define WXS_HAS_MIXED_CONTENT(item) \ 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 267 268 #define WXS_EMPTIABLE(t) \ 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 270 271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 272 273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 274 275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 276 /* 277 * Macros for exclusively for simple types. 278 */ 279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 280 281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 282 283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 284 285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 286 /* 287 * Misc parser context macros. 288 */ 289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 290 291 #define WXS_HAS_BUCKETS(ctx) \ 292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 294 295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 296 297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 298 299 #define WXS_SCHEMA(ctx) (ctx)->schema 300 301 #define WXS_ADD_LOCAL(ctx, item) \ 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 303 304 #define WXS_ADD_GLOBAL(ctx, item) \ 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 306 307 #define WXS_ADD_PENDING(ctx, item) \ 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 309 /* 310 * xmlSchemaItemList macros. 311 */ 312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 313 /* 314 * Misc macros. 315 */ 316 #define IS_SCHEMA(node, type) \ 317 ((node != NULL) && (node->ns != NULL) && \ 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 320 321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 322 323 /* 324 * Since we put the default/fixed values into the dict, we can 325 * use pointer comparison for those values. 326 * REMOVED: (xmlStrEqual((v1), (v2))) 327 */ 328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 329 330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 331 332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 333 334 #define HFAILURE if (res == -1) goto exit_failure; 335 336 #define HERROR if (res != 0) goto exit_error; 337 338 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 339 /* 340 * Some flags used for various schema constraints. 341 */ 342 #define SUBSET_RESTRICTION 1<<0 343 #define SUBSET_EXTENSION 1<<1 344 #define SUBSET_SUBSTITUTION 1<<2 345 #define SUBSET_LIST 1<<3 346 #define SUBSET_UNION 1<<4 347 348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 350 351 typedef struct _xmlSchemaItemList xmlSchemaItemList; 352 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 353 struct _xmlSchemaItemList { 354 void **items; /* used for dynamic addition of schemata */ 355 int nbItems; /* used for dynamic addition of schemata */ 356 int sizeItems; /* used for dynamic addition of schemata */ 357 }; 358 359 #define XML_SCHEMA_CTXT_PARSER 1 360 #define XML_SCHEMA_CTXT_VALIDATOR 2 361 362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 364 struct _xmlSchemaAbstractCtxt { 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 366 }; 367 368 typedef struct _xmlSchemaBucket xmlSchemaBucket; 369 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 370 371 #define XML_SCHEMA_SCHEMA_MAIN 0 372 #define XML_SCHEMA_SCHEMA_IMPORT 1 373 #define XML_SCHEMA_SCHEMA_INCLUDE 2 374 #define XML_SCHEMA_SCHEMA_REDEFINE 3 375 376 /** 377 * xmlSchemaSchemaRelation: 378 * 379 * Used to create a graph of schema relationships. 380 */ 381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 383 struct _xmlSchemaSchemaRelation { 384 xmlSchemaSchemaRelationPtr next; 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 386 const xmlChar *importNamespace; 387 xmlSchemaBucketPtr bucket; 388 }; 389 390 #define XML_SCHEMA_BUCKET_MARKED 1<<0 391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 392 393 struct _xmlSchemaBucket { 394 int type; 395 int flags; 396 const xmlChar *schemaLocation; 397 const xmlChar *origTargetNamespace; 398 const xmlChar *targetNamespace; 399 xmlDocPtr doc; 400 xmlSchemaSchemaRelationPtr relations; 401 int located; 402 int parsed; 403 int imported; 404 int preserveDoc; 405 xmlSchemaItemListPtr globals; /* Global components. */ 406 xmlSchemaItemListPtr locals; /* Local components. */ 407 }; 408 409 /** 410 * xmlSchemaImport: 411 * (extends xmlSchemaBucket) 412 * 413 * Reflects a schema. Holds some information 414 * about the schema and its toplevel components. Duplicate 415 * toplevel components are not checked at this level. 416 */ 417 typedef struct _xmlSchemaImport xmlSchemaImport; 418 typedef xmlSchemaImport *xmlSchemaImportPtr; 419 struct _xmlSchemaImport { 420 int type; /* Main OR import OR include. */ 421 int flags; 422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 423 /* For chameleon includes, @origTargetNamespace will be NULL */ 424 const xmlChar *origTargetNamespace; 425 /* 426 * For chameleon includes, @targetNamespace will be the 427 * targetNamespace of the including schema. 428 */ 429 const xmlChar *targetNamespace; 430 xmlDocPtr doc; /* The schema node-tree. */ 431 /* @relations will hold any included/imported/redefined schemas. */ 432 xmlSchemaSchemaRelationPtr relations; 433 int located; 434 int parsed; 435 int imported; 436 int preserveDoc; 437 xmlSchemaItemListPtr globals; 438 xmlSchemaItemListPtr locals; 439 /* The imported schema. */ 440 xmlSchemaPtr schema; 441 }; 442 443 /* 444 * (extends xmlSchemaBucket) 445 */ 446 typedef struct _xmlSchemaInclude xmlSchemaInclude; 447 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 448 struct _xmlSchemaInclude { 449 int type; 450 int flags; 451 const xmlChar *schemaLocation; 452 const xmlChar *origTargetNamespace; 453 const xmlChar *targetNamespace; 454 xmlDocPtr doc; 455 xmlSchemaSchemaRelationPtr relations; 456 int located; 457 int parsed; 458 int imported; 459 int preserveDoc; 460 xmlSchemaItemListPtr globals; /* Global components. */ 461 xmlSchemaItemListPtr locals; /* Local components. */ 462 463 /* The owning main or import schema bucket. */ 464 xmlSchemaImportPtr ownerImport; 465 }; 466 467 /** 468 * xmlSchemaBasicItem: 469 * 470 * The abstract base type for schema components. 471 */ 472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 474 struct _xmlSchemaBasicItem { 475 xmlSchemaTypeType type; 476 }; 477 478 /** 479 * xmlSchemaAnnotItem: 480 * 481 * The abstract base type for annotated schema components. 482 * (Extends xmlSchemaBasicItem) 483 */ 484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 486 struct _xmlSchemaAnnotItem { 487 xmlSchemaTypeType type; 488 xmlSchemaAnnotPtr annot; 489 }; 490 491 /** 492 * xmlSchemaTreeItem: 493 * 494 * The abstract base type for tree-like structured schema components. 495 * (Extends xmlSchemaAnnotItem) 496 */ 497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 499 struct _xmlSchemaTreeItem { 500 xmlSchemaTypeType type; 501 xmlSchemaAnnotPtr annot; 502 xmlSchemaTreeItemPtr next; 503 xmlSchemaTreeItemPtr children; 504 }; 505 506 507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 508 /** 509 * xmlSchemaAttributeUsePtr: 510 * 511 * The abstract base type for tree-like structured schema components. 512 * (Extends xmlSchemaTreeItem) 513 */ 514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 516 struct _xmlSchemaAttributeUse { 517 xmlSchemaTypeType type; 518 xmlSchemaAnnotPtr annot; 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 520 /* 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 522 * a QName-ref. to an attribute group definition. 523 */ 524 xmlSchemaAttributePtr attrDecl; 525 526 int flags; 527 xmlNodePtr node; 528 int occurs; /* required, optional */ 529 const xmlChar * defValue; 530 xmlSchemaValPtr defVal; 531 }; 532 533 /** 534 * xmlSchemaAttributeUseProhibPtr: 535 * 536 * A helper component to reflect attribute prohibitions. 537 * (Extends xmlSchemaBasicItem) 538 */ 539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 541 struct _xmlSchemaAttributeUseProhib { 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 543 xmlNodePtr node; 544 const xmlChar *name; 545 const xmlChar *targetNamespace; 546 int isRef; 547 }; 548 549 /** 550 * xmlSchemaRedef: 551 */ 552 typedef struct _xmlSchemaRedef xmlSchemaRedef; 553 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 554 struct _xmlSchemaRedef { 555 xmlSchemaRedefPtr next; 556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 560 const xmlChar *refTargetNs; /* The target namespace of the 561 to-be-redefined comp. */ 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 563 }; 564 565 /** 566 * xmlSchemaConstructionCtxt: 567 */ 568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 570 struct _xmlSchemaConstructionCtxt { 571 xmlSchemaPtr mainSchema; /* The main schema. */ 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 573 xmlDictPtr dict; 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 578 need to be fixed. */ 579 xmlHashTablePtr substGroups; 580 xmlSchemaRedefPtr redefs; 581 xmlSchemaRedefPtr lastRedef; 582 }; 583 584 #define XML_SCHEMAS_PARSE_ERROR 1 585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 586 587 struct _xmlSchemaParserCtxt { 588 int type; 589 void *errCtxt; /* user specific error context */ 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 592 int err; 593 int nberrors; 594 xmlStructuredErrorFunc serror; 595 596 xmlSchemaConstructionCtxtPtr constructor; 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 598 599 /* xmlSchemaPtr topschema; */ 600 /* xmlHashTablePtr namespaces; */ 601 602 xmlSchemaPtr schema; /* The main schema in use */ 603 int counter; 604 605 const xmlChar *URL; 606 xmlDocPtr doc; 607 int preserve; /* Whether the doc should be freed */ 608 609 const char *buffer; 610 int size; 611 612 /* 613 * Used to build complex element content models 614 */ 615 xmlAutomataPtr am; 616 xmlAutomataStatePtr start; 617 xmlAutomataStatePtr end; 618 xmlAutomataStatePtr state; 619 620 xmlDictPtr dict; /* dictionary for interned string names */ 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 622 int options; 623 xmlSchemaValidCtxtPtr vctxt; 624 int isS4S; 625 int isRedefine; 626 int xsiAssemble; 627 int stop; /* If the parser should stop; i.e. a critical error. */ 628 const xmlChar *targetNamespace; 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 630 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 632 int redefCounter; /* Used for redefinitions. */ 633 xmlSchemaItemListPtr attrProhibs; 634 }; 635 636 /** 637 * xmlSchemaQNameRef: 638 * 639 * A component reference item (not a schema component) 640 * (Extends xmlSchemaBasicItem) 641 */ 642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 644 struct _xmlSchemaQNameRef { 645 xmlSchemaTypeType type; 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 647 xmlSchemaTypeType itemType; 648 const xmlChar *name; 649 const xmlChar *targetNamespace; 650 xmlNodePtr node; 651 }; 652 653 /** 654 * xmlSchemaParticle: 655 * 656 * A particle component. 657 * (Extends xmlSchemaTreeItem) 658 */ 659 typedef struct _xmlSchemaParticle xmlSchemaParticle; 660 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 661 struct _xmlSchemaParticle { 662 xmlSchemaTypeType type; 663 xmlSchemaAnnotPtr annot; 664 xmlSchemaTreeItemPtr next; /* next particle */ 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 667 etc.) */ 668 int minOccurs; 669 int maxOccurs; 670 xmlNodePtr node; 671 }; 672 673 /** 674 * xmlSchemaModelGroup: 675 * 676 * A model group component. 677 * (Extends xmlSchemaTreeItem) 678 */ 679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 681 struct _xmlSchemaModelGroup { 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 683 xmlSchemaAnnotPtr annot; 684 xmlSchemaTreeItemPtr next; /* not used */ 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 686 xmlNodePtr node; 687 }; 688 689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 691 /** 692 * xmlSchemaModelGroupDef: 693 * 694 * A model group definition component. 695 * (Extends xmlSchemaTreeItem) 696 */ 697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 699 struct _xmlSchemaModelGroupDef { 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 701 xmlSchemaAnnotPtr annot; 702 xmlSchemaTreeItemPtr next; /* not used */ 703 xmlSchemaTreeItemPtr children; /* the "model group" */ 704 const xmlChar *name; 705 const xmlChar *targetNamespace; 706 xmlNodePtr node; 707 int flags; 708 }; 709 710 typedef struct _xmlSchemaIDC xmlSchemaIDC; 711 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 712 713 /** 714 * xmlSchemaIDCSelect: 715 * 716 * The identity-constraint "field" and "selector" item, holding the 717 * XPath expression. 718 */ 719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 721 struct _xmlSchemaIDCSelect { 722 xmlSchemaIDCSelectPtr next; 723 xmlSchemaIDCPtr idc; 724 int index; /* an index position if significant for IDC key-sequences */ 725 const xmlChar *xpath; /* the XPath expression */ 726 void *xpathComp; /* the compiled XPath expression */ 727 }; 728 729 /** 730 * xmlSchemaIDC: 731 * 732 * The identity-constraint definition component. 733 * (Extends xmlSchemaAnnotItem) 734 */ 735 736 struct _xmlSchemaIDC { 737 xmlSchemaTypeType type; 738 xmlSchemaAnnotPtr annot; 739 xmlSchemaIDCPtr next; 740 xmlNodePtr node; 741 const xmlChar *name; 742 const xmlChar *targetNamespace; 743 xmlSchemaIDCSelectPtr selector; 744 xmlSchemaIDCSelectPtr fields; 745 int nbFields; 746 xmlSchemaQNameRefPtr ref; 747 }; 748 749 /** 750 * xmlSchemaIDCAug: 751 * 752 * The augmented IDC information used for validation. 753 */ 754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 756 struct _xmlSchemaIDCAug { 757 xmlSchemaIDCAugPtr next; /* next in a list */ 758 xmlSchemaIDCPtr def; /* the IDC definition */ 759 int keyrefDepth; /* the lowest tree level to which IDC 760 tables need to be bubbled upwards */ 761 }; 762 763 /** 764 * xmlSchemaPSVIIDCKeySequence: 765 * 766 * The key sequence of a node table item. 767 */ 768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 770 struct _xmlSchemaPSVIIDCKey { 771 xmlSchemaTypePtr type; 772 xmlSchemaValPtr val; 773 }; 774 775 /** 776 * xmlSchemaPSVIIDCNode: 777 * 778 * The node table item of a node table. 779 */ 780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 782 struct _xmlSchemaPSVIIDCNode { 783 xmlNodePtr node; 784 xmlSchemaPSVIIDCKeyPtr *keys; 785 int nodeLine; 786 int nodeQNameID; 787 788 }; 789 790 /** 791 * xmlSchemaPSVIIDCBinding: 792 * 793 * The identity-constraint binding item of the [identity-constraint table]. 794 */ 795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 797 struct _xmlSchemaPSVIIDCBinding { 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 799 xmlSchemaIDCPtr definition; /* the IDC definition */ 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 801 int nbNodes; /* number of entries in the node table */ 802 int sizeNodes; /* size of the node table */ 803 xmlSchemaItemListPtr dupls; 804 }; 805 806 807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 809 810 #define XPATH_STATE_OBJ_MATCHES -2 811 #define XPATH_STATE_OBJ_BLOCKED -3 812 813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 815 816 /** 817 * xmlSchemaIDCStateObj: 818 * 819 * The state object used to evaluate XPath expressions. 820 */ 821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 823 struct _xmlSchemaIDCStateObj { 824 int type; 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 826 int depth; /* depth of creation */ 827 int *history; /* list of (depth, state-id) tuples */ 828 int nbHistory; 829 int sizeHistory; 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 831 matcher */ 832 xmlSchemaIDCSelectPtr sel; 833 void *xpathCtxt; 834 }; 835 836 #define IDC_MATCHER 0 837 838 /** 839 * xmlSchemaIDCMatcher: 840 * 841 * Used to evaluate IDC selectors (and fields). 842 */ 843 struct _xmlSchemaIDCMatcher { 844 int type; 845 int depth; /* the tree depth at creation time */ 846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 849 int idcType; 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 851 elements */ 852 int sizeKeySeqs; 853 xmlSchemaItemListPtr targets; /* list of target-node 854 (xmlSchemaPSVIIDCNodePtr) entries */ 855 }; 856 857 /* 858 * Element info flags. 859 */ 860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 864 865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 868 869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 873 874 /** 875 * xmlSchemaNodeInfo: 876 * 877 * Holds information of an element node. 878 */ 879 struct _xmlSchemaNodeInfo { 880 int nodeType; 881 xmlNodePtr node; 882 int nodeLine; 883 const xmlChar *localName; 884 const xmlChar *nsName; 885 const xmlChar *value; 886 xmlSchemaValPtr val; /* the pre-computed value if any */ 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 888 889 int flags; /* combination of node info flags */ 890 891 int valNeeded; 892 int normVal; 893 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 895 int depth; 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 897 for the scope element*/ 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 899 element */ 900 xmlRegExecCtxtPtr regexCtxt; 901 902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 903 int nbNsBindings; 904 int sizeNsBindings; 905 906 int hasKeyrefs; 907 int appliedXPath; /* Indicates that an XPath has been applied. */ 908 }; 909 910 #define XML_SCHEMAS_ATTR_UNKNOWN 1 911 #define XML_SCHEMAS_ATTR_ASSESSED 2 912 #define XML_SCHEMAS_ATTR_PROHIBITED 3 913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 917 #define XML_SCHEMAS_ATTR_DEFAULT 8 918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 926 #define XML_SCHEMAS_ATTR_META 17 927 /* 928 * @metaType values of xmlSchemaAttrInfo. 929 */ 930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 935 936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 938 struct _xmlSchemaAttrInfo { 939 int nodeType; 940 xmlNodePtr node; 941 int nodeLine; 942 const xmlChar *localName; 943 const xmlChar *nsName; 944 const xmlChar *value; 945 xmlSchemaValPtr val; /* the pre-computed value if any */ 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 947 int flags; /* combination of node info flags */ 948 949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 951 int state; 952 int metaType; 953 const xmlChar *vcValue; /* the value constraint value */ 954 xmlSchemaNodeInfoPtr parent; 955 }; 956 957 958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 959 /** 960 * xmlSchemaValidCtxt: 961 * 962 * A Schemas validation context 963 */ 964 struct _xmlSchemaValidCtxt { 965 int type; 966 void *errCtxt; /* user specific data block */ 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 969 xmlStructuredErrorFunc serror; 970 971 xmlSchemaPtr schema; /* The schema in use */ 972 xmlDocPtr doc; 973 xmlParserInputBufferPtr input; 974 xmlCharEncoding enc; 975 xmlSAXHandlerPtr sax; 976 xmlParserCtxtPtr parserCtxt; 977 void *user_data; /* TODO: What is this for? */ 978 char *filename; 979 980 int err; 981 int nberrors; 982 983 xmlNodePtr node; 984 xmlNodePtr cur; 985 /* xmlSchemaTypePtr type; */ 986 987 xmlRegExecCtxtPtr regexp; 988 xmlSchemaValPtr value; 989 990 int valueWS; 991 int options; 992 xmlNodePtr validationRoot; 993 xmlSchemaParserCtxtPtr pctxt; 994 int xsiAssemble; 995 996 int depth; 997 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 998 int sizeElemInfos; 999 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1000 1001 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1002 1003 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1004 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1005 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1006 1007 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1008 int nbIdcNodes; 1009 int sizeIdcNodes; 1010 1011 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1012 int nbIdcKeys; 1013 int sizeIdcKeys; 1014 1015 int flags; 1016 1017 xmlDictPtr dict; 1018 1019 #ifdef LIBXML_READER_ENABLED 1020 xmlTextReaderPtr reader; 1021 #endif 1022 1023 xmlSchemaAttrInfoPtr *attrInfos; 1024 int nbAttrInfos; 1025 int sizeAttrInfos; 1026 1027 int skipDepth; 1028 xmlSchemaItemListPtr nodeQNames; 1029 int hasKeyrefs; 1030 int createIDCNodeTables; 1031 int psviExposeIDCNodeTables; 1032 1033 /* Locator for error reporting in streaming mode */ 1034 xmlSchemaValidityLocatorFunc locFunc; 1035 void *locCtxt; 1036 }; 1037 1038 /** 1039 * xmlSchemaSubstGroup: 1040 * 1041 * 1042 */ 1043 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1044 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1045 struct _xmlSchemaSubstGroup { 1046 xmlSchemaElementPtr head; 1047 xmlSchemaItemListPtr members; 1048 }; 1049 1050 /************************************************************************ 1051 * * 1052 * Some predeclarations * 1053 * * 1054 ************************************************************************/ 1055 1056 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1057 xmlSchemaPtr schema, 1058 xmlNodePtr node); 1059 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1060 xmlSchemaPtr schema, 1061 xmlNodePtr node); 1062 static int 1063 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1064 xmlSchemaAbstractCtxtPtr ctxt); 1065 static const xmlChar * 1066 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1067 static int 1068 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070 static int 1071 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1072 xmlSchemaParserCtxtPtr ctxt); 1073 static void 1074 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1075 static xmlSchemaWhitespaceValueType 1076 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1077 static xmlSchemaTreeItemPtr 1078 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1079 xmlNodePtr node, xmlSchemaTypeType type, 1080 int withParticle); 1081 static const xmlChar * 1082 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1083 static xmlSchemaTypeLinkPtr 1084 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1085 static void 1086 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1087 const char *funcName, 1088 const char *message) LIBXML_ATTR_FORMAT(3,0); 1089 static int 1090 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1091 xmlSchemaTypePtr type, 1092 xmlSchemaTypePtr baseType, 1093 int subset); 1094 static void 1095 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1096 xmlSchemaParserCtxtPtr ctxt); 1097 static void 1098 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1099 static xmlSchemaQNameRefPtr 1100 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1101 xmlSchemaPtr schema, 1102 xmlNodePtr node); 1103 1104 /************************************************************************ 1105 * * 1106 * Helper functions * 1107 * * 1108 ************************************************************************/ 1109 1110 /** 1111 * xmlSchemaItemTypeToStr: 1112 * @type: the type of the schema item 1113 * 1114 * Returns the component name of a schema item. 1115 */ 1116 static const xmlChar * 1117 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1118 { 1119 switch (type) { 1120 case XML_SCHEMA_TYPE_BASIC: 1121 return(BAD_CAST "simple type definition"); 1122 case XML_SCHEMA_TYPE_SIMPLE: 1123 return(BAD_CAST "simple type definition"); 1124 case XML_SCHEMA_TYPE_COMPLEX: 1125 return(BAD_CAST "complex type definition"); 1126 case XML_SCHEMA_TYPE_ELEMENT: 1127 return(BAD_CAST "element declaration"); 1128 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1129 return(BAD_CAST "attribute use"); 1130 case XML_SCHEMA_TYPE_ATTRIBUTE: 1131 return(BAD_CAST "attribute declaration"); 1132 case XML_SCHEMA_TYPE_GROUP: 1133 return(BAD_CAST "model group definition"); 1134 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1135 return(BAD_CAST "attribute group definition"); 1136 case XML_SCHEMA_TYPE_NOTATION: 1137 return(BAD_CAST "notation declaration"); 1138 case XML_SCHEMA_TYPE_SEQUENCE: 1139 return(BAD_CAST "model group (sequence)"); 1140 case XML_SCHEMA_TYPE_CHOICE: 1141 return(BAD_CAST "model group (choice)"); 1142 case XML_SCHEMA_TYPE_ALL: 1143 return(BAD_CAST "model group (all)"); 1144 case XML_SCHEMA_TYPE_PARTICLE: 1145 return(BAD_CAST "particle"); 1146 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1147 return(BAD_CAST "unique identity-constraint"); 1148 /* return(BAD_CAST "IDC (unique)"); */ 1149 case XML_SCHEMA_TYPE_IDC_KEY: 1150 return(BAD_CAST "key identity-constraint"); 1151 /* return(BAD_CAST "IDC (key)"); */ 1152 case XML_SCHEMA_TYPE_IDC_KEYREF: 1153 return(BAD_CAST "keyref identity-constraint"); 1154 /* return(BAD_CAST "IDC (keyref)"); */ 1155 case XML_SCHEMA_TYPE_ANY: 1156 return(BAD_CAST "wildcard (any)"); 1157 case XML_SCHEMA_EXTRA_QNAMEREF: 1158 return(BAD_CAST "[helper component] QName reference"); 1159 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1160 return(BAD_CAST "[helper component] attribute use prohibition"); 1161 default: 1162 return(BAD_CAST "Not a schema component"); 1163 } 1164 } 1165 1166 /** 1167 * xmlSchemaGetComponentTypeStr: 1168 * @type: the type of the schema item 1169 * 1170 * Returns the component name of a schema item. 1171 */ 1172 static const xmlChar * 1173 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1174 { 1175 switch (item->type) { 1176 case XML_SCHEMA_TYPE_BASIC: 1177 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1178 return(BAD_CAST "complex type definition"); 1179 else 1180 return(BAD_CAST "simple type definition"); 1181 default: 1182 return(xmlSchemaItemTypeToStr(item->type)); 1183 } 1184 } 1185 1186 /** 1187 * xmlSchemaGetComponentNode: 1188 * @item: a schema component 1189 * 1190 * Returns node associated with the schema component. 1191 * NOTE that such a node need not be available; plus, a component's 1192 * node need not to reflect the component directly, since there is no 1193 * one-to-one relationship between the XML Schema representation and 1194 * the component representation. 1195 */ 1196 static xmlNodePtr 1197 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1198 { 1199 switch (item->type) { 1200 case XML_SCHEMA_TYPE_ELEMENT: 1201 return (((xmlSchemaElementPtr) item)->node); 1202 case XML_SCHEMA_TYPE_ATTRIBUTE: 1203 return (((xmlSchemaAttributePtr) item)->node); 1204 case XML_SCHEMA_TYPE_COMPLEX: 1205 case XML_SCHEMA_TYPE_SIMPLE: 1206 return (((xmlSchemaTypePtr) item)->node); 1207 case XML_SCHEMA_TYPE_ANY: 1208 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1209 return (((xmlSchemaWildcardPtr) item)->node); 1210 case XML_SCHEMA_TYPE_PARTICLE: 1211 return (((xmlSchemaParticlePtr) item)->node); 1212 case XML_SCHEMA_TYPE_SEQUENCE: 1213 case XML_SCHEMA_TYPE_CHOICE: 1214 case XML_SCHEMA_TYPE_ALL: 1215 return (((xmlSchemaModelGroupPtr) item)->node); 1216 case XML_SCHEMA_TYPE_GROUP: 1217 return (((xmlSchemaModelGroupDefPtr) item)->node); 1218 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1219 return (((xmlSchemaAttributeGroupPtr) item)->node); 1220 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1221 case XML_SCHEMA_TYPE_IDC_KEY: 1222 case XML_SCHEMA_TYPE_IDC_KEYREF: 1223 return (((xmlSchemaIDCPtr) item)->node); 1224 case XML_SCHEMA_EXTRA_QNAMEREF: 1225 return(((xmlSchemaQNameRefPtr) item)->node); 1226 /* TODO: What to do with NOTATIONs? 1227 case XML_SCHEMA_TYPE_NOTATION: 1228 return (((xmlSchemaNotationPtr) item)->node); 1229 */ 1230 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1231 return (((xmlSchemaAttributeUsePtr) item)->node); 1232 default: 1233 return (NULL); 1234 } 1235 } 1236 1237 #if 0 1238 /** 1239 * xmlSchemaGetNextComponent: 1240 * @item: a schema component 1241 * 1242 * Returns the next sibling of the schema component. 1243 */ 1244 static xmlSchemaBasicItemPtr 1245 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1246 { 1247 switch (item->type) { 1248 case XML_SCHEMA_TYPE_ELEMENT: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1250 case XML_SCHEMA_TYPE_ATTRIBUTE: 1251 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1252 case XML_SCHEMA_TYPE_COMPLEX: 1253 case XML_SCHEMA_TYPE_SIMPLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1255 case XML_SCHEMA_TYPE_ANY: 1256 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1257 return (NULL); 1258 case XML_SCHEMA_TYPE_PARTICLE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1260 case XML_SCHEMA_TYPE_SEQUENCE: 1261 case XML_SCHEMA_TYPE_CHOICE: 1262 case XML_SCHEMA_TYPE_ALL: 1263 return (NULL); 1264 case XML_SCHEMA_TYPE_GROUP: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1268 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1269 case XML_SCHEMA_TYPE_IDC_KEY: 1270 case XML_SCHEMA_TYPE_IDC_KEYREF: 1271 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1272 default: 1273 return (NULL); 1274 } 1275 } 1276 #endif 1277 1278 1279 /** 1280 * xmlSchemaFormatQName: 1281 * @buf: the string buffer 1282 * @namespaceName: the namespace name 1283 * @localName: the local name 1284 * 1285 * Returns the given QName in the format "{namespaceName}localName" or 1286 * just "localName" if @namespaceName is NULL. 1287 * 1288 * Returns the localName if @namespaceName is NULL, a formatted 1289 * string otherwise. 1290 */ 1291 static const xmlChar* 1292 xmlSchemaFormatQName(xmlChar **buf, 1293 const xmlChar *namespaceName, 1294 const xmlChar *localName) 1295 { 1296 FREE_AND_NULL(*buf) 1297 if (namespaceName != NULL) { 1298 *buf = xmlStrdup(BAD_CAST "{"); 1299 *buf = xmlStrcat(*buf, namespaceName); 1300 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1301 } 1302 if (localName != NULL) { 1303 if (namespaceName == NULL) 1304 return(localName); 1305 *buf = xmlStrcat(*buf, localName); 1306 } else { 1307 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1308 } 1309 return ((const xmlChar *) *buf); 1310 } 1311 1312 static const xmlChar* 1313 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1314 { 1315 if (ns != NULL) 1316 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1317 else 1318 return (xmlSchemaFormatQName(buf, NULL, localName)); 1319 } 1320 1321 static const xmlChar * 1322 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1323 { 1324 switch (item->type) { 1325 case XML_SCHEMA_TYPE_ELEMENT: 1326 return (((xmlSchemaElementPtr) item)->name); 1327 case XML_SCHEMA_TYPE_ATTRIBUTE: 1328 return (((xmlSchemaAttributePtr) item)->name); 1329 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1330 return (((xmlSchemaAttributeGroupPtr) item)->name); 1331 case XML_SCHEMA_TYPE_BASIC: 1332 case XML_SCHEMA_TYPE_SIMPLE: 1333 case XML_SCHEMA_TYPE_COMPLEX: 1334 return (((xmlSchemaTypePtr) item)->name); 1335 case XML_SCHEMA_TYPE_GROUP: 1336 return (((xmlSchemaModelGroupDefPtr) item)->name); 1337 case XML_SCHEMA_TYPE_IDC_KEY: 1338 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1339 case XML_SCHEMA_TYPE_IDC_KEYREF: 1340 return (((xmlSchemaIDCPtr) item)->name); 1341 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1342 if (WXS_ATTRUSE_DECL(item) != NULL) { 1343 return(xmlSchemaGetComponentName( 1344 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1345 } else 1346 return(NULL); 1347 case XML_SCHEMA_EXTRA_QNAMEREF: 1348 return (((xmlSchemaQNameRefPtr) item)->name); 1349 case XML_SCHEMA_TYPE_NOTATION: 1350 return (((xmlSchemaNotationPtr) item)->name); 1351 default: 1352 /* 1353 * Other components cannot have names. 1354 */ 1355 break; 1356 } 1357 return (NULL); 1358 } 1359 1360 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1361 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1362 /* 1363 static const xmlChar * 1364 xmlSchemaGetQNameRefName(void *ref) 1365 { 1366 return(((xmlSchemaQNameRefPtr) ref)->name); 1367 } 1368 1369 static const xmlChar * 1370 xmlSchemaGetQNameRefTargetNs(void *ref) 1371 { 1372 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1373 } 1374 */ 1375 1376 static const xmlChar * 1377 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1378 { 1379 switch (item->type) { 1380 case XML_SCHEMA_TYPE_ELEMENT: 1381 return (((xmlSchemaElementPtr) item)->targetNamespace); 1382 case XML_SCHEMA_TYPE_ATTRIBUTE: 1383 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1384 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1385 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_BASIC: 1387 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1388 case XML_SCHEMA_TYPE_SIMPLE: 1389 case XML_SCHEMA_TYPE_COMPLEX: 1390 return (((xmlSchemaTypePtr) item)->targetNamespace); 1391 case XML_SCHEMA_TYPE_GROUP: 1392 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1393 case XML_SCHEMA_TYPE_IDC_KEY: 1394 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1395 case XML_SCHEMA_TYPE_IDC_KEYREF: 1396 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1397 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1398 if (WXS_ATTRUSE_DECL(item) != NULL) { 1399 return(xmlSchemaGetComponentTargetNs( 1400 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1401 } 1402 /* TODO: Will returning NULL break something? */ 1403 break; 1404 case XML_SCHEMA_EXTRA_QNAMEREF: 1405 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1406 case XML_SCHEMA_TYPE_NOTATION: 1407 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1408 default: 1409 /* 1410 * Other components cannot have names. 1411 */ 1412 break; 1413 } 1414 return (NULL); 1415 } 1416 1417 static const xmlChar* 1418 xmlSchemaGetComponentQName(xmlChar **buf, 1419 void *item) 1420 { 1421 return (xmlSchemaFormatQName(buf, 1422 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1423 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1424 } 1425 1426 static const xmlChar* 1427 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1428 { 1429 xmlChar *str = NULL; 1430 1431 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1432 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1433 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1434 (xmlSchemaBasicItemPtr) item)); 1435 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1436 FREE_AND_NULL(str); 1437 return(*buf); 1438 } 1439 1440 static const xmlChar* 1441 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1442 { 1443 return(xmlSchemaGetComponentDesignation(buf, idc)); 1444 } 1445 1446 /** 1447 * xmlSchemaWildcardPCToString: 1448 * @pc: the type of processContents 1449 * 1450 * Returns a string representation of the type of 1451 * processContents. 1452 */ 1453 static const xmlChar * 1454 xmlSchemaWildcardPCToString(int pc) 1455 { 1456 switch (pc) { 1457 case XML_SCHEMAS_ANY_SKIP: 1458 return (BAD_CAST "skip"); 1459 case XML_SCHEMAS_ANY_LAX: 1460 return (BAD_CAST "lax"); 1461 case XML_SCHEMAS_ANY_STRICT: 1462 return (BAD_CAST "strict"); 1463 default: 1464 return (BAD_CAST "invalid process contents"); 1465 } 1466 } 1467 1468 /** 1469 * xmlSchemaGetCanonValueWhtspExt: 1470 * @val: the precomputed value 1471 * @retValue: the returned value 1472 * @ws: the whitespace type of the value 1473 * 1474 * Get a the canonical representation of the value. 1475 * The caller has to free the returned retValue. 1476 * 1477 * Returns 0 if the value could be built and -1 in case of 1478 * API errors or if the value type is not supported yet. 1479 */ 1480 static int 1481 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1482 xmlSchemaWhitespaceValueType ws, 1483 xmlChar **retValue) 1484 { 1485 int list; 1486 xmlSchemaValType valType; 1487 const xmlChar *value, *value2 = NULL; 1488 1489 1490 if ((retValue == NULL) || (val == NULL)) 1491 return (-1); 1492 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1493 *retValue = NULL; 1494 do { 1495 value = NULL; 1496 valType = xmlSchemaGetValType(val); 1497 switch (valType) { 1498 case XML_SCHEMAS_STRING: 1499 case XML_SCHEMAS_NORMSTRING: 1500 case XML_SCHEMAS_ANYSIMPLETYPE: 1501 value = xmlSchemaValueGetAsString(val); 1502 if (value != NULL) { 1503 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1504 value2 = xmlSchemaCollapseString(value); 1505 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1506 value2 = xmlSchemaWhiteSpaceReplace(value); 1507 if (value2 != NULL) 1508 value = value2; 1509 } 1510 break; 1511 default: 1512 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1513 if (value2 != NULL) 1514 xmlFree((xmlChar *) value2); 1515 goto internal_error; 1516 } 1517 value = value2; 1518 } 1519 if (*retValue == NULL) 1520 if (value == NULL) { 1521 if (! list) 1522 *retValue = xmlStrdup(BAD_CAST ""); 1523 } else 1524 *retValue = xmlStrdup(value); 1525 else if (value != NULL) { 1526 /* List. */ 1527 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1528 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1529 } 1530 FREE_AND_NULL(value2) 1531 val = xmlSchemaValueGetNext(val); 1532 } while (val != NULL); 1533 1534 return (0); 1535 internal_error: 1536 if (*retValue != NULL) 1537 xmlFree((xmlChar *) (*retValue)); 1538 if (value2 != NULL) 1539 xmlFree((xmlChar *) value2); 1540 return (-1); 1541 } 1542 1543 /** 1544 * xmlSchemaFormatItemForReport: 1545 * @buf: the string buffer 1546 * @itemDes: the designation of the item 1547 * @itemName: the name of the item 1548 * @item: the item as an object 1549 * @itemNode: the node of the item 1550 * @local: the local name 1551 * @parsing: if the function is used during the parse 1552 * 1553 * Returns a representation of the given item used 1554 * for error reports. 1555 * 1556 * The following order is used to build the resulting 1557 * designation if the arguments are not NULL: 1558 * 1a. If itemDes not NULL -> itemDes 1559 * 1b. If (itemDes not NULL) and (itemName not NULL) 1560 * -> itemDes + itemName 1561 * 2. If the preceding was NULL and (item not NULL) -> item 1562 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1563 * 1564 * If the itemNode is an attribute node, the name of the attribute 1565 * will be appended to the result. 1566 * 1567 * Returns the formatted string and sets @buf to the resulting value. 1568 */ 1569 static xmlChar* 1570 xmlSchemaFormatItemForReport(xmlChar **buf, 1571 const xmlChar *itemDes, 1572 xmlSchemaBasicItemPtr item, 1573 xmlNodePtr itemNode) 1574 { 1575 xmlChar *str = NULL; 1576 int named = 1; 1577 1578 if (*buf != NULL) { 1579 xmlFree(*buf); 1580 *buf = NULL; 1581 } 1582 1583 if (itemDes != NULL) { 1584 *buf = xmlStrdup(itemDes); 1585 } else if (item != NULL) { 1586 switch (item->type) { 1587 case XML_SCHEMA_TYPE_BASIC: { 1588 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1589 1590 if (WXS_IS_ATOMIC(type)) 1591 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1592 else if (WXS_IS_LIST(type)) 1593 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1594 else if (WXS_IS_UNION(type)) 1595 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1596 else 1597 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1598 *buf = xmlStrcat(*buf, type->name); 1599 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1600 } 1601 break; 1602 case XML_SCHEMA_TYPE_SIMPLE: { 1603 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1604 1605 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1606 *buf = xmlStrdup(BAD_CAST""); 1607 } else { 1608 *buf = xmlStrdup(BAD_CAST "local "); 1609 } 1610 if (WXS_IS_ATOMIC(type)) 1611 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1612 else if (WXS_IS_LIST(type)) 1613 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1614 else if (WXS_IS_UNION(type)) 1615 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1616 else 1617 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1618 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1619 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1620 *buf = xmlStrcat(*buf, type->name); 1621 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1622 } 1623 } 1624 break; 1625 case XML_SCHEMA_TYPE_COMPLEX: { 1626 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1627 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1629 *buf = xmlStrdup(BAD_CAST ""); 1630 else 1631 *buf = xmlStrdup(BAD_CAST "local "); 1632 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1633 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1634 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1635 *buf = xmlStrcat(*buf, type->name); 1636 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1637 } 1638 } 1639 break; 1640 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1641 xmlSchemaAttributeUsePtr ause; 1642 1643 ause = WXS_ATTR_USE_CAST item; 1644 *buf = xmlStrdup(BAD_CAST "attribute use "); 1645 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1646 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1647 *buf = xmlStrcat(*buf, 1648 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1649 FREE_AND_NULL(str) 1650 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1651 } else { 1652 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1653 } 1654 } 1655 break; 1656 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1657 xmlSchemaAttributePtr attr; 1658 1659 attr = (xmlSchemaAttributePtr) item; 1660 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1661 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1662 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1663 attr->targetNamespace, attr->name)); 1664 FREE_AND_NULL(str) 1665 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1666 } 1667 break; 1668 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1669 xmlSchemaGetComponentDesignation(buf, item); 1670 break; 1671 case XML_SCHEMA_TYPE_ELEMENT: { 1672 xmlSchemaElementPtr elem; 1673 1674 elem = (xmlSchemaElementPtr) item; 1675 *buf = xmlStrdup(BAD_CAST "element decl."); 1676 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1677 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1678 elem->targetNamespace, elem->name)); 1679 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1680 } 1681 break; 1682 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1683 case XML_SCHEMA_TYPE_IDC_KEY: 1684 case XML_SCHEMA_TYPE_IDC_KEYREF: 1685 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1686 *buf = xmlStrdup(BAD_CAST "unique '"); 1687 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1688 *buf = xmlStrdup(BAD_CAST "key '"); 1689 else 1690 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1691 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1692 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1693 break; 1694 case XML_SCHEMA_TYPE_ANY: 1695 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1696 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1697 ((xmlSchemaWildcardPtr) item)->processContents)); 1698 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1699 break; 1700 case XML_SCHEMA_FACET_MININCLUSIVE: 1701 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1702 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1703 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1704 case XML_SCHEMA_FACET_TOTALDIGITS: 1705 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1706 case XML_SCHEMA_FACET_PATTERN: 1707 case XML_SCHEMA_FACET_ENUMERATION: 1708 case XML_SCHEMA_FACET_WHITESPACE: 1709 case XML_SCHEMA_FACET_LENGTH: 1710 case XML_SCHEMA_FACET_MAXLENGTH: 1711 case XML_SCHEMA_FACET_MINLENGTH: 1712 *buf = xmlStrdup(BAD_CAST "facet '"); 1713 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1714 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1715 break; 1716 case XML_SCHEMA_TYPE_GROUP: { 1717 *buf = xmlStrdup(BAD_CAST "model group def."); 1718 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1719 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1720 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1721 FREE_AND_NULL(str) 1722 } 1723 break; 1724 case XML_SCHEMA_TYPE_SEQUENCE: 1725 case XML_SCHEMA_TYPE_CHOICE: 1726 case XML_SCHEMA_TYPE_ALL: 1727 case XML_SCHEMA_TYPE_PARTICLE: 1728 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1729 break; 1730 case XML_SCHEMA_TYPE_NOTATION: { 1731 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1732 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1733 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1734 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1735 FREE_AND_NULL(str); 1736 } 1737 default: 1738 named = 0; 1739 } 1740 } else 1741 named = 0; 1742 1743 if ((named == 0) && (itemNode != NULL)) { 1744 xmlNodePtr elem; 1745 1746 if (itemNode->type == XML_ATTRIBUTE_NODE) 1747 elem = itemNode->parent; 1748 else 1749 elem = itemNode; 1750 *buf = xmlStrdup(BAD_CAST "Element '"); 1751 if (elem->ns != NULL) { 1752 *buf = xmlStrcat(*buf, 1753 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1754 FREE_AND_NULL(str) 1755 } else 1756 *buf = xmlStrcat(*buf, elem->name); 1757 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1758 1759 } 1760 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1761 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1762 if (itemNode->ns != NULL) { 1763 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1764 itemNode->ns->href, itemNode->name)); 1765 FREE_AND_NULL(str) 1766 } else 1767 *buf = xmlStrcat(*buf, itemNode->name); 1768 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1769 } 1770 FREE_AND_NULL(str) 1771 1772 return (xmlEscapeFormatString(buf)); 1773 } 1774 1775 /** 1776 * xmlSchemaFormatFacetEnumSet: 1777 * @buf: the string buffer 1778 * @type: the type holding the enumeration facets 1779 * 1780 * Builds a string consisting of all enumeration elements. 1781 * 1782 * Returns a string of all enumeration elements. 1783 */ 1784 static const xmlChar * 1785 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1786 xmlChar **buf, xmlSchemaTypePtr type) 1787 { 1788 xmlSchemaFacetPtr facet; 1789 xmlSchemaWhitespaceValueType ws; 1790 xmlChar *value = NULL; 1791 int res, found = 0; 1792 1793 if (*buf != NULL) 1794 xmlFree(*buf); 1795 *buf = NULL; 1796 1797 do { 1798 /* 1799 * Use the whitespace type of the base type. 1800 */ 1801 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1802 for (facet = type->facets; facet != NULL; facet = facet->next) { 1803 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1804 continue; 1805 found = 1; 1806 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1807 ws, &value); 1808 if (res == -1) { 1809 xmlSchemaInternalErr(actxt, 1810 "xmlSchemaFormatFacetEnumSet", 1811 "compute the canonical lexical representation"); 1812 if (*buf != NULL) 1813 xmlFree(*buf); 1814 *buf = NULL; 1815 return (NULL); 1816 } 1817 if (*buf == NULL) 1818 *buf = xmlStrdup(BAD_CAST "'"); 1819 else 1820 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1821 *buf = xmlStrcat(*buf, BAD_CAST value); 1822 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1823 if (value != NULL) { 1824 xmlFree((xmlChar *)value); 1825 value = NULL; 1826 } 1827 } 1828 /* 1829 * The enumeration facet of a type restricts the enumeration 1830 * facet of the ancestor type; i.e., such restricted enumerations 1831 * do not belong to the set of the given type. Thus we break 1832 * on the first found enumeration. 1833 */ 1834 if (found) 1835 break; 1836 type = type->baseType; 1837 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1838 1839 return ((const xmlChar *) *buf); 1840 } 1841 1842 /************************************************************************ 1843 * * 1844 * Error functions * 1845 * * 1846 ************************************************************************/ 1847 1848 #if 0 1849 static void 1850 xmlSchemaErrMemory(const char *msg) 1851 { 1852 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1853 msg); 1854 } 1855 #endif 1856 1857 static void 1858 xmlSchemaPSimpleErr(const char *msg) 1859 { 1860 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1861 msg); 1862 } 1863 1864 /** 1865 * xmlSchemaPErrMemory: 1866 * @node: a context node 1867 * @extra: extra informations 1868 * 1869 * Handle an out of memory condition 1870 */ 1871 static void 1872 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1873 const char *extra, xmlNodePtr node) 1874 { 1875 if (ctxt != NULL) 1876 ctxt->nberrors++; 1877 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1878 extra); 1879 } 1880 1881 /** 1882 * xmlSchemaPErr: 1883 * @ctxt: the parsing context 1884 * @node: the context node 1885 * @error: the error code 1886 * @msg: the error message 1887 * @str1: extra data 1888 * @str2: extra data 1889 * 1890 * Handle a parser error 1891 */ 1892 static void LIBXML_ATTR_FORMAT(4,0) 1893 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1894 const char *msg, const xmlChar * str1, const xmlChar * str2) 1895 { 1896 xmlGenericErrorFunc channel = NULL; 1897 xmlStructuredErrorFunc schannel = NULL; 1898 void *data = NULL; 1899 1900 if (ctxt != NULL) { 1901 ctxt->nberrors++; 1902 ctxt->err = error; 1903 channel = ctxt->error; 1904 data = ctxt->errCtxt; 1905 schannel = ctxt->serror; 1906 } 1907 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1908 error, XML_ERR_ERROR, NULL, 0, 1909 (const char *) str1, (const char *) str2, NULL, 0, 0, 1910 msg, str1, str2); 1911 } 1912 1913 /** 1914 * xmlSchemaPErr2: 1915 * @ctxt: the parsing context 1916 * @node: the context node 1917 * @node: the current child 1918 * @error: the error code 1919 * @msg: the error message 1920 * @str1: extra data 1921 * @str2: extra data 1922 * 1923 * Handle a parser error 1924 */ 1925 static void LIBXML_ATTR_FORMAT(5,0) 1926 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1927 xmlNodePtr child, int error, 1928 const char *msg, const xmlChar * str1, const xmlChar * str2) 1929 { 1930 if (child != NULL) 1931 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1932 else 1933 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1934 } 1935 1936 1937 /** 1938 * xmlSchemaPErrExt: 1939 * @ctxt: the parsing context 1940 * @node: the context node 1941 * @error: the error code 1942 * @strData1: extra data 1943 * @strData2: extra data 1944 * @strData3: extra data 1945 * @msg: the message 1946 * @str1: extra parameter for the message display 1947 * @str2: extra parameter for the message display 1948 * @str3: extra parameter for the message display 1949 * @str4: extra parameter for the message display 1950 * @str5: extra parameter for the message display 1951 * 1952 * Handle a parser error 1953 */ 1954 static void LIBXML_ATTR_FORMAT(7,0) 1955 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1956 const xmlChar * strData1, const xmlChar * strData2, 1957 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1958 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1959 const xmlChar * str5) 1960 { 1961 1962 xmlGenericErrorFunc channel = NULL; 1963 xmlStructuredErrorFunc schannel = NULL; 1964 void *data = NULL; 1965 1966 if (ctxt != NULL) { 1967 ctxt->nberrors++; 1968 ctxt->err = error; 1969 channel = ctxt->error; 1970 data = ctxt->errCtxt; 1971 schannel = ctxt->serror; 1972 } 1973 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1974 error, XML_ERR_ERROR, NULL, 0, 1975 (const char *) strData1, (const char *) strData2, 1976 (const char *) strData3, 0, 0, msg, str1, str2, 1977 str3, str4, str5); 1978 } 1979 1980 /************************************************************************ 1981 * * 1982 * Allround error functions * 1983 * * 1984 ************************************************************************/ 1985 1986 /** 1987 * xmlSchemaVTypeErrMemory: 1988 * @node: a context node 1989 * @extra: extra informations 1990 * 1991 * Handle an out of memory condition 1992 */ 1993 static void 1994 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1995 const char *extra, xmlNodePtr node) 1996 { 1997 if (ctxt != NULL) { 1998 ctxt->nberrors++; 1999 ctxt->err = XML_SCHEMAV_INTERNAL; 2000 } 2001 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2002 extra); 2003 } 2004 2005 static void LIBXML_ATTR_FORMAT(2,0) 2006 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2007 const char *msg, const xmlChar *str) 2008 { 2009 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2010 msg, (const char *) str); 2011 } 2012 2013 #define WXS_ERROR_TYPE_ERROR 1 2014 #define WXS_ERROR_TYPE_WARNING 2 2015 /** 2016 * xmlSchemaErr4Line: 2017 * @ctxt: the validation context 2018 * @errorLevel: the error level 2019 * @error: the error code 2020 * @node: the context node 2021 * @line: the line number 2022 * @msg: the error message 2023 * @str1: extra data 2024 * @str2: extra data 2025 * @str3: extra data 2026 * @str4: extra data 2027 * 2028 * Handle a validation error 2029 */ 2030 static void LIBXML_ATTR_FORMAT(6,0) 2031 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2032 xmlErrorLevel errorLevel, 2033 int error, xmlNodePtr node, int line, const char *msg, 2034 const xmlChar *str1, const xmlChar *str2, 2035 const xmlChar *str3, const xmlChar *str4) 2036 { 2037 xmlStructuredErrorFunc schannel = NULL; 2038 xmlGenericErrorFunc channel = NULL; 2039 void *data = NULL; 2040 2041 if (ctxt != NULL) { 2042 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2043 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2044 const char *file = NULL; 2045 int col = 0; 2046 if (errorLevel != XML_ERR_WARNING) { 2047 vctxt->nberrors++; 2048 vctxt->err = error; 2049 channel = vctxt->error; 2050 } else { 2051 channel = vctxt->warning; 2052 } 2053 schannel = vctxt->serror; 2054 data = vctxt->errCtxt; 2055 2056 /* 2057 * Error node. If we specify a line number, then 2058 * do not channel any node to the error function. 2059 */ 2060 if (line == 0) { 2061 if ((node == NULL) && 2062 (vctxt->depth >= 0) && 2063 (vctxt->inode != NULL)) { 2064 node = vctxt->inode->node; 2065 } 2066 /* 2067 * Get filename and line if no node-tree. 2068 */ 2069 if ((node == NULL) && 2070 (vctxt->parserCtxt != NULL) && 2071 (vctxt->parserCtxt->input != NULL)) { 2072 file = vctxt->parserCtxt->input->filename; 2073 line = vctxt->parserCtxt->input->line; 2074 col = vctxt->parserCtxt->input->col; 2075 } 2076 } else { 2077 /* 2078 * Override the given node's (if any) position 2079 * and channel only the given line number. 2080 */ 2081 node = NULL; 2082 /* 2083 * Get filename. 2084 */ 2085 if (vctxt->doc != NULL) 2086 file = (const char *) vctxt->doc->URL; 2087 else if ((vctxt->parserCtxt != NULL) && 2088 (vctxt->parserCtxt->input != NULL)) 2089 file = vctxt->parserCtxt->input->filename; 2090 } 2091 if (vctxt->locFunc != NULL) { 2092 if ((file == NULL) || (line == 0)) { 2093 unsigned long l; 2094 const char *f; 2095 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2096 if (file == NULL) 2097 file = f; 2098 if (line == 0) 2099 line = (int) l; 2100 } 2101 } 2102 if ((file == NULL) && (vctxt->filename != NULL)) 2103 file = vctxt->filename; 2104 2105 __xmlRaiseError(schannel, channel, data, ctxt, 2106 node, XML_FROM_SCHEMASV, 2107 error, errorLevel, file, line, 2108 (const char *) str1, (const char *) str2, 2109 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2110 2111 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2112 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2113 if (errorLevel != XML_ERR_WARNING) { 2114 pctxt->nberrors++; 2115 pctxt->err = error; 2116 channel = pctxt->error; 2117 } else { 2118 channel = pctxt->warning; 2119 } 2120 schannel = pctxt->serror; 2121 data = pctxt->errCtxt; 2122 __xmlRaiseError(schannel, channel, data, ctxt, 2123 node, XML_FROM_SCHEMASP, error, 2124 errorLevel, NULL, 0, 2125 (const char *) str1, (const char *) str2, 2126 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2127 } else { 2128 TODO 2129 } 2130 } 2131 } 2132 2133 /** 2134 * xmlSchemaErr3: 2135 * @ctxt: the validation context 2136 * @node: the context node 2137 * @error: the error code 2138 * @msg: the error message 2139 * @str1: extra data 2140 * @str2: extra data 2141 * @str3: extra data 2142 * 2143 * Handle a validation error 2144 */ 2145 static void LIBXML_ATTR_FORMAT(4,0) 2146 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2147 int error, xmlNodePtr node, const char *msg, 2148 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2149 { 2150 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2151 msg, str1, str2, str3, NULL); 2152 } 2153 2154 static void LIBXML_ATTR_FORMAT(4,0) 2155 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2156 int error, xmlNodePtr node, const char *msg, 2157 const xmlChar *str1, const xmlChar *str2, 2158 const xmlChar *str3, const xmlChar *str4) 2159 { 2160 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2161 msg, str1, str2, str3, str4); 2162 } 2163 2164 static void LIBXML_ATTR_FORMAT(4,0) 2165 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2166 int error, xmlNodePtr node, const char *msg, 2167 const xmlChar *str1, const xmlChar *str2) 2168 { 2169 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2170 } 2171 2172 static xmlChar * 2173 xmlSchemaFormatNodeForError(xmlChar ** msg, 2174 xmlSchemaAbstractCtxtPtr actxt, 2175 xmlNodePtr node) 2176 { 2177 xmlChar *str = NULL; 2178 2179 *msg = NULL; 2180 if ((node != NULL) && 2181 (node->type != XML_ELEMENT_NODE) && 2182 (node->type != XML_ATTRIBUTE_NODE)) 2183 { 2184 /* 2185 * Don't try to format other nodes than element and 2186 * attribute nodes. 2187 * Play safe and return an empty string. 2188 */ 2189 *msg = xmlStrdup(BAD_CAST ""); 2190 return(*msg); 2191 } 2192 if (node != NULL) { 2193 /* 2194 * Work on tree nodes. 2195 */ 2196 if (node->type == XML_ATTRIBUTE_NODE) { 2197 xmlNodePtr elem = node->parent; 2198 2199 *msg = xmlStrdup(BAD_CAST "Element '"); 2200 if (elem->ns != NULL) 2201 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2202 elem->ns->href, elem->name)); 2203 else 2204 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2205 NULL, elem->name)); 2206 FREE_AND_NULL(str); 2207 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2208 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2209 } else { 2210 *msg = xmlStrdup(BAD_CAST "Element '"); 2211 } 2212 if (node->ns != NULL) 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 node->ns->href, node->name)); 2215 else 2216 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2217 NULL, node->name)); 2218 FREE_AND_NULL(str); 2219 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2220 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2221 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2222 /* 2223 * Work on node infos. 2224 */ 2225 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2226 xmlSchemaNodeInfoPtr ielem = 2227 vctxt->elemInfos[vctxt->depth]; 2228 2229 *msg = xmlStrdup(BAD_CAST "Element '"); 2230 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2231 ielem->nsName, ielem->localName)); 2232 FREE_AND_NULL(str); 2233 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2234 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2235 } else { 2236 *msg = xmlStrdup(BAD_CAST "Element '"); 2237 } 2238 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2239 vctxt->inode->nsName, vctxt->inode->localName)); 2240 FREE_AND_NULL(str); 2241 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2242 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2243 /* 2244 * Hmm, no node while parsing? 2245 * Return an empty string, in case NULL will break something. 2246 */ 2247 *msg = xmlStrdup(BAD_CAST ""); 2248 } else { 2249 TODO 2250 return (NULL); 2251 } 2252 2253 /* 2254 * xmlSchemaFormatItemForReport() also returns an escaped format 2255 * string, so do this before calling it below (in the future). 2256 */ 2257 xmlEscapeFormatString(msg); 2258 2259 /* 2260 * VAL TODO: The output of the given schema component is currently 2261 * disabled. 2262 */ 2263 #if 0 2264 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2265 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2266 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2267 NULL, type, NULL, 0)); 2268 FREE_AND_NULL(str) 2269 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2270 } 2271 #endif 2272 return (*msg); 2273 } 2274 2275 static void LIBXML_ATTR_FORMAT(3,0) 2276 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2277 const char *funcName, 2278 const char *message, 2279 const xmlChar *str1, 2280 const xmlChar *str2) 2281 { 2282 xmlChar *msg = NULL; 2283 2284 if (actxt == NULL) 2285 return; 2286 msg = xmlStrdup(BAD_CAST "Internal error: %s, "); 2287 msg = xmlStrcat(msg, BAD_CAST message); 2288 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2289 2290 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2291 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, 2292 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2293 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2294 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, 2295 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2296 2297 FREE_AND_NULL(msg) 2298 } 2299 2300 static void LIBXML_ATTR_FORMAT(3,0) 2301 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2302 const char *funcName, 2303 const char *message) 2304 { 2305 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2306 } 2307 2308 #if 0 2309 static void LIBXML_ATTR_FORMAT(3,0) 2310 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2311 const char *funcName, 2312 const char *message, 2313 const xmlChar *str1, 2314 const xmlChar *str2) 2315 { 2316 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2317 str1, str2); 2318 } 2319 #endif 2320 2321 static void LIBXML_ATTR_FORMAT(5,0) 2322 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2323 xmlParserErrors error, 2324 xmlNodePtr node, 2325 xmlSchemaBasicItemPtr item, 2326 const char *message, 2327 const xmlChar *str1, const xmlChar *str2, 2328 const xmlChar *str3, const xmlChar *str4) 2329 { 2330 xmlChar *msg = NULL; 2331 2332 if ((node == NULL) && (item != NULL) && 2333 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2334 node = WXS_ITEM_NODE(item); 2335 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2336 msg = xmlStrcat(msg, BAD_CAST ": "); 2337 } else 2338 xmlSchemaFormatNodeForError(&msg, actxt, node); 2339 msg = xmlStrcat(msg, (const xmlChar *) message); 2340 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2341 xmlSchemaErr4(actxt, error, node, 2342 (const char *) msg, str1, str2, str3, str4); 2343 FREE_AND_NULL(msg) 2344 } 2345 2346 static void LIBXML_ATTR_FORMAT(5,0) 2347 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2348 xmlParserErrors error, 2349 xmlNodePtr node, 2350 xmlSchemaBasicItemPtr item, 2351 const char *message, 2352 const xmlChar *str1, 2353 const xmlChar *str2) 2354 { 2355 xmlSchemaCustomErr4(actxt, error, node, item, 2356 message, str1, str2, NULL, NULL); 2357 } 2358 2359 2360 2361 static void LIBXML_ATTR_FORMAT(5,0) 2362 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2363 xmlParserErrors error, 2364 xmlNodePtr node, 2365 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2366 const char *message, 2367 const xmlChar *str1, 2368 const xmlChar *str2, 2369 const xmlChar *str3) 2370 { 2371 xmlChar *msg = NULL; 2372 2373 xmlSchemaFormatNodeForError(&msg, actxt, node); 2374 msg = xmlStrcat(msg, (const xmlChar *) message); 2375 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2376 2377 /* URGENT TODO: Set the error code to something sane. */ 2378 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2379 (const char *) msg, str1, str2, str3, NULL); 2380 2381 FREE_AND_NULL(msg) 2382 } 2383 2384 2385 2386 static void LIBXML_ATTR_FORMAT(5,0) 2387 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2388 xmlParserErrors error, 2389 xmlSchemaPSVIIDCNodePtr idcNode, 2390 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2391 const char *message, 2392 const xmlChar *str1, 2393 const xmlChar *str2) 2394 { 2395 xmlChar *msg = NULL, *qname = NULL; 2396 2397 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2398 msg = xmlStrcat(msg, (const xmlChar *) message); 2399 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2400 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2401 error, NULL, idcNode->nodeLine, (const char *) msg, 2402 xmlSchemaFormatQName(&qname, 2403 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2404 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2405 str1, str2, NULL); 2406 FREE_AND_NULL(qname); 2407 FREE_AND_NULL(msg); 2408 } 2409 2410 static int 2411 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2412 xmlNodePtr node) 2413 { 2414 if (node != NULL) 2415 return (node->type); 2416 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2417 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2418 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2419 return (-1); 2420 } 2421 2422 static int 2423 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2424 { 2425 switch (item->type) { 2426 case XML_SCHEMA_TYPE_COMPLEX: 2427 case XML_SCHEMA_TYPE_SIMPLE: 2428 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2429 return(1); 2430 break; 2431 case XML_SCHEMA_TYPE_GROUP: 2432 return (1); 2433 case XML_SCHEMA_TYPE_ELEMENT: 2434 if ( ((xmlSchemaElementPtr) item)->flags & 2435 XML_SCHEMAS_ELEM_GLOBAL) 2436 return(1); 2437 break; 2438 case XML_SCHEMA_TYPE_ATTRIBUTE: 2439 if ( ((xmlSchemaAttributePtr) item)->flags & 2440 XML_SCHEMAS_ATTR_GLOBAL) 2441 return(1); 2442 break; 2443 /* Note that attribute groups are always global. */ 2444 default: 2445 return(1); 2446 } 2447 return (0); 2448 } 2449 2450 static void 2451 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2452 xmlParserErrors error, 2453 xmlNodePtr node, 2454 const xmlChar *value, 2455 xmlSchemaTypePtr type, 2456 int displayValue) 2457 { 2458 xmlChar *msg = NULL; 2459 2460 xmlSchemaFormatNodeForError(&msg, actxt, node); 2461 2462 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2463 XML_ATTRIBUTE_NODE)) 2464 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2465 else 2466 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2467 "value of "); 2468 2469 if (! xmlSchemaIsGlobalItem(type)) 2470 msg = xmlStrcat(msg, BAD_CAST "the local "); 2471 else 2472 msg = xmlStrcat(msg, BAD_CAST "the "); 2473 2474 if (WXS_IS_ATOMIC(type)) 2475 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2476 else if (WXS_IS_LIST(type)) 2477 msg = xmlStrcat(msg, BAD_CAST "list type"); 2478 else if (WXS_IS_UNION(type)) 2479 msg = xmlStrcat(msg, BAD_CAST "union type"); 2480 2481 if (xmlSchemaIsGlobalItem(type)) { 2482 xmlChar *str = NULL; 2483 msg = xmlStrcat(msg, BAD_CAST " '"); 2484 if (type->builtInType != 0) { 2485 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2486 str = xmlStrdup(type->name); 2487 } else { 2488 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 2489 if (!str) 2490 str = xmlStrdup(qName); 2491 } 2492 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2493 msg = xmlStrcat(msg, BAD_CAST "'"); 2494 FREE_AND_NULL(str); 2495 } 2496 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2497 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2498 XML_ATTRIBUTE_NODE)) 2499 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2500 else 2501 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2502 FREE_AND_NULL(msg) 2503 } 2504 2505 static const xmlChar * 2506 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2507 xmlSchemaNodeInfoPtr ni, 2508 xmlNodePtr node) 2509 { 2510 if (node != NULL) { 2511 if (node->ns != NULL) 2512 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2513 else 2514 return (xmlSchemaFormatQName(str, NULL, node->name)); 2515 } else if (ni != NULL) 2516 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2517 return (NULL); 2518 } 2519 2520 static void 2521 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2522 xmlParserErrors error, 2523 xmlSchemaAttrInfoPtr ni, 2524 xmlNodePtr node) 2525 { 2526 xmlChar *msg = NULL, *str = NULL; 2527 2528 xmlSchemaFormatNodeForError(&msg, actxt, node); 2529 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2530 xmlSchemaErr(actxt, error, node, (const char *) msg, 2531 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2532 NULL); 2533 FREE_AND_NULL(str) 2534 FREE_AND_NULL(msg) 2535 } 2536 2537 static void LIBXML_ATTR_FORMAT(5,0) 2538 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2539 xmlParserErrors error, 2540 xmlNodePtr node, 2541 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2542 const char *message, 2543 int nbval, 2544 int nbneg, 2545 xmlChar **values) 2546 { 2547 xmlChar *str = NULL, *msg = NULL; 2548 xmlChar *localName, *nsName; 2549 const xmlChar *cur, *end; 2550 int i; 2551 2552 xmlSchemaFormatNodeForError(&msg, actxt, node); 2553 msg = xmlStrcat(msg, (const xmlChar *) message); 2554 msg = xmlStrcat(msg, BAD_CAST "."); 2555 /* 2556 * Note that is does not make sense to report that we have a 2557 * wildcard here, since the wildcard might be unfolded into 2558 * multiple transitions. 2559 */ 2560 if (nbval + nbneg > 0) { 2561 if (nbval + nbneg > 1) { 2562 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2563 } else 2564 str = xmlStrdup(BAD_CAST " Expected is ( "); 2565 nsName = NULL; 2566 2567 for (i = 0; i < nbval + nbneg; i++) { 2568 cur = values[i]; 2569 if (cur == NULL) 2570 continue; 2571 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2572 (cur[3] == ' ')) { 2573 cur += 4; 2574 str = xmlStrcat(str, BAD_CAST "##other"); 2575 } 2576 /* 2577 * Get the local name. 2578 */ 2579 localName = NULL; 2580 2581 end = cur; 2582 if (*end == '*') { 2583 localName = xmlStrdup(BAD_CAST "*"); 2584 end++; 2585 } else { 2586 while ((*end != 0) && (*end != '|')) 2587 end++; 2588 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2589 } 2590 if (*end != 0) { 2591 end++; 2592 /* 2593 * Skip "*|*" if they come with negated expressions, since 2594 * they represent the same negated wildcard. 2595 */ 2596 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2597 /* 2598 * Get the namespace name. 2599 */ 2600 cur = end; 2601 if (*end == '*') { 2602 nsName = xmlStrdup(BAD_CAST "{*}"); 2603 } else { 2604 while (*end != 0) 2605 end++; 2606 2607 if (i >= nbval) 2608 nsName = xmlStrdup(BAD_CAST "{##other:"); 2609 else 2610 nsName = xmlStrdup(BAD_CAST "{"); 2611 2612 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2613 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2614 } 2615 str = xmlStrcat(str, BAD_CAST nsName); 2616 FREE_AND_NULL(nsName) 2617 } else { 2618 FREE_AND_NULL(localName); 2619 continue; 2620 } 2621 } 2622 str = xmlStrcat(str, BAD_CAST localName); 2623 FREE_AND_NULL(localName); 2624 2625 if (i < nbval + nbneg -1) 2626 str = xmlStrcat(str, BAD_CAST ", "); 2627 } 2628 str = xmlStrcat(str, BAD_CAST " ).\n"); 2629 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2630 FREE_AND_NULL(str) 2631 } else 2632 msg = xmlStrcat(msg, BAD_CAST "\n"); 2633 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2634 xmlFree(msg); 2635 } 2636 2637 static void LIBXML_ATTR_FORMAT(8,0) 2638 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2639 xmlParserErrors error, 2640 xmlNodePtr node, 2641 const xmlChar *value, 2642 unsigned long length, 2643 xmlSchemaTypePtr type, 2644 xmlSchemaFacetPtr facet, 2645 const char *message, 2646 const xmlChar *str1, 2647 const xmlChar *str2) 2648 { 2649 xmlChar *str = NULL, *msg = NULL; 2650 xmlSchemaTypeType facetType; 2651 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2652 2653 xmlSchemaFormatNodeForError(&msg, actxt, node); 2654 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2655 facetType = XML_SCHEMA_FACET_ENUMERATION; 2656 /* 2657 * If enumerations are validated, one must not expect the 2658 * facet to be given. 2659 */ 2660 } else 2661 facetType = facet->type; 2662 msg = xmlStrcat(msg, BAD_CAST "["); 2663 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2664 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2665 msg = xmlStrcat(msg, BAD_CAST "'] "); 2666 if (message == NULL) { 2667 /* 2668 * Use a default message. 2669 */ 2670 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2671 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2672 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2673 2674 char len[25], actLen[25]; 2675 2676 /* FIXME, TODO: What is the max expected string length of the 2677 * this value? 2678 */ 2679 if (nodeType == XML_ATTRIBUTE_NODE) 2680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2681 else 2682 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2683 2684 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2685 snprintf(actLen, 24, "%lu", length); 2686 2687 if (facetType == XML_SCHEMA_FACET_LENGTH) 2688 msg = xmlStrcat(msg, 2689 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2690 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2691 msg = xmlStrcat(msg, 2692 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2693 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2694 msg = xmlStrcat(msg, 2695 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2696 2697 if (nodeType == XML_ATTRIBUTE_NODE) 2698 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2699 value, (const xmlChar *) actLen, (const xmlChar *) len); 2700 else 2701 xmlSchemaErr(actxt, error, node, (const char *) msg, 2702 (const xmlChar *) actLen, (const xmlChar *) len); 2703 2704 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2706 "of the set {%s}.\n"); 2707 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2708 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2709 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2711 "by the pattern '%s'.\n"); 2712 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2713 facet->value); 2714 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2716 "minimum value allowed ('%s').\n"); 2717 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2718 facet->value); 2719 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2720 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2721 "maximum value allowed ('%s').\n"); 2722 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2723 facet->value); 2724 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2725 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2726 "'%s'.\n"); 2727 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2728 facet->value); 2729 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2730 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2731 "'%s'.\n"); 2732 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2733 facet->value); 2734 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2735 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2736 "digits than are allowed ('%s').\n"); 2737 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2738 facet->value); 2739 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2740 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2741 "digits than are allowed ('%s').\n"); 2742 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2743 facet->value); 2744 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2745 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2746 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2747 } else { 2748 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2749 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2750 } 2751 } else { 2752 msg = xmlStrcat(msg, (const xmlChar *) message); 2753 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2754 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2755 } 2756 FREE_AND_NULL(str) 2757 xmlFree(msg); 2758 } 2759 2760 #define VERROR(err, type, msg) \ 2761 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2762 2763 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2764 2765 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2766 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2767 2768 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2769 2770 2771 /** 2772 * xmlSchemaPMissingAttrErr: 2773 * @ctxt: the schema validation context 2774 * @ownerDes: the designation of the owner 2775 * @ownerName: the name of the owner 2776 * @ownerItem: the owner as a schema object 2777 * @ownerElem: the owner as an element node 2778 * @node: the parent element node of the missing attribute node 2779 * @type: the corresponding type of the attribute node 2780 * 2781 * Reports an illegal attribute. 2782 */ 2783 static void 2784 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2785 xmlParserErrors error, 2786 xmlSchemaBasicItemPtr ownerItem, 2787 xmlNodePtr ownerElem, 2788 const char *name, 2789 const char *message) 2790 { 2791 xmlChar *des = NULL; 2792 2793 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2794 2795 if (message != NULL) 2796 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2797 else 2798 xmlSchemaPErr(ctxt, ownerElem, error, 2799 "%s: The attribute '%s' is required but missing.\n", 2800 BAD_CAST des, BAD_CAST name); 2801 FREE_AND_NULL(des); 2802 } 2803 2804 2805 /** 2806 * xmlSchemaPResCompAttrErr: 2807 * @ctxt: the schema validation context 2808 * @error: the error code 2809 * @ownerDes: the designation of the owner 2810 * @ownerItem: the owner as a schema object 2811 * @ownerElem: the owner as an element node 2812 * @name: the name of the attribute holding the QName 2813 * @refName: the referenced local name 2814 * @refURI: the referenced namespace URI 2815 * @message: optional message 2816 * 2817 * Used to report QName attribute values that failed to resolve 2818 * to schema components. 2819 */ 2820 static void 2821 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2822 xmlParserErrors error, 2823 xmlSchemaBasicItemPtr ownerItem, 2824 xmlNodePtr ownerElem, 2825 const char *name, 2826 const xmlChar *refName, 2827 const xmlChar *refURI, 2828 xmlSchemaTypeType refType, 2829 const char *refTypeStr) 2830 { 2831 xmlChar *des = NULL, *strA = NULL; 2832 2833 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2834 if (refTypeStr == NULL) 2835 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2836 xmlSchemaPErrExt(ctxt, ownerElem, error, 2837 NULL, NULL, NULL, 2838 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2839 "%s.\n", BAD_CAST des, BAD_CAST name, 2840 xmlSchemaFormatQName(&strA, refURI, refName), 2841 BAD_CAST refTypeStr, NULL); 2842 FREE_AND_NULL(des) 2843 FREE_AND_NULL(strA) 2844 } 2845 2846 /** 2847 * xmlSchemaPCustomAttrErr: 2848 * @ctxt: the schema parser context 2849 * @error: the error code 2850 * @ownerDes: the designation of the owner 2851 * @ownerItem: the owner as a schema object 2852 * @attr: the illegal attribute node 2853 * 2854 * Reports an illegal attribute during the parse. 2855 */ 2856 static void 2857 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2858 xmlParserErrors error, 2859 xmlChar **ownerDes, 2860 xmlSchemaBasicItemPtr ownerItem, 2861 xmlAttrPtr attr, 2862 const char *msg) 2863 { 2864 xmlChar *des = NULL; 2865 2866 if (ownerDes == NULL) 2867 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2868 else if (*ownerDes == NULL) { 2869 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2870 des = *ownerDes; 2871 } else 2872 des = *ownerDes; 2873 if (attr == NULL) { 2874 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2875 "%s, attribute '%s': %s.\n", 2876 BAD_CAST des, (const xmlChar *) "Unknown", 2877 (const xmlChar *) msg, NULL, NULL); 2878 } else { 2879 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2880 "%s, attribute '%s': %s.\n", 2881 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2882 } 2883 if (ownerDes == NULL) 2884 FREE_AND_NULL(des); 2885 } 2886 2887 /** 2888 * xmlSchemaPIllegalAttrErr: 2889 * @ctxt: the schema parser context 2890 * @error: the error code 2891 * @ownerDes: the designation of the attribute's owner 2892 * @ownerItem: the attribute's owner item 2893 * @attr: the illegal attribute node 2894 * 2895 * Reports an illegal attribute during the parse. 2896 */ 2897 static void 2898 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2899 xmlParserErrors error, 2900 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2901 xmlAttrPtr attr) 2902 { 2903 xmlChar *strA = NULL, *strB = NULL; 2904 2905 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2906 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2907 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2908 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2909 NULL, NULL); 2910 FREE_AND_NULL(strA); 2911 FREE_AND_NULL(strB); 2912 } 2913 2914 /** 2915 * xmlSchemaPCustomErr: 2916 * @ctxt: the schema parser context 2917 * @error: the error code 2918 * @itemDes: the designation of the schema item 2919 * @item: the schema item 2920 * @itemElem: the node of the schema item 2921 * @message: the error message 2922 * @str1: an optional param for the error message 2923 * @str2: an optional param for the error message 2924 * @str3: an optional param for the error message 2925 * 2926 * Reports an error during parsing. 2927 */ 2928 static void LIBXML_ATTR_FORMAT(5,0) 2929 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2930 xmlParserErrors error, 2931 xmlSchemaBasicItemPtr item, 2932 xmlNodePtr itemElem, 2933 const char *message, 2934 const xmlChar *str1, 2935 const xmlChar *str2, 2936 const xmlChar *str3) 2937 { 2938 xmlChar *des = NULL, *msg = NULL; 2939 2940 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2941 msg = xmlStrdup(BAD_CAST "%s: "); 2942 msg = xmlStrcat(msg, (const xmlChar *) message); 2943 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2944 if ((itemElem == NULL) && (item != NULL)) 2945 itemElem = WXS_ITEM_NODE(item); 2946 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2947 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2948 FREE_AND_NULL(des); 2949 FREE_AND_NULL(msg); 2950 } 2951 2952 /** 2953 * xmlSchemaPCustomErr: 2954 * @ctxt: the schema parser context 2955 * @error: the error code 2956 * @itemDes: the designation of the schema item 2957 * @item: the schema item 2958 * @itemElem: the node of the schema item 2959 * @message: the error message 2960 * @str1: the optional param for the error message 2961 * 2962 * Reports an error during parsing. 2963 */ 2964 static void LIBXML_ATTR_FORMAT(5,0) 2965 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2966 xmlParserErrors error, 2967 xmlSchemaBasicItemPtr item, 2968 xmlNodePtr itemElem, 2969 const char *message, 2970 const xmlChar *str1) 2971 { 2972 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2973 str1, NULL, NULL); 2974 } 2975 2976 /** 2977 * xmlSchemaPAttrUseErr: 2978 * @ctxt: the schema parser context 2979 * @error: the error code 2980 * @itemDes: the designation of the schema type 2981 * @item: the schema type 2982 * @itemElem: the node of the schema type 2983 * @attr: the invalid schema attribute 2984 * @message: the error message 2985 * @str1: the optional param for the error message 2986 * 2987 * Reports an attribute use error during parsing. 2988 */ 2989 static void LIBXML_ATTR_FORMAT(6,0) 2990 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2991 xmlParserErrors error, 2992 xmlNodePtr node, 2993 xmlSchemaBasicItemPtr ownerItem, 2994 const xmlSchemaAttributeUsePtr attruse, 2995 const char *message, 2996 const xmlChar *str1, const xmlChar *str2, 2997 const xmlChar *str3,const xmlChar *str4) 2998 { 2999 xmlChar *str = NULL, *msg = NULL; 3000 3001 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 3002 msg = xmlStrcat(msg, BAD_CAST ", "); 3003 msg = xmlStrcat(msg, 3004 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 3005 WXS_BASIC_CAST attruse, NULL)); 3006 FREE_AND_NULL(str); 3007 msg = xmlStrcat(msg, BAD_CAST ": "); 3008 msg = xmlStrcat(msg, (const xmlChar *) message); 3009 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3010 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3011 (const char *) msg, str1, str2, str3, str4); 3012 xmlFree(msg); 3013 } 3014 3015 /** 3016 * xmlSchemaPIllegalFacetAtomicErr: 3017 * @ctxt: the schema parser context 3018 * @error: the error code 3019 * @type: the schema type 3020 * @baseType: the base type of type 3021 * @facet: the illegal facet 3022 * 3023 * Reports an illegal facet for atomic simple types. 3024 */ 3025 static void 3026 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3027 xmlParserErrors error, 3028 xmlSchemaTypePtr type, 3029 xmlSchemaTypePtr baseType, 3030 xmlSchemaFacetPtr facet) 3031 { 3032 xmlChar *des = NULL, *strT = NULL; 3033 3034 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3035 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3036 "%s: The facet '%s' is not allowed on types derived from the " 3037 "type %s.\n", 3038 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3039 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3040 NULL, NULL); 3041 FREE_AND_NULL(des); 3042 FREE_AND_NULL(strT); 3043 } 3044 3045 /** 3046 * xmlSchemaPIllegalFacetListUnionErr: 3047 * @ctxt: the schema parser context 3048 * @error: the error code 3049 * @itemDes: the designation of the schema item involved 3050 * @item: the schema item involved 3051 * @facet: the illegal facet 3052 * 3053 * Reports an illegal facet for <list> and <union>. 3054 */ 3055 static void 3056 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3057 xmlParserErrors error, 3058 xmlSchemaTypePtr type, 3059 xmlSchemaFacetPtr facet) 3060 { 3061 xmlChar *des = NULL; 3062 3063 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3064 type->node); 3065 xmlSchemaPErr(ctxt, type->node, error, 3066 "%s: The facet '%s' is not allowed.\n", 3067 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3068 FREE_AND_NULL(des); 3069 } 3070 3071 /** 3072 * xmlSchemaPMutualExclAttrErr: 3073 * @ctxt: the schema validation context 3074 * @error: the error code 3075 * @elemDes: the designation of the parent element node 3076 * @attr: the bad attribute node 3077 * @type: the corresponding type of the attribute node 3078 * 3079 * Reports an illegal attribute. 3080 */ 3081 static void 3082 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3083 xmlParserErrors error, 3084 xmlSchemaBasicItemPtr ownerItem, 3085 xmlAttrPtr attr, 3086 const char *name1, 3087 const char *name2) 3088 { 3089 xmlChar *des = NULL; 3090 3091 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3092 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3093 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3094 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3095 FREE_AND_NULL(des); 3096 } 3097 3098 /** 3099 * xmlSchemaPSimpleTypeErr: 3100 * @ctxt: the schema validation context 3101 * @error: the error code 3102 * @type: the type specifier 3103 * @ownerDes: the designation of the owner 3104 * @ownerItem: the schema object if existent 3105 * @node: the validated node 3106 * @value: the validated value 3107 * 3108 * Reports a simple type validation error. 3109 * TODO: Should this report the value of an element as well? 3110 */ 3111 static void LIBXML_ATTR_FORMAT(8,0) 3112 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3113 xmlParserErrors error, 3114 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3115 xmlNodePtr node, 3116 xmlSchemaTypePtr type, 3117 const char *expected, 3118 const xmlChar *value, 3119 const char *message, 3120 const xmlChar *str1, 3121 const xmlChar *str2) 3122 { 3123 xmlChar *msg = NULL; 3124 3125 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3126 if (message == NULL) { 3127 /* 3128 * Use default messages. 3129 */ 3130 if (type != NULL) { 3131 if (node->type == XML_ATTRIBUTE_NODE) 3132 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3133 else 3134 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3135 "valid value of "); 3136 if (! xmlSchemaIsGlobalItem(type)) 3137 msg = xmlStrcat(msg, BAD_CAST "the local "); 3138 else 3139 msg = xmlStrcat(msg, BAD_CAST "the "); 3140 3141 if (WXS_IS_ATOMIC(type)) 3142 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3143 else if (WXS_IS_LIST(type)) 3144 msg = xmlStrcat(msg, BAD_CAST "list type"); 3145 else if (WXS_IS_UNION(type)) 3146 msg = xmlStrcat(msg, BAD_CAST "union type"); 3147 3148 if (xmlSchemaIsGlobalItem(type)) { 3149 xmlChar *str = NULL; 3150 msg = xmlStrcat(msg, BAD_CAST " '"); 3151 if (type->builtInType != 0) { 3152 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3153 str = xmlStrdup(type->name); 3154 } else { 3155 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 3156 if (!str) 3157 str = xmlStrdup(qName); 3158 } 3159 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 3160 msg = xmlStrcat(msg, BAD_CAST "'."); 3161 FREE_AND_NULL(str); 3162 } 3163 } else { 3164 if (node->type == XML_ATTRIBUTE_NODE) 3165 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3166 else 3167 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3168 "valid."); 3169 } 3170 if (expected) { 3171 xmlChar *expectedEscaped = xmlCharStrdup(expected); 3172 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3173 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); 3174 FREE_AND_NULL(expectedEscaped); 3175 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3176 } else 3177 msg = xmlStrcat(msg, BAD_CAST "\n"); 3178 if (node->type == XML_ATTRIBUTE_NODE) 3179 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3180 else 3181 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3182 } else { 3183 msg = xmlStrcat(msg, BAD_CAST message); 3184 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3185 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3186 (const char*) msg, str1, str2, NULL, NULL, NULL); 3187 } 3188 /* Cleanup. */ 3189 FREE_AND_NULL(msg) 3190 } 3191 3192 /** 3193 * xmlSchemaPContentErr: 3194 * @ctxt: the schema parser context 3195 * @error: the error code 3196 * @onwerDes: the designation of the holder of the content 3197 * @ownerItem: the owner item of the holder of the content 3198 * @ownerElem: the node of the holder of the content 3199 * @child: the invalid child node 3200 * @message: the optional error message 3201 * @content: the optional string describing the correct content 3202 * 3203 * Reports an error concerning the content of a schema element. 3204 */ 3205 static void 3206 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3207 xmlParserErrors error, 3208 xmlSchemaBasicItemPtr ownerItem, 3209 xmlNodePtr ownerElem, 3210 xmlNodePtr child, 3211 const char *message, 3212 const char *content) 3213 { 3214 xmlChar *des = NULL; 3215 3216 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3217 if (message != NULL) 3218 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3219 "%s: %s.\n", 3220 BAD_CAST des, BAD_CAST message); 3221 else { 3222 if (content != NULL) { 3223 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3224 "%s: The content is not valid. Expected is %s.\n", 3225 BAD_CAST des, BAD_CAST content); 3226 } else { 3227 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3228 "%s: The content is not valid.\n", 3229 BAD_CAST des, NULL); 3230 } 3231 } 3232 FREE_AND_NULL(des) 3233 } 3234 3235 /************************************************************************ 3236 * * 3237 * Streamable error functions * 3238 * * 3239 ************************************************************************/ 3240 3241 3242 3243 3244 /************************************************************************ 3245 * * 3246 * Validation helper functions * 3247 * * 3248 ************************************************************************/ 3249 3250 3251 /************************************************************************ 3252 * * 3253 * Allocation functions * 3254 * * 3255 ************************************************************************/ 3256 3257 /** 3258 * xmlSchemaNewSchemaForParserCtxt: 3259 * @ctxt: a schema validation context 3260 * 3261 * Allocate a new Schema structure. 3262 * 3263 * Returns the newly allocated structure or NULL in case or error 3264 */ 3265 static xmlSchemaPtr 3266 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3267 { 3268 xmlSchemaPtr ret; 3269 3270 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3271 if (ret == NULL) { 3272 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3273 return (NULL); 3274 } 3275 memset(ret, 0, sizeof(xmlSchema)); 3276 ret->dict = ctxt->dict; 3277 xmlDictReference(ret->dict); 3278 3279 return (ret); 3280 } 3281 3282 /** 3283 * xmlSchemaNewFacet: 3284 * 3285 * Allocate a new Facet structure. 3286 * 3287 * Returns the newly allocated structure or NULL in case or error 3288 */ 3289 xmlSchemaFacetPtr 3290 xmlSchemaNewFacet(void) 3291 { 3292 xmlSchemaFacetPtr ret; 3293 3294 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3295 if (ret == NULL) { 3296 return (NULL); 3297 } 3298 memset(ret, 0, sizeof(xmlSchemaFacet)); 3299 3300 return (ret); 3301 } 3302 3303 /** 3304 * xmlSchemaNewAnnot: 3305 * @ctxt: a schema validation context 3306 * @node: a node 3307 * 3308 * Allocate a new annotation structure. 3309 * 3310 * Returns the newly allocated structure or NULL in case or error 3311 */ 3312 static xmlSchemaAnnotPtr 3313 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3314 { 3315 xmlSchemaAnnotPtr ret; 3316 3317 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3318 if (ret == NULL) { 3319 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3320 return (NULL); 3321 } 3322 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3323 ret->content = node; 3324 return (ret); 3325 } 3326 3327 static xmlSchemaItemListPtr 3328 xmlSchemaItemListCreate(void) 3329 { 3330 xmlSchemaItemListPtr ret; 3331 3332 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3333 if (ret == NULL) { 3334 xmlSchemaPErrMemory(NULL, 3335 "allocating an item list structure", NULL); 3336 return (NULL); 3337 } 3338 memset(ret, 0, sizeof(xmlSchemaItemList)); 3339 return (ret); 3340 } 3341 3342 static void 3343 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3344 { 3345 if (list->items != NULL) { 3346 xmlFree(list->items); 3347 list->items = NULL; 3348 } 3349 list->nbItems = 0; 3350 list->sizeItems = 0; 3351 } 3352 3353 static int 3354 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3355 { 3356 if (list->items == NULL) { 3357 list->items = (void **) xmlMalloc( 3358 20 * sizeof(void *)); 3359 if (list->items == NULL) { 3360 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3361 return(-1); 3362 } 3363 list->sizeItems = 20; 3364 } else if (list->sizeItems <= list->nbItems) { 3365 list->sizeItems *= 2; 3366 list->items = (void **) xmlRealloc(list->items, 3367 list->sizeItems * sizeof(void *)); 3368 if (list->items == NULL) { 3369 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3370 list->sizeItems = 0; 3371 return(-1); 3372 } 3373 } 3374 list->items[list->nbItems++] = item; 3375 return(0); 3376 } 3377 3378 static int 3379 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3380 int initialSize, 3381 void *item) 3382 { 3383 if (list->items == NULL) { 3384 if (initialSize <= 0) 3385 initialSize = 1; 3386 list->items = (void **) xmlMalloc( 3387 initialSize * sizeof(void *)); 3388 if (list->items == NULL) { 3389 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3390 return(-1); 3391 } 3392 list->sizeItems = initialSize; 3393 } else if (list->sizeItems <= list->nbItems) { 3394 list->sizeItems *= 2; 3395 list->items = (void **) xmlRealloc(list->items, 3396 list->sizeItems * sizeof(void *)); 3397 if (list->items == NULL) { 3398 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3399 list->sizeItems = 0; 3400 return(-1); 3401 } 3402 } 3403 list->items[list->nbItems++] = item; 3404 return(0); 3405 } 3406 3407 static int 3408 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3409 { 3410 if (list->items == NULL) { 3411 list->items = (void **) xmlMalloc( 3412 20 * sizeof(void *)); 3413 if (list->items == NULL) { 3414 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3415 return(-1); 3416 } 3417 list->sizeItems = 20; 3418 } else if (list->sizeItems <= list->nbItems) { 3419 list->sizeItems *= 2; 3420 list->items = (void **) xmlRealloc(list->items, 3421 list->sizeItems * sizeof(void *)); 3422 if (list->items == NULL) { 3423 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3424 list->sizeItems = 0; 3425 return(-1); 3426 } 3427 } 3428 /* 3429 * Just append if the index is greater/equal than the item count. 3430 */ 3431 if (idx >= list->nbItems) { 3432 list->items[list->nbItems++] = item; 3433 } else { 3434 int i; 3435 for (i = list->nbItems; i > idx; i--) 3436 list->items[i] = list->items[i-1]; 3437 list->items[idx] = item; 3438 list->nbItems++; 3439 } 3440 return(0); 3441 } 3442 3443 #if 0 /* enable if ever needed */ 3444 static int 3445 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3446 int initialSize, 3447 void *item, 3448 int idx) 3449 { 3450 if (list->items == NULL) { 3451 if (initialSize <= 0) 3452 initialSize = 1; 3453 list->items = (void **) xmlMalloc( 3454 initialSize * sizeof(void *)); 3455 if (list->items == NULL) { 3456 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3457 return(-1); 3458 } 3459 list->sizeItems = initialSize; 3460 } else if (list->sizeItems <= list->nbItems) { 3461 list->sizeItems *= 2; 3462 list->items = (void **) xmlRealloc(list->items, 3463 list->sizeItems * sizeof(void *)); 3464 if (list->items == NULL) { 3465 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3466 list->sizeItems = 0; 3467 return(-1); 3468 } 3469 } 3470 /* 3471 * Just append if the index is greater/equal than the item count. 3472 */ 3473 if (idx >= list->nbItems) { 3474 list->items[list->nbItems++] = item; 3475 } else { 3476 int i; 3477 for (i = list->nbItems; i > idx; i--) 3478 list->items[i] = list->items[i-1]; 3479 list->items[idx] = item; 3480 list->nbItems++; 3481 } 3482 return(0); 3483 } 3484 #endif 3485 3486 static int 3487 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3488 { 3489 int i; 3490 if ((list->items == NULL) || (idx >= list->nbItems)) { 3491 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3492 "index error.\n"); 3493 return(-1); 3494 } 3495 3496 if (list->nbItems == 1) { 3497 /* TODO: Really free the list? */ 3498 xmlFree(list->items); 3499 list->items = NULL; 3500 list->nbItems = 0; 3501 list->sizeItems = 0; 3502 } else if (list->nbItems -1 == idx) { 3503 list->nbItems--; 3504 } else { 3505 for (i = idx; i < list->nbItems -1; i++) 3506 list->items[i] = list->items[i+1]; 3507 list->nbItems--; 3508 } 3509 return(0); 3510 } 3511 3512 /** 3513 * xmlSchemaItemListFree: 3514 * @annot: a schema type structure 3515 * 3516 * Deallocate a annotation structure 3517 */ 3518 static void 3519 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3520 { 3521 if (list == NULL) 3522 return; 3523 if (list->items != NULL) 3524 xmlFree(list->items); 3525 xmlFree(list); 3526 } 3527 3528 static void 3529 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3530 { 3531 if (bucket == NULL) 3532 return; 3533 if (bucket->globals != NULL) { 3534 xmlSchemaComponentListFree(bucket->globals); 3535 xmlSchemaItemListFree(bucket->globals); 3536 } 3537 if (bucket->locals != NULL) { 3538 xmlSchemaComponentListFree(bucket->locals); 3539 xmlSchemaItemListFree(bucket->locals); 3540 } 3541 if (bucket->relations != NULL) { 3542 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3543 do { 3544 prev = cur; 3545 cur = cur->next; 3546 xmlFree(prev); 3547 } while (cur != NULL); 3548 } 3549 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3550 xmlFreeDoc(bucket->doc); 3551 } 3552 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3553 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3554 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3555 } 3556 xmlFree(bucket); 3557 } 3558 3559 static xmlSchemaBucketPtr 3560 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3561 int type, const xmlChar *targetNamespace) 3562 { 3563 xmlSchemaBucketPtr ret; 3564 int size; 3565 xmlSchemaPtr mainSchema; 3566 3567 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3568 PERROR_INT("xmlSchemaBucketCreate", 3569 "no main schema on constructor"); 3570 return(NULL); 3571 } 3572 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3573 /* Create the schema bucket. */ 3574 if (WXS_IS_BUCKET_INCREDEF(type)) 3575 size = sizeof(xmlSchemaInclude); 3576 else 3577 size = sizeof(xmlSchemaImport); 3578 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3579 if (ret == NULL) { 3580 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3581 return(NULL); 3582 } 3583 memset(ret, 0, size); 3584 ret->targetNamespace = targetNamespace; 3585 ret->type = type; 3586 ret->globals = xmlSchemaItemListCreate(); 3587 if (ret->globals == NULL) { 3588 xmlFree(ret); 3589 return(NULL); 3590 } 3591 ret->locals = xmlSchemaItemListCreate(); 3592 if (ret->locals == NULL) { 3593 xmlFree(ret); 3594 return(NULL); 3595 } 3596 /* 3597 * The following will assure that only the first bucket is marked as 3598 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3599 * For each following import buckets an xmlSchema will be created. 3600 * An xmlSchema will be created for every distinct targetNamespace. 3601 * We assign the targetNamespace to the schemata here. 3602 */ 3603 if (! WXS_HAS_BUCKETS(pctxt)) { 3604 if (WXS_IS_BUCKET_INCREDEF(type)) { 3605 PERROR_INT("xmlSchemaBucketCreate", 3606 "first bucket but it's an include or redefine"); 3607 xmlSchemaBucketFree(ret); 3608 return(NULL); 3609 } 3610 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3611 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3612 /* Point to the *main* schema. */ 3613 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3614 WXS_IMPBUCKET(ret)->schema = mainSchema; 3615 /* 3616 * Ensure that the main schema gets a targetNamespace. 3617 */ 3618 mainSchema->targetNamespace = targetNamespace; 3619 } else { 3620 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3621 PERROR_INT("xmlSchemaBucketCreate", 3622 "main bucket but it's not the first one"); 3623 xmlSchemaBucketFree(ret); 3624 return(NULL); 3625 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3626 /* 3627 * Create a schema for imports and assign the 3628 * targetNamespace. 3629 */ 3630 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3631 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3632 xmlSchemaBucketFree(ret); 3633 return(NULL); 3634 } 3635 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3636 } 3637 } 3638 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3639 int res; 3640 /* 3641 * Imports go into the "schemasImports" slot of the main *schema*. 3642 * Note that we create an import entry for the main schema as well; i.e., 3643 * even if there's only one schema, we'll get an import. 3644 */ 3645 if (mainSchema->schemasImports == NULL) { 3646 mainSchema->schemasImports = xmlHashCreateDict(5, 3647 WXS_CONSTRUCTOR(pctxt)->dict); 3648 if (mainSchema->schemasImports == NULL) { 3649 xmlSchemaBucketFree(ret); 3650 return(NULL); 3651 } 3652 } 3653 if (targetNamespace == NULL) 3654 res = xmlHashAddEntry(mainSchema->schemasImports, 3655 XML_SCHEMAS_NO_NAMESPACE, ret); 3656 else 3657 res = xmlHashAddEntry(mainSchema->schemasImports, 3658 targetNamespace, ret); 3659 if (res != 0) { 3660 PERROR_INT("xmlSchemaBucketCreate", 3661 "failed to add the schema bucket to the hash"); 3662 xmlSchemaBucketFree(ret); 3663 return(NULL); 3664 } 3665 } else { 3666 /* Set the @ownerImport of an include bucket. */ 3667 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3668 WXS_INCBUCKET(ret)->ownerImport = 3669 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3670 else 3671 WXS_INCBUCKET(ret)->ownerImport = 3672 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3673 3674 /* Includes got into the "includes" slot of the *main* schema. */ 3675 if (mainSchema->includes == NULL) { 3676 mainSchema->includes = xmlSchemaItemListCreate(); 3677 if (mainSchema->includes == NULL) { 3678 xmlSchemaBucketFree(ret); 3679 return(NULL); 3680 } 3681 } 3682 xmlSchemaItemListAdd(mainSchema->includes, ret); 3683 } 3684 /* 3685 * Add to list of all buckets; this is used for lookup 3686 * during schema construction time only. 3687 */ 3688 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3689 return(NULL); 3690 return(ret); 3691 } 3692 3693 static int 3694 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3695 { 3696 if (*list == NULL) { 3697 *list = xmlSchemaItemListCreate(); 3698 if (*list == NULL) 3699 return(-1); 3700 } 3701 xmlSchemaItemListAddSize(*list, initialSize, item); 3702 return(0); 3703 } 3704 3705 /** 3706 * xmlSchemaFreeAnnot: 3707 * @annot: a schema type structure 3708 * 3709 * Deallocate a annotation structure 3710 */ 3711 static void 3712 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3713 { 3714 if (annot == NULL) 3715 return; 3716 if (annot->next == NULL) { 3717 xmlFree(annot); 3718 } else { 3719 xmlSchemaAnnotPtr prev; 3720 3721 do { 3722 prev = annot; 3723 annot = annot->next; 3724 xmlFree(prev); 3725 } while (annot != NULL); 3726 } 3727 } 3728 3729 /** 3730 * xmlSchemaFreeNotation: 3731 * @schema: a schema notation structure 3732 * 3733 * Deallocate a Schema Notation structure. 3734 */ 3735 static void 3736 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3737 { 3738 if (nota == NULL) 3739 return; 3740 xmlFree(nota); 3741 } 3742 3743 /** 3744 * xmlSchemaFreeAttribute: 3745 * @attr: an attribute declaration 3746 * 3747 * Deallocates an attribute declaration structure. 3748 */ 3749 static void 3750 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3751 { 3752 if (attr == NULL) 3753 return; 3754 if (attr->annot != NULL) 3755 xmlSchemaFreeAnnot(attr->annot); 3756 if (attr->defVal != NULL) 3757 xmlSchemaFreeValue(attr->defVal); 3758 xmlFree(attr); 3759 } 3760 3761 /** 3762 * xmlSchemaFreeAttributeUse: 3763 * @use: an attribute use 3764 * 3765 * Deallocates an attribute use structure. 3766 */ 3767 static void 3768 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3769 { 3770 if (use == NULL) 3771 return; 3772 if (use->annot != NULL) 3773 xmlSchemaFreeAnnot(use->annot); 3774 if (use->defVal != NULL) 3775 xmlSchemaFreeValue(use->defVal); 3776 xmlFree(use); 3777 } 3778 3779 /** 3780 * xmlSchemaFreeAttributeUseProhib: 3781 * @prohib: an attribute use prohibition 3782 * 3783 * Deallocates an attribute use structure. 3784 */ 3785 static void 3786 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3787 { 3788 if (prohib == NULL) 3789 return; 3790 xmlFree(prohib); 3791 } 3792 3793 /** 3794 * xmlSchemaFreeWildcardNsSet: 3795 * set: a schema wildcard namespace 3796 * 3797 * Deallocates a list of wildcard constraint structures. 3798 */ 3799 static void 3800 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3801 { 3802 xmlSchemaWildcardNsPtr next; 3803 3804 while (set != NULL) { 3805 next = set->next; 3806 xmlFree(set); 3807 set = next; 3808 } 3809 } 3810 3811 /** 3812 * xmlSchemaFreeWildcard: 3813 * @wildcard: a wildcard structure 3814 * 3815 * Deallocates a wildcard structure. 3816 */ 3817 void 3818 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3819 { 3820 if (wildcard == NULL) 3821 return; 3822 if (wildcard->annot != NULL) 3823 xmlSchemaFreeAnnot(wildcard->annot); 3824 if (wildcard->nsSet != NULL) 3825 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3826 if (wildcard->negNsSet != NULL) 3827 xmlFree(wildcard->negNsSet); 3828 xmlFree(wildcard); 3829 } 3830 3831 /** 3832 * xmlSchemaFreeAttributeGroup: 3833 * @schema: a schema attribute group structure 3834 * 3835 * Deallocate a Schema Attribute Group structure. 3836 */ 3837 static void 3838 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3839 { 3840 if (attrGr == NULL) 3841 return; 3842 if (attrGr->annot != NULL) 3843 xmlSchemaFreeAnnot(attrGr->annot); 3844 if (attrGr->attrUses != NULL) 3845 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3846 xmlFree(attrGr); 3847 } 3848 3849 /** 3850 * xmlSchemaFreeQNameRef: 3851 * @item: a QName reference structure 3852 * 3853 * Deallocatea a QName reference structure. 3854 */ 3855 static void 3856 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3857 { 3858 xmlFree(item); 3859 } 3860 3861 /** 3862 * xmlSchemaFreeTypeLinkList: 3863 * @alink: a type link 3864 * 3865 * Deallocate a list of types. 3866 */ 3867 static void 3868 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3869 { 3870 xmlSchemaTypeLinkPtr next; 3871 3872 while (link != NULL) { 3873 next = link->next; 3874 xmlFree(link); 3875 link = next; 3876 } 3877 } 3878 3879 static void 3880 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3881 { 3882 xmlSchemaIDCStateObjPtr next; 3883 while (sto != NULL) { 3884 next = sto->next; 3885 if (sto->history != NULL) 3886 xmlFree(sto->history); 3887 if (sto->xpathCtxt != NULL) 3888 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3889 xmlFree(sto); 3890 sto = next; 3891 } 3892 } 3893 3894 /** 3895 * xmlSchemaFreeIDC: 3896 * @idc: a identity-constraint definition 3897 * 3898 * Deallocates an identity-constraint definition. 3899 */ 3900 static void 3901 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3902 { 3903 xmlSchemaIDCSelectPtr cur, prev; 3904 3905 if (idcDef == NULL) 3906 return; 3907 if (idcDef->annot != NULL) 3908 xmlSchemaFreeAnnot(idcDef->annot); 3909 /* Selector */ 3910 if (idcDef->selector != NULL) { 3911 if (idcDef->selector->xpathComp != NULL) 3912 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3913 xmlFree(idcDef->selector); 3914 } 3915 /* Fields */ 3916 if (idcDef->fields != NULL) { 3917 cur = idcDef->fields; 3918 do { 3919 prev = cur; 3920 cur = cur->next; 3921 if (prev->xpathComp != NULL) 3922 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3923 xmlFree(prev); 3924 } while (cur != NULL); 3925 } 3926 xmlFree(idcDef); 3927 } 3928 3929 /** 3930 * xmlSchemaFreeElement: 3931 * @schema: a schema element structure 3932 * 3933 * Deallocate a Schema Element structure. 3934 */ 3935 static void 3936 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3937 { 3938 if (elem == NULL) 3939 return; 3940 if (elem->annot != NULL) 3941 xmlSchemaFreeAnnot(elem->annot); 3942 if (elem->contModel != NULL) 3943 xmlRegFreeRegexp(elem->contModel); 3944 if (elem->defVal != NULL) 3945 xmlSchemaFreeValue(elem->defVal); 3946 xmlFree(elem); 3947 } 3948 3949 /** 3950 * xmlSchemaFreeFacet: 3951 * @facet: a schema facet structure 3952 * 3953 * Deallocate a Schema Facet structure. 3954 */ 3955 void 3956 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3957 { 3958 if (facet == NULL) 3959 return; 3960 if (facet->val != NULL) 3961 xmlSchemaFreeValue(facet->val); 3962 if (facet->regexp != NULL) 3963 xmlRegFreeRegexp(facet->regexp); 3964 if (facet->annot != NULL) 3965 xmlSchemaFreeAnnot(facet->annot); 3966 xmlFree(facet); 3967 } 3968 3969 /** 3970 * xmlSchemaFreeType: 3971 * @type: a schema type structure 3972 * 3973 * Deallocate a Schema Type structure. 3974 */ 3975 void 3976 xmlSchemaFreeType(xmlSchemaTypePtr type) 3977 { 3978 if (type == NULL) 3979 return; 3980 if (type->annot != NULL) 3981 xmlSchemaFreeAnnot(type->annot); 3982 if (type->facets != NULL) { 3983 xmlSchemaFacetPtr facet, next; 3984 3985 facet = type->facets; 3986 while (facet != NULL) { 3987 next = facet->next; 3988 xmlSchemaFreeFacet(facet); 3989 facet = next; 3990 } 3991 } 3992 if (type->attrUses != NULL) 3993 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3994 if (type->memberTypes != NULL) 3995 xmlSchemaFreeTypeLinkList(type->memberTypes); 3996 if (type->facetSet != NULL) { 3997 xmlSchemaFacetLinkPtr next, link; 3998 3999 link = type->facetSet; 4000 do { 4001 next = link->next; 4002 xmlFree(link); 4003 link = next; 4004 } while (link != NULL); 4005 } 4006 if (type->contModel != NULL) 4007 xmlRegFreeRegexp(type->contModel); 4008 xmlFree(type); 4009 } 4010 4011 /** 4012 * xmlSchemaFreeModelGroupDef: 4013 * @item: a schema model group definition 4014 * 4015 * Deallocates a schema model group definition. 4016 */ 4017 static void 4018 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4019 { 4020 if (item->annot != NULL) 4021 xmlSchemaFreeAnnot(item->annot); 4022 xmlFree(item); 4023 } 4024 4025 /** 4026 * xmlSchemaFreeModelGroup: 4027 * @item: a schema model group 4028 * 4029 * Deallocates a schema model group structure. 4030 */ 4031 static void 4032 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4033 { 4034 if (item->annot != NULL) 4035 xmlSchemaFreeAnnot(item->annot); 4036 xmlFree(item); 4037 } 4038 4039 static void 4040 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4041 { 4042 if ((list == NULL) || (list->nbItems == 0)) 4043 return; 4044 { 4045 xmlSchemaTreeItemPtr item; 4046 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4047 int i; 4048 4049 for (i = 0; i < list->nbItems; i++) { 4050 item = items[i]; 4051 if (item == NULL) 4052 continue; 4053 switch (item->type) { 4054 case XML_SCHEMA_TYPE_SIMPLE: 4055 case XML_SCHEMA_TYPE_COMPLEX: 4056 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4057 break; 4058 case XML_SCHEMA_TYPE_ATTRIBUTE: 4059 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4060 break; 4061 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4062 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4063 break; 4064 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4065 xmlSchemaFreeAttributeUseProhib( 4066 (xmlSchemaAttributeUseProhibPtr) item); 4067 break; 4068 case XML_SCHEMA_TYPE_ELEMENT: 4069 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4070 break; 4071 case XML_SCHEMA_TYPE_PARTICLE: 4072 if (item->annot != NULL) 4073 xmlSchemaFreeAnnot(item->annot); 4074 xmlFree(item); 4075 break; 4076 case XML_SCHEMA_TYPE_SEQUENCE: 4077 case XML_SCHEMA_TYPE_CHOICE: 4078 case XML_SCHEMA_TYPE_ALL: 4079 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4080 break; 4081 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4082 xmlSchemaFreeAttributeGroup( 4083 (xmlSchemaAttributeGroupPtr) item); 4084 break; 4085 case XML_SCHEMA_TYPE_GROUP: 4086 xmlSchemaFreeModelGroupDef( 4087 (xmlSchemaModelGroupDefPtr) item); 4088 break; 4089 case XML_SCHEMA_TYPE_ANY: 4090 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4091 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4092 break; 4093 case XML_SCHEMA_TYPE_IDC_KEY: 4094 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4095 case XML_SCHEMA_TYPE_IDC_KEYREF: 4096 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4097 break; 4098 case XML_SCHEMA_TYPE_NOTATION: 4099 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4100 break; 4101 case XML_SCHEMA_EXTRA_QNAMEREF: 4102 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4103 break; 4104 default: { 4105 /* TODO: This should never be hit. */ 4106 xmlSchemaPSimpleInternalErr(NULL, 4107 "Internal error: xmlSchemaComponentListFree, " 4108 "unexpected component type '%s'\n", 4109 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4110 } 4111 break; 4112 } 4113 } 4114 list->nbItems = 0; 4115 } 4116 } 4117 4118 /** 4119 * xmlSchemaFree: 4120 * @schema: a schema structure 4121 * 4122 * Deallocate a Schema structure. 4123 */ 4124 void 4125 xmlSchemaFree(xmlSchemaPtr schema) 4126 { 4127 if (schema == NULL) 4128 return; 4129 /* @volatiles is not used anymore :-/ */ 4130 if (schema->volatiles != NULL) 4131 TODO 4132 /* 4133 * Note that those slots are not responsible for freeing 4134 * schema components anymore; this will now be done by 4135 * the schema buckets. 4136 */ 4137 if (schema->notaDecl != NULL) 4138 xmlHashFree(schema->notaDecl, NULL); 4139 if (schema->attrDecl != NULL) 4140 xmlHashFree(schema->attrDecl, NULL); 4141 if (schema->attrgrpDecl != NULL) 4142 xmlHashFree(schema->attrgrpDecl, NULL); 4143 if (schema->elemDecl != NULL) 4144 xmlHashFree(schema->elemDecl, NULL); 4145 if (schema->typeDecl != NULL) 4146 xmlHashFree(schema->typeDecl, NULL); 4147 if (schema->groupDecl != NULL) 4148 xmlHashFree(schema->groupDecl, NULL); 4149 if (schema->idcDef != NULL) 4150 xmlHashFree(schema->idcDef, NULL); 4151 4152 if (schema->schemasImports != NULL) 4153 xmlHashFree(schema->schemasImports, 4154 (xmlHashDeallocator) xmlSchemaBucketFree); 4155 if (schema->includes != NULL) { 4156 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4157 int i; 4158 for (i = 0; i < list->nbItems; i++) { 4159 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4160 } 4161 xmlSchemaItemListFree(list); 4162 } 4163 if (schema->annot != NULL) 4164 xmlSchemaFreeAnnot(schema->annot); 4165 /* Never free the doc here, since this will be done by the buckets. */ 4166 4167 xmlDictFree(schema->dict); 4168 xmlFree(schema); 4169 } 4170 4171 /************************************************************************ 4172 * * 4173 * Debug functions * 4174 * * 4175 ************************************************************************/ 4176 4177 #ifdef LIBXML_OUTPUT_ENABLED 4178 4179 static void 4180 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4181 4182 /** 4183 * xmlSchemaElementDump: 4184 * @elem: an element 4185 * @output: the file output 4186 * 4187 * Dump the element 4188 */ 4189 static void 4190 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4191 const xmlChar * name ATTRIBUTE_UNUSED, 4192 const xmlChar * namespace ATTRIBUTE_UNUSED, 4193 const xmlChar * context ATTRIBUTE_UNUSED) 4194 { 4195 if (elem == NULL) 4196 return; 4197 4198 4199 fprintf(output, "Element"); 4200 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4201 fprintf(output, " (global)"); 4202 fprintf(output, ": '%s' ", elem->name); 4203 if (namespace != NULL) 4204 fprintf(output, "ns '%s'", namespace); 4205 fprintf(output, "\n"); 4206 #if 0 4207 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4208 fprintf(output, " min %d ", elem->minOccurs); 4209 if (elem->maxOccurs >= UNBOUNDED) 4210 fprintf(output, "max: unbounded\n"); 4211 else if (elem->maxOccurs != 1) 4212 fprintf(output, "max: %d\n", elem->maxOccurs); 4213 else 4214 fprintf(output, "\n"); 4215 } 4216 #endif 4217 /* 4218 * Misc other properties. 4219 */ 4220 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4221 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4222 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4223 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4224 fprintf(output, " props: "); 4225 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4226 fprintf(output, "[fixed] "); 4227 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4228 fprintf(output, "[default] "); 4229 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4230 fprintf(output, "[abstract] "); 4231 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4232 fprintf(output, "[nillable] "); 4233 fprintf(output, "\n"); 4234 } 4235 /* 4236 * Default/fixed value. 4237 */ 4238 if (elem->value != NULL) 4239 fprintf(output, " value: '%s'\n", elem->value); 4240 /* 4241 * Type. 4242 */ 4243 if (elem->namedType != NULL) { 4244 fprintf(output, " type: '%s' ", elem->namedType); 4245 if (elem->namedTypeNs != NULL) 4246 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4247 else 4248 fprintf(output, "\n"); 4249 } else if (elem->subtypes != NULL) { 4250 /* 4251 * Dump local types. 4252 */ 4253 xmlSchemaTypeDump(elem->subtypes, output); 4254 } 4255 /* 4256 * Substitution group. 4257 */ 4258 if (elem->substGroup != NULL) { 4259 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4260 if (elem->substGroupNs != NULL) 4261 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4262 else 4263 fprintf(output, "\n"); 4264 } 4265 } 4266 4267 /** 4268 * xmlSchemaAnnotDump: 4269 * @output: the file output 4270 * @annot: a annotation 4271 * 4272 * Dump the annotation 4273 */ 4274 static void 4275 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4276 { 4277 xmlChar *content; 4278 4279 if (annot == NULL) 4280 return; 4281 4282 content = xmlNodeGetContent(annot->content); 4283 if (content != NULL) { 4284 fprintf(output, " Annot: %s\n", content); 4285 xmlFree(content); 4286 } else 4287 fprintf(output, " Annot: empty\n"); 4288 } 4289 4290 /** 4291 * xmlSchemaContentModelDump: 4292 * @particle: the schema particle 4293 * @output: the file output 4294 * @depth: the depth used for intentation 4295 * 4296 * Dump a SchemaType structure 4297 */ 4298 static void 4299 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4300 { 4301 xmlChar *str = NULL; 4302 xmlSchemaTreeItemPtr term; 4303 char shift[100]; 4304 int i; 4305 4306 if (particle == NULL) 4307 return; 4308 for (i = 0;((i < depth) && (i < 25));i++) 4309 shift[2 * i] = shift[2 * i + 1] = ' '; 4310 shift[2 * i] = shift[2 * i + 1] = 0; 4311 fprintf(output, "%s", shift); 4312 if (particle->children == NULL) { 4313 fprintf(output, "MISSING particle term\n"); 4314 return; 4315 } 4316 term = particle->children; 4317 if (term == NULL) { 4318 fprintf(output, "(NULL)"); 4319 } else { 4320 switch (term->type) { 4321 case XML_SCHEMA_TYPE_ELEMENT: 4322 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4323 ((xmlSchemaElementPtr)term)->targetNamespace, 4324 ((xmlSchemaElementPtr)term)->name)); 4325 FREE_AND_NULL(str); 4326 break; 4327 case XML_SCHEMA_TYPE_SEQUENCE: 4328 fprintf(output, "SEQUENCE"); 4329 break; 4330 case XML_SCHEMA_TYPE_CHOICE: 4331 fprintf(output, "CHOICE"); 4332 break; 4333 case XML_SCHEMA_TYPE_ALL: 4334 fprintf(output, "ALL"); 4335 break; 4336 case XML_SCHEMA_TYPE_ANY: 4337 fprintf(output, "ANY"); 4338 break; 4339 default: 4340 fprintf(output, "UNKNOWN\n"); 4341 return; 4342 } 4343 } 4344 if (particle->minOccurs != 1) 4345 fprintf(output, " min: %d", particle->minOccurs); 4346 if (particle->maxOccurs >= UNBOUNDED) 4347 fprintf(output, " max: unbounded"); 4348 else if (particle->maxOccurs != 1) 4349 fprintf(output, " max: %d", particle->maxOccurs); 4350 fprintf(output, "\n"); 4351 if (term && 4352 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4353 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4354 (term->type == XML_SCHEMA_TYPE_ALL)) && 4355 (term->children != NULL)) { 4356 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4357 output, depth +1); 4358 } 4359 if (particle->next != NULL) 4360 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4361 output, depth); 4362 } 4363 4364 /** 4365 * xmlSchemaAttrUsesDump: 4366 * @uses: attribute uses list 4367 * @output: the file output 4368 * 4369 * Dumps a list of attribute use components. 4370 */ 4371 static void 4372 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4373 { 4374 xmlSchemaAttributeUsePtr use; 4375 xmlSchemaAttributeUseProhibPtr prohib; 4376 xmlSchemaQNameRefPtr ref; 4377 const xmlChar *name, *tns; 4378 xmlChar *str = NULL; 4379 int i; 4380 4381 if ((uses == NULL) || (uses->nbItems == 0)) 4382 return; 4383 4384 fprintf(output, " attributes:\n"); 4385 for (i = 0; i < uses->nbItems; i++) { 4386 use = uses->items[i]; 4387 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4388 fprintf(output, " [prohibition] "); 4389 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4390 name = prohib->name; 4391 tns = prohib->targetNamespace; 4392 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4393 fprintf(output, " [reference] "); 4394 ref = (xmlSchemaQNameRefPtr) use; 4395 name = ref->name; 4396 tns = ref->targetNamespace; 4397 } else { 4398 fprintf(output, " [use] "); 4399 name = WXS_ATTRUSE_DECL_NAME(use); 4400 tns = WXS_ATTRUSE_DECL_TNS(use); 4401 } 4402 fprintf(output, "'%s'\n", 4403 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4404 FREE_AND_NULL(str); 4405 } 4406 } 4407 4408 /** 4409 * xmlSchemaTypeDump: 4410 * @output: the file output 4411 * @type: a type structure 4412 * 4413 * Dump a SchemaType structure 4414 */ 4415 static void 4416 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4417 { 4418 if (type == NULL) { 4419 fprintf(output, "Type: NULL\n"); 4420 return; 4421 } 4422 fprintf(output, "Type: "); 4423 if (type->name != NULL) 4424 fprintf(output, "'%s' ", type->name); 4425 else 4426 fprintf(output, "(no name) "); 4427 if (type->targetNamespace != NULL) 4428 fprintf(output, "ns '%s' ", type->targetNamespace); 4429 switch (type->type) { 4430 case XML_SCHEMA_TYPE_BASIC: 4431 fprintf(output, "[basic] "); 4432 break; 4433 case XML_SCHEMA_TYPE_SIMPLE: 4434 fprintf(output, "[simple] "); 4435 break; 4436 case XML_SCHEMA_TYPE_COMPLEX: 4437 fprintf(output, "[complex] "); 4438 break; 4439 case XML_SCHEMA_TYPE_SEQUENCE: 4440 fprintf(output, "[sequence] "); 4441 break; 4442 case XML_SCHEMA_TYPE_CHOICE: 4443 fprintf(output, "[choice] "); 4444 break; 4445 case XML_SCHEMA_TYPE_ALL: 4446 fprintf(output, "[all] "); 4447 break; 4448 case XML_SCHEMA_TYPE_UR: 4449 fprintf(output, "[ur] "); 4450 break; 4451 case XML_SCHEMA_TYPE_RESTRICTION: 4452 fprintf(output, "[restriction] "); 4453 break; 4454 case XML_SCHEMA_TYPE_EXTENSION: 4455 fprintf(output, "[extension] "); 4456 break; 4457 default: 4458 fprintf(output, "[unknown type %d] ", type->type); 4459 break; 4460 } 4461 fprintf(output, "content: "); 4462 switch (type->contentType) { 4463 case XML_SCHEMA_CONTENT_UNKNOWN: 4464 fprintf(output, "[unknown] "); 4465 break; 4466 case XML_SCHEMA_CONTENT_EMPTY: 4467 fprintf(output, "[empty] "); 4468 break; 4469 case XML_SCHEMA_CONTENT_ELEMENTS: 4470 fprintf(output, "[element] "); 4471 break; 4472 case XML_SCHEMA_CONTENT_MIXED: 4473 fprintf(output, "[mixed] "); 4474 break; 4475 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4476 /* not used. */ 4477 break; 4478 case XML_SCHEMA_CONTENT_BASIC: 4479 fprintf(output, "[basic] "); 4480 break; 4481 case XML_SCHEMA_CONTENT_SIMPLE: 4482 fprintf(output, "[simple] "); 4483 break; 4484 case XML_SCHEMA_CONTENT_ANY: 4485 fprintf(output, "[any] "); 4486 break; 4487 } 4488 fprintf(output, "\n"); 4489 if (type->base != NULL) { 4490 fprintf(output, " base type: '%s'", type->base); 4491 if (type->baseNs != NULL) 4492 fprintf(output, " ns '%s'\n", type->baseNs); 4493 else 4494 fprintf(output, "\n"); 4495 } 4496 if (type->attrUses != NULL) 4497 xmlSchemaAttrUsesDump(type->attrUses, output); 4498 if (type->annot != NULL) 4499 xmlSchemaAnnotDump(output, type->annot); 4500 #ifdef DUMP_CONTENT_MODEL 4501 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4502 (type->subtypes != NULL)) { 4503 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4504 output, 1); 4505 } 4506 #endif 4507 } 4508 4509 /** 4510 * xmlSchemaDump: 4511 * @output: the file output 4512 * @schema: a schema structure 4513 * 4514 * Dump a Schema structure. 4515 */ 4516 void 4517 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4518 { 4519 if (output == NULL) 4520 return; 4521 if (schema == NULL) { 4522 fprintf(output, "Schemas: NULL\n"); 4523 return; 4524 } 4525 fprintf(output, "Schemas: "); 4526 if (schema->name != NULL) 4527 fprintf(output, "%s, ", schema->name); 4528 else 4529 fprintf(output, "no name, "); 4530 if (schema->targetNamespace != NULL) 4531 fprintf(output, "%s", (const char *) schema->targetNamespace); 4532 else 4533 fprintf(output, "no target namespace"); 4534 fprintf(output, "\n"); 4535 if (schema->annot != NULL) 4536 xmlSchemaAnnotDump(output, schema->annot); 4537 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4538 output); 4539 xmlHashScanFull(schema->elemDecl, 4540 (xmlHashScannerFull) xmlSchemaElementDump, output); 4541 } 4542 4543 #ifdef DEBUG_IDC_NODE_TABLE 4544 /** 4545 * xmlSchemaDebugDumpIDCTable: 4546 * @vctxt: the WXS validation context 4547 * 4548 * Displays the current IDC table for debug purposes. 4549 */ 4550 static void 4551 xmlSchemaDebugDumpIDCTable(FILE * output, 4552 const xmlChar *namespaceName, 4553 const xmlChar *localName, 4554 xmlSchemaPSVIIDCBindingPtr bind) 4555 { 4556 xmlChar *str = NULL; 4557 const xmlChar *value; 4558 xmlSchemaPSVIIDCNodePtr tab; 4559 xmlSchemaPSVIIDCKeyPtr key; 4560 int i, j, res; 4561 4562 fprintf(output, "IDC: TABLES on '%s'\n", 4563 xmlSchemaFormatQName(&str, namespaceName, localName)); 4564 FREE_AND_NULL(str) 4565 4566 if (bind == NULL) 4567 return; 4568 do { 4569 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4570 xmlSchemaGetComponentQName(&str, 4571 bind->definition), bind->nbNodes); 4572 FREE_AND_NULL(str) 4573 for (i = 0; i < bind->nbNodes; i++) { 4574 tab = bind->nodeTable[i]; 4575 fprintf(output, " ( "); 4576 for (j = 0; j < bind->definition->nbFields; j++) { 4577 key = tab->keys[j]; 4578 if ((key != NULL) && (key->val != NULL)) { 4579 res = xmlSchemaGetCanonValue(key->val, &value); 4580 if (res >= 0) 4581 fprintf(output, "'%s' ", value); 4582 else 4583 fprintf(output, "CANON-VALUE-FAILED "); 4584 if (res == 0) 4585 FREE_AND_NULL(value) 4586 } else if (key != NULL) 4587 fprintf(output, "(no val), "); 4588 else 4589 fprintf(output, "(key missing), "); 4590 } 4591 fprintf(output, ")\n"); 4592 } 4593 if (bind->dupls && bind->dupls->nbItems) { 4594 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4595 for (i = 0; i < bind->dupls->nbItems; i++) { 4596 tab = bind->dupls->items[i]; 4597 fprintf(output, " ( "); 4598 for (j = 0; j < bind->definition->nbFields; j++) { 4599 key = tab->keys[j]; 4600 if ((key != NULL) && (key->val != NULL)) { 4601 res = xmlSchemaGetCanonValue(key->val, &value); 4602 if (res >= 0) 4603 fprintf(output, "'%s' ", value); 4604 else 4605 fprintf(output, "CANON-VALUE-FAILED "); 4606 if (res == 0) 4607 FREE_AND_NULL(value) 4608 } else if (key != NULL) 4609 fprintf(output, "(no val), "); 4610 else 4611 fprintf(output, "(key missing), "); 4612 } 4613 fprintf(output, ")\n"); 4614 } 4615 } 4616 bind = bind->next; 4617 } while (bind != NULL); 4618 } 4619 #endif /* DEBUG_IDC */ 4620 #endif /* LIBXML_OUTPUT_ENABLED */ 4621 4622 /************************************************************************ 4623 * * 4624 * Utilities * 4625 * * 4626 ************************************************************************/ 4627 4628 /** 4629 * xmlSchemaGetPropNode: 4630 * @node: the element node 4631 * @name: the name of the attribute 4632 * 4633 * Seeks an attribute with a name of @name in 4634 * no namespace. 4635 * 4636 * Returns the attribute or NULL if not present. 4637 */ 4638 static xmlAttrPtr 4639 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4640 { 4641 xmlAttrPtr prop; 4642 4643 if ((node == NULL) || (name == NULL)) 4644 return(NULL); 4645 prop = node->properties; 4646 while (prop != NULL) { 4647 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4648 return(prop); 4649 prop = prop->next; 4650 } 4651 return (NULL); 4652 } 4653 4654 /** 4655 * xmlSchemaGetPropNodeNs: 4656 * @node: the element node 4657 * @uri: the uri 4658 * @name: the name of the attribute 4659 * 4660 * Seeks an attribute with a local name of @name and 4661 * a namespace URI of @uri. 4662 * 4663 * Returns the attribute or NULL if not present. 4664 */ 4665 static xmlAttrPtr 4666 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4667 { 4668 xmlAttrPtr prop; 4669 4670 if ((node == NULL) || (name == NULL)) 4671 return(NULL); 4672 prop = node->properties; 4673 while (prop != NULL) { 4674 if ((prop->ns != NULL) && 4675 xmlStrEqual(prop->name, BAD_CAST name) && 4676 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4677 return(prop); 4678 prop = prop->next; 4679 } 4680 return (NULL); 4681 } 4682 4683 static const xmlChar * 4684 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4685 { 4686 xmlChar *val; 4687 const xmlChar *ret; 4688 4689 val = xmlNodeGetContent(node); 4690 if (val == NULL) 4691 val = xmlStrdup((xmlChar *)""); 4692 ret = xmlDictLookup(ctxt->dict, val, -1); 4693 xmlFree(val); 4694 return(ret); 4695 } 4696 4697 static const xmlChar * 4698 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4699 { 4700 return((const xmlChar*) xmlNodeGetContent(node)); 4701 } 4702 4703 /** 4704 * xmlSchemaGetProp: 4705 * @ctxt: the parser context 4706 * @node: the node 4707 * @name: the property name 4708 * 4709 * Read a attribute value and internalize the string 4710 * 4711 * Returns the string or NULL if not present. 4712 */ 4713 static const xmlChar * 4714 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4715 const char *name) 4716 { 4717 xmlChar *val; 4718 const xmlChar *ret; 4719 4720 val = xmlGetNoNsProp(node, BAD_CAST name); 4721 if (val == NULL) 4722 return(NULL); 4723 ret = xmlDictLookup(ctxt->dict, val, -1); 4724 xmlFree(val); 4725 return(ret); 4726 } 4727 4728 /************************************************************************ 4729 * * 4730 * Parsing functions * 4731 * * 4732 ************************************************************************/ 4733 4734 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4735 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4736 ret = xmlHashLookup(schema->slot, name); \ 4737 if (ret != NULL) goto exit; \ 4738 } \ 4739 if (xmlHashSize(schema->schemasImports) > 1) { \ 4740 xmlSchemaImportPtr import; \ 4741 if (nsName == NULL) \ 4742 import = xmlHashLookup(schema->schemasImports, \ 4743 XML_SCHEMAS_NO_NAMESPACE); \ 4744 else \ 4745 import = xmlHashLookup(schema->schemasImports, nsName); \ 4746 if (import == NULL) \ 4747 goto exit; \ 4748 ret = xmlHashLookup(import->schema->slot, name); \ 4749 } 4750 4751 /** 4752 * xmlSchemaGetElem: 4753 * @schema: the schema context 4754 * @name: the element name 4755 * @ns: the element namespace 4756 * 4757 * Lookup a global element declaration in the schema. 4758 * 4759 * Returns the element declaration or NULL if not found. 4760 */ 4761 static xmlSchemaElementPtr 4762 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4763 const xmlChar * nsName) 4764 { 4765 xmlSchemaElementPtr ret = NULL; 4766 4767 if ((name == NULL) || (schema == NULL)) 4768 return(NULL); 4769 if (schema != NULL) { 4770 WXS_FIND_GLOBAL_ITEM(elemDecl) 4771 } 4772 exit: 4773 #ifdef DEBUG 4774 if (ret == NULL) { 4775 if (nsName == NULL) 4776 fprintf(stderr, "Unable to lookup element decl. %s", name); 4777 else 4778 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4779 nsName); 4780 } 4781 #endif 4782 return (ret); 4783 } 4784 4785 /** 4786 * xmlSchemaGetType: 4787 * @schema: the main schema 4788 * @name: the type's name 4789 * nsName: the type's namespace 4790 * 4791 * Lookup a type in the schemas or the predefined types 4792 * 4793 * Returns the group definition or NULL if not found. 4794 */ 4795 static xmlSchemaTypePtr 4796 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4797 const xmlChar * nsName) 4798 { 4799 xmlSchemaTypePtr ret = NULL; 4800 4801 if (name == NULL) 4802 return (NULL); 4803 /* First try the built-in types. */ 4804 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4805 ret = xmlSchemaGetPredefinedType(name, nsName); 4806 if (ret != NULL) 4807 goto exit; 4808 /* 4809 * Note that we try the parsed schemas as well here 4810 * since one might have parsed the S4S, which contain more 4811 * than the built-in types. 4812 * TODO: Can we optimize this? 4813 */ 4814 } 4815 if (schema != NULL) { 4816 WXS_FIND_GLOBAL_ITEM(typeDecl) 4817 } 4818 exit: 4819 4820 #ifdef DEBUG 4821 if (ret == NULL) { 4822 if (nsName == NULL) 4823 fprintf(stderr, "Unable to lookup type %s", name); 4824 else 4825 fprintf(stderr, "Unable to lookup type %s:%s", name, 4826 nsName); 4827 } 4828 #endif 4829 return (ret); 4830 } 4831 4832 /** 4833 * xmlSchemaGetAttributeDecl: 4834 * @schema: the context of the schema 4835 * @name: the name of the attribute 4836 * @ns: the target namespace of the attribute 4837 * 4838 * Lookup a an attribute in the schema or imported schemas 4839 * 4840 * Returns the attribute declaration or NULL if not found. 4841 */ 4842 static xmlSchemaAttributePtr 4843 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4844 const xmlChar * nsName) 4845 { 4846 xmlSchemaAttributePtr ret = NULL; 4847 4848 if ((name == NULL) || (schema == NULL)) 4849 return (NULL); 4850 if (schema != NULL) { 4851 WXS_FIND_GLOBAL_ITEM(attrDecl) 4852 } 4853 exit: 4854 #ifdef DEBUG 4855 if (ret == NULL) { 4856 if (nsName == NULL) 4857 fprintf(stderr, "Unable to lookup attribute %s", name); 4858 else 4859 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4860 nsName); 4861 } 4862 #endif 4863 return (ret); 4864 } 4865 4866 /** 4867 * xmlSchemaGetAttributeGroup: 4868 * @schema: the context of the schema 4869 * @name: the name of the attribute group 4870 * @ns: the target namespace of the attribute group 4871 * 4872 * Lookup a an attribute group in the schema or imported schemas 4873 * 4874 * Returns the attribute group definition or NULL if not found. 4875 */ 4876 static xmlSchemaAttributeGroupPtr 4877 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4878 const xmlChar * nsName) 4879 { 4880 xmlSchemaAttributeGroupPtr ret = NULL; 4881 4882 if ((name == NULL) || (schema == NULL)) 4883 return (NULL); 4884 if (schema != NULL) { 4885 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4886 } 4887 exit: 4888 /* TODO: 4889 if ((ret != NULL) && (ret->redef != NULL)) { 4890 * Return the last redefinition. * 4891 ret = ret->redef; 4892 } 4893 */ 4894 #ifdef DEBUG 4895 if (ret == NULL) { 4896 if (nsName == NULL) 4897 fprintf(stderr, "Unable to lookup attribute group %s", name); 4898 else 4899 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4900 nsName); 4901 } 4902 #endif 4903 return (ret); 4904 } 4905 4906 /** 4907 * xmlSchemaGetGroup: 4908 * @schema: the context of the schema 4909 * @name: the name of the group 4910 * @ns: the target namespace of the group 4911 * 4912 * Lookup a group in the schema or imported schemas 4913 * 4914 * Returns the group definition or NULL if not found. 4915 */ 4916 static xmlSchemaModelGroupDefPtr 4917 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4918 const xmlChar * nsName) 4919 { 4920 xmlSchemaModelGroupDefPtr ret = NULL; 4921 4922 if ((name == NULL) || (schema == NULL)) 4923 return (NULL); 4924 if (schema != NULL) { 4925 WXS_FIND_GLOBAL_ITEM(groupDecl) 4926 } 4927 exit: 4928 4929 #ifdef DEBUG 4930 if (ret == NULL) { 4931 if (nsName == NULL) 4932 fprintf(stderr, "Unable to lookup group %s", name); 4933 else 4934 fprintf(stderr, "Unable to lookup group %s:%s", name, 4935 nsName); 4936 } 4937 #endif 4938 return (ret); 4939 } 4940 4941 static xmlSchemaNotationPtr 4942 xmlSchemaGetNotation(xmlSchemaPtr schema, 4943 const xmlChar *name, 4944 const xmlChar *nsName) 4945 { 4946 xmlSchemaNotationPtr ret = NULL; 4947 4948 if ((name == NULL) || (schema == NULL)) 4949 return (NULL); 4950 if (schema != NULL) { 4951 WXS_FIND_GLOBAL_ITEM(notaDecl) 4952 } 4953 exit: 4954 return (ret); 4955 } 4956 4957 static xmlSchemaIDCPtr 4958 xmlSchemaGetIDC(xmlSchemaPtr schema, 4959 const xmlChar *name, 4960 const xmlChar *nsName) 4961 { 4962 xmlSchemaIDCPtr ret = NULL; 4963 4964 if ((name == NULL) || (schema == NULL)) 4965 return (NULL); 4966 if (schema != NULL) { 4967 WXS_FIND_GLOBAL_ITEM(idcDef) 4968 } 4969 exit: 4970 return (ret); 4971 } 4972 4973 /** 4974 * xmlSchemaGetNamedComponent: 4975 * @schema: the schema 4976 * @name: the name of the group 4977 * @ns: the target namespace of the group 4978 * 4979 * Lookup a group in the schema or imported schemas 4980 * 4981 * Returns the group definition or NULL if not found. 4982 */ 4983 static xmlSchemaBasicItemPtr 4984 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4985 xmlSchemaTypeType itemType, 4986 const xmlChar *name, 4987 const xmlChar *targetNs) 4988 { 4989 switch (itemType) { 4990 case XML_SCHEMA_TYPE_GROUP: 4991 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4992 name, targetNs)); 4993 case XML_SCHEMA_TYPE_ELEMENT: 4994 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4995 name, targetNs)); 4996 default: 4997 TODO 4998 return (NULL); 4999 } 5000 } 5001 5002 /************************************************************************ 5003 * * 5004 * Parsing functions * 5005 * * 5006 ************************************************************************/ 5007 5008 #define IS_BLANK_NODE(n) \ 5009 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 5010 5011 /** 5012 * xmlSchemaIsBlank: 5013 * @str: a string 5014 * @len: the length of the string or -1 5015 * 5016 * Check if a string is ignorable 5017 * 5018 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5019 */ 5020 static int 5021 xmlSchemaIsBlank(xmlChar * str, int len) 5022 { 5023 if (str == NULL) 5024 return (1); 5025 if (len < 0) { 5026 while (*str != 0) { 5027 if (!(IS_BLANK_CH(*str))) 5028 return (0); 5029 str++; 5030 } 5031 } else while ((*str != 0) && (len != 0)) { 5032 if (!(IS_BLANK_CH(*str))) 5033 return (0); 5034 str++; 5035 len--; 5036 } 5037 5038 return (1); 5039 } 5040 5041 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5042 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5043 /* 5044 * xmlSchemaFindRedefCompInGraph: 5045 * ATTENTION TODO: This uses pointer comp. for strings. 5046 */ 5047 static xmlSchemaBasicItemPtr 5048 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5049 xmlSchemaTypeType type, 5050 const xmlChar *name, 5051 const xmlChar *nsName) 5052 { 5053 xmlSchemaBasicItemPtr ret; 5054 int i; 5055 5056 if ((bucket == NULL) || (name == NULL)) 5057 return(NULL); 5058 if ((bucket->globals == NULL) || 5059 (bucket->globals->nbItems == 0)) 5060 goto subschemas; 5061 /* 5062 * Search in global components. 5063 */ 5064 for (i = 0; i < bucket->globals->nbItems; i++) { 5065 ret = bucket->globals->items[i]; 5066 if (ret->type == type) { 5067 switch (type) { 5068 case XML_SCHEMA_TYPE_COMPLEX: 5069 case XML_SCHEMA_TYPE_SIMPLE: 5070 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5071 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5072 nsName)) 5073 { 5074 return(ret); 5075 } 5076 break; 5077 case XML_SCHEMA_TYPE_GROUP: 5078 if ((WXS_COMP_NAME(ret, 5079 xmlSchemaModelGroupDefPtr) == name) && 5080 (WXS_COMP_TNS(ret, 5081 xmlSchemaModelGroupDefPtr) == nsName)) 5082 { 5083 return(ret); 5084 } 5085 break; 5086 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5087 if ((WXS_COMP_NAME(ret, 5088 xmlSchemaAttributeGroupPtr) == name) && 5089 (WXS_COMP_TNS(ret, 5090 xmlSchemaAttributeGroupPtr) == nsName)) 5091 { 5092 return(ret); 5093 } 5094 break; 5095 default: 5096 /* Should not be hit. */ 5097 return(NULL); 5098 } 5099 } 5100 } 5101 subschemas: 5102 /* 5103 * Process imported/included schemas. 5104 */ 5105 if (bucket->relations != NULL) { 5106 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5107 5108 /* 5109 * TODO: Marking the bucket will not avoid multiple searches 5110 * in the same schema, but avoids at least circularity. 5111 */ 5112 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5113 do { 5114 if ((rel->bucket != NULL) && 5115 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5116 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5117 type, name, nsName); 5118 if (ret != NULL) 5119 return(ret); 5120 } 5121 rel = rel->next; 5122 } while (rel != NULL); 5123 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5124 } 5125 return(NULL); 5126 } 5127 5128 /** 5129 * xmlSchemaAddNotation: 5130 * @ctxt: a schema parser context 5131 * @schema: the schema being built 5132 * @name: the item name 5133 * 5134 * Add an XML schema annotation declaration 5135 * *WARNING* this interface is highly subject to change 5136 * 5137 * Returns the new struture or NULL in case of error 5138 */ 5139 static xmlSchemaNotationPtr 5140 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5141 const xmlChar *name, const xmlChar *nsName, 5142 xmlNodePtr node ATTRIBUTE_UNUSED) 5143 { 5144 xmlSchemaNotationPtr ret = NULL; 5145 5146 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5147 return (NULL); 5148 5149 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5150 if (ret == NULL) { 5151 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5152 return (NULL); 5153 } 5154 memset(ret, 0, sizeof(xmlSchemaNotation)); 5155 ret->type = XML_SCHEMA_TYPE_NOTATION; 5156 ret->name = name; 5157 ret->targetNamespace = nsName; 5158 /* TODO: do we need the node to be set? 5159 * ret->node = node;*/ 5160 WXS_ADD_GLOBAL(ctxt, ret); 5161 return (ret); 5162 } 5163 5164 /** 5165 * xmlSchemaAddAttribute: 5166 * @ctxt: a schema parser context 5167 * @schema: the schema being built 5168 * @name: the item name 5169 * @namespace: the namespace 5170 * 5171 * Add an XML schema Attrribute declaration 5172 * *WARNING* this interface is highly subject to change 5173 * 5174 * Returns the new struture or NULL in case of error 5175 */ 5176 static xmlSchemaAttributePtr 5177 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5178 const xmlChar * name, const xmlChar * nsName, 5179 xmlNodePtr node, int topLevel) 5180 { 5181 xmlSchemaAttributePtr ret = NULL; 5182 5183 if ((ctxt == NULL) || (schema == NULL)) 5184 return (NULL); 5185 5186 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5187 if (ret == NULL) { 5188 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5189 return (NULL); 5190 } 5191 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5192 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5193 ret->node = node; 5194 ret->name = name; 5195 ret->targetNamespace = nsName; 5196 5197 if (topLevel) 5198 WXS_ADD_GLOBAL(ctxt, ret); 5199 else 5200 WXS_ADD_LOCAL(ctxt, ret); 5201 WXS_ADD_PENDING(ctxt, ret); 5202 return (ret); 5203 } 5204 5205 /** 5206 * xmlSchemaAddAttributeUse: 5207 * @ctxt: a schema parser context 5208 * @schema: the schema being built 5209 * @name: the item name 5210 * @namespace: the namespace 5211 * 5212 * Add an XML schema Attrribute declaration 5213 * *WARNING* this interface is highly subject to change 5214 * 5215 * Returns the new struture or NULL in case of error 5216 */ 5217 static xmlSchemaAttributeUsePtr 5218 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5219 xmlNodePtr node) 5220 { 5221 xmlSchemaAttributeUsePtr ret = NULL; 5222 5223 if (pctxt == NULL) 5224 return (NULL); 5225 5226 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5227 if (ret == NULL) { 5228 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5229 return (NULL); 5230 } 5231 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5232 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5233 ret->node = node; 5234 5235 WXS_ADD_LOCAL(pctxt, ret); 5236 return (ret); 5237 } 5238 5239 /* 5240 * xmlSchemaAddRedef: 5241 * 5242 * Adds a redefinition information. This is used at a later stage to: 5243 * resolve references to the redefined components and to check constraints. 5244 */ 5245 static xmlSchemaRedefPtr 5246 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5247 xmlSchemaBucketPtr targetBucket, 5248 void *item, 5249 const xmlChar *refName, 5250 const xmlChar *refTargetNs) 5251 { 5252 xmlSchemaRedefPtr ret; 5253 5254 ret = (xmlSchemaRedefPtr) 5255 xmlMalloc(sizeof(xmlSchemaRedef)); 5256 if (ret == NULL) { 5257 xmlSchemaPErrMemory(pctxt, 5258 "allocating redefinition info", NULL); 5259 return (NULL); 5260 } 5261 memset(ret, 0, sizeof(xmlSchemaRedef)); 5262 ret->item = item; 5263 ret->targetBucket = targetBucket; 5264 ret->refName = refName; 5265 ret->refTargetNs = refTargetNs; 5266 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5267 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5268 else 5269 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5270 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5271 5272 return (ret); 5273 } 5274 5275 /** 5276 * xmlSchemaAddAttributeGroupDefinition: 5277 * @ctxt: a schema parser context 5278 * @schema: the schema being built 5279 * @name: the item name 5280 * @nsName: the target namespace 5281 * @node: the corresponding node 5282 * 5283 * Add an XML schema Attrribute Group definition. 5284 * 5285 * Returns the new struture or NULL in case of error 5286 */ 5287 static xmlSchemaAttributeGroupPtr 5288 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5289 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5290 const xmlChar *name, 5291 const xmlChar *nsName, 5292 xmlNodePtr node) 5293 { 5294 xmlSchemaAttributeGroupPtr ret = NULL; 5295 5296 if ((pctxt == NULL) || (name == NULL)) 5297 return (NULL); 5298 5299 ret = (xmlSchemaAttributeGroupPtr) 5300 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5301 if (ret == NULL) { 5302 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5303 return (NULL); 5304 } 5305 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5306 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5307 ret->name = name; 5308 ret->targetNamespace = nsName; 5309 ret->node = node; 5310 5311 /* TODO: Remove the flag. */ 5312 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5313 if (pctxt->isRedefine) { 5314 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5315 ret, name, nsName); 5316 if (pctxt->redef == NULL) { 5317 xmlFree(ret); 5318 return(NULL); 5319 } 5320 pctxt->redefCounter = 0; 5321 } 5322 WXS_ADD_GLOBAL(pctxt, ret); 5323 WXS_ADD_PENDING(pctxt, ret); 5324 return (ret); 5325 } 5326 5327 /** 5328 * xmlSchemaAddElement: 5329 * @ctxt: a schema parser context 5330 * @schema: the schema being built 5331 * @name: the type name 5332 * @namespace: the type namespace 5333 * 5334 * Add an XML schema Element declaration 5335 * *WARNING* this interface is highly subject to change 5336 * 5337 * Returns the new struture or NULL in case of error 5338 */ 5339 static xmlSchemaElementPtr 5340 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5341 const xmlChar * name, const xmlChar * nsName, 5342 xmlNodePtr node, int topLevel) 5343 { 5344 xmlSchemaElementPtr ret = NULL; 5345 5346 if ((ctxt == NULL) || (name == NULL)) 5347 return (NULL); 5348 5349 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5350 if (ret == NULL) { 5351 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5352 return (NULL); 5353 } 5354 memset(ret, 0, sizeof(xmlSchemaElement)); 5355 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5356 ret->name = name; 5357 ret->targetNamespace = nsName; 5358 ret->node = node; 5359 5360 if (topLevel) 5361 WXS_ADD_GLOBAL(ctxt, ret); 5362 else 5363 WXS_ADD_LOCAL(ctxt, ret); 5364 WXS_ADD_PENDING(ctxt, ret); 5365 return (ret); 5366 } 5367 5368 /** 5369 * xmlSchemaAddType: 5370 * @ctxt: a schema parser context 5371 * @schema: the schema being built 5372 * @name: the item name 5373 * @namespace: the namespace 5374 * 5375 * Add an XML schema item 5376 * *WARNING* this interface is highly subject to change 5377 * 5378 * Returns the new struture or NULL in case of error 5379 */ 5380 static xmlSchemaTypePtr 5381 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5382 xmlSchemaTypeType type, 5383 const xmlChar * name, const xmlChar * nsName, 5384 xmlNodePtr node, int topLevel) 5385 { 5386 xmlSchemaTypePtr ret = NULL; 5387 5388 if ((ctxt == NULL) || (schema == NULL)) 5389 return (NULL); 5390 5391 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5392 if (ret == NULL) { 5393 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5394 return (NULL); 5395 } 5396 memset(ret, 0, sizeof(xmlSchemaType)); 5397 ret->type = type; 5398 ret->name = name; 5399 ret->targetNamespace = nsName; 5400 ret->node = node; 5401 if (topLevel) { 5402 if (ctxt->isRedefine) { 5403 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5404 ret, name, nsName); 5405 if (ctxt->redef == NULL) { 5406 xmlFree(ret); 5407 return(NULL); 5408 } 5409 ctxt->redefCounter = 0; 5410 } 5411 WXS_ADD_GLOBAL(ctxt, ret); 5412 } else 5413 WXS_ADD_LOCAL(ctxt, ret); 5414 WXS_ADD_PENDING(ctxt, ret); 5415 return (ret); 5416 } 5417 5418 static xmlSchemaQNameRefPtr 5419 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5420 xmlSchemaTypeType refType, 5421 const xmlChar *refName, 5422 const xmlChar *refNs) 5423 { 5424 xmlSchemaQNameRefPtr ret; 5425 5426 ret = (xmlSchemaQNameRefPtr) 5427 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5428 if (ret == NULL) { 5429 xmlSchemaPErrMemory(pctxt, 5430 "allocating QName reference item", NULL); 5431 return (NULL); 5432 } 5433 ret->node = NULL; 5434 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5435 ret->name = refName; 5436 ret->targetNamespace = refNs; 5437 ret->item = NULL; 5438 ret->itemType = refType; 5439 /* 5440 * Store the reference item in the schema. 5441 */ 5442 WXS_ADD_LOCAL(pctxt, ret); 5443 return (ret); 5444 } 5445 5446 static xmlSchemaAttributeUseProhibPtr 5447 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5448 { 5449 xmlSchemaAttributeUseProhibPtr ret; 5450 5451 ret = (xmlSchemaAttributeUseProhibPtr) 5452 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5453 if (ret == NULL) { 5454 xmlSchemaPErrMemory(pctxt, 5455 "allocating attribute use prohibition", NULL); 5456 return (NULL); 5457 } 5458 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5459 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5460 WXS_ADD_LOCAL(pctxt, ret); 5461 return (ret); 5462 } 5463 5464 5465 /** 5466 * xmlSchemaAddModelGroup: 5467 * @ctxt: a schema parser context 5468 * @schema: the schema being built 5469 * @type: the "compositor" type of the model group 5470 * @node: the node in the schema doc 5471 * 5472 * Adds a schema model group 5473 * *WARNING* this interface is highly subject to change 5474 * 5475 * Returns the new struture or NULL in case of error 5476 */ 5477 static xmlSchemaModelGroupPtr 5478 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5479 xmlSchemaPtr schema, 5480 xmlSchemaTypeType type, 5481 xmlNodePtr node) 5482 { 5483 xmlSchemaModelGroupPtr ret = NULL; 5484 5485 if ((ctxt == NULL) || (schema == NULL)) 5486 return (NULL); 5487 5488 ret = (xmlSchemaModelGroupPtr) 5489 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5490 if (ret == NULL) { 5491 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5492 NULL); 5493 return (NULL); 5494 } 5495 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5496 ret->type = type; 5497 ret->node = node; 5498 WXS_ADD_LOCAL(ctxt, ret); 5499 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5500 (type == XML_SCHEMA_TYPE_CHOICE)) 5501 WXS_ADD_PENDING(ctxt, ret); 5502 return (ret); 5503 } 5504 5505 5506 /** 5507 * xmlSchemaAddParticle: 5508 * @ctxt: a schema parser context 5509 * @schema: the schema being built 5510 * @node: the corresponding node in the schema doc 5511 * @min: the minOccurs 5512 * @max: the maxOccurs 5513 * 5514 * Adds an XML schema particle component. 5515 * *WARNING* this interface is highly subject to change 5516 * 5517 * Returns the new struture or NULL in case of error 5518 */ 5519 static xmlSchemaParticlePtr 5520 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5521 xmlNodePtr node, int min, int max) 5522 { 5523 xmlSchemaParticlePtr ret = NULL; 5524 if (ctxt == NULL) 5525 return (NULL); 5526 5527 #ifdef DEBUG 5528 fprintf(stderr, "Adding particle component\n"); 5529 #endif 5530 ret = (xmlSchemaParticlePtr) 5531 xmlMalloc(sizeof(xmlSchemaParticle)); 5532 if (ret == NULL) { 5533 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5534 NULL); 5535 return (NULL); 5536 } 5537 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5538 ret->annot = NULL; 5539 ret->node = node; 5540 ret->minOccurs = min; 5541 ret->maxOccurs = max; 5542 ret->next = NULL; 5543 ret->children = NULL; 5544 5545 WXS_ADD_LOCAL(ctxt, ret); 5546 /* 5547 * Note that addition to pending components will be done locally 5548 * to the specific parsing function, since the most particles 5549 * need not to be fixed up (i.e. the reference to be resolved). 5550 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5551 */ 5552 return (ret); 5553 } 5554 5555 /** 5556 * xmlSchemaAddModelGroupDefinition: 5557 * @ctxt: a schema validation context 5558 * @schema: the schema being built 5559 * @name: the group name 5560 * 5561 * Add an XML schema Group definition 5562 * 5563 * Returns the new struture or NULL in case of error 5564 */ 5565 static xmlSchemaModelGroupDefPtr 5566 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5567 xmlSchemaPtr schema, 5568 const xmlChar *name, 5569 const xmlChar *nsName, 5570 xmlNodePtr node) 5571 { 5572 xmlSchemaModelGroupDefPtr ret = NULL; 5573 5574 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5575 return (NULL); 5576 5577 ret = (xmlSchemaModelGroupDefPtr) 5578 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5579 if (ret == NULL) { 5580 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5581 return (NULL); 5582 } 5583 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5584 ret->name = name; 5585 ret->type = XML_SCHEMA_TYPE_GROUP; 5586 ret->node = node; 5587 ret->targetNamespace = nsName; 5588 5589 if (ctxt->isRedefine) { 5590 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5591 ret, name, nsName); 5592 if (ctxt->redef == NULL) { 5593 xmlFree(ret); 5594 return(NULL); 5595 } 5596 ctxt->redefCounter = 0; 5597 } 5598 WXS_ADD_GLOBAL(ctxt, ret); 5599 WXS_ADD_PENDING(ctxt, ret); 5600 return (ret); 5601 } 5602 5603 /** 5604 * xmlSchemaNewWildcardNs: 5605 * @ctxt: a schema validation context 5606 * 5607 * Creates a new wildcard namespace constraint. 5608 * 5609 * Returns the new struture or NULL in case of error 5610 */ 5611 static xmlSchemaWildcardNsPtr 5612 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5613 { 5614 xmlSchemaWildcardNsPtr ret; 5615 5616 ret = (xmlSchemaWildcardNsPtr) 5617 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5618 if (ret == NULL) { 5619 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5620 return (NULL); 5621 } 5622 ret->value = NULL; 5623 ret->next = NULL; 5624 return (ret); 5625 } 5626 5627 static xmlSchemaIDCPtr 5628 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5629 const xmlChar *name, const xmlChar *nsName, 5630 int category, xmlNodePtr node) 5631 { 5632 xmlSchemaIDCPtr ret = NULL; 5633 5634 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5635 return (NULL); 5636 5637 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5638 if (ret == NULL) { 5639 xmlSchemaPErrMemory(ctxt, 5640 "allocating an identity-constraint definition", NULL); 5641 return (NULL); 5642 } 5643 memset(ret, 0, sizeof(xmlSchemaIDC)); 5644 /* The target namespace of the parent element declaration. */ 5645 ret->targetNamespace = nsName; 5646 ret->name = name; 5647 ret->type = category; 5648 ret->node = node; 5649 5650 WXS_ADD_GLOBAL(ctxt, ret); 5651 /* 5652 * Only keyrefs need to be fixup up. 5653 */ 5654 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5655 WXS_ADD_PENDING(ctxt, ret); 5656 return (ret); 5657 } 5658 5659 /** 5660 * xmlSchemaAddWildcard: 5661 * @ctxt: a schema validation context 5662 * @schema: a schema 5663 * 5664 * Adds a wildcard. 5665 * It corresponds to a xsd:anyAttribute and xsd:any. 5666 * 5667 * Returns the new struture or NULL in case of error 5668 */ 5669 static xmlSchemaWildcardPtr 5670 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5671 xmlSchemaTypeType type, xmlNodePtr node) 5672 { 5673 xmlSchemaWildcardPtr ret = NULL; 5674 5675 if ((ctxt == NULL) || (schema == NULL)) 5676 return (NULL); 5677 5678 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5679 if (ret == NULL) { 5680 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5681 return (NULL); 5682 } 5683 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5684 ret->type = type; 5685 ret->node = node; 5686 WXS_ADD_LOCAL(ctxt, ret); 5687 return (ret); 5688 } 5689 5690 static void 5691 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5692 { 5693 if (group == NULL) 5694 return; 5695 if (group->members != NULL) 5696 xmlSchemaItemListFree(group->members); 5697 xmlFree(group); 5698 } 5699 5700 static xmlSchemaSubstGroupPtr 5701 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5702 xmlSchemaElementPtr head) 5703 { 5704 xmlSchemaSubstGroupPtr ret; 5705 5706 /* Init subst group hash. */ 5707 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5708 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5709 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5710 return(NULL); 5711 } 5712 /* Create a new substitution group. */ 5713 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5714 if (ret == NULL) { 5715 xmlSchemaPErrMemory(NULL, 5716 "allocating a substitution group container", NULL); 5717 return(NULL); 5718 } 5719 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5720 ret->head = head; 5721 /* Create list of members. */ 5722 ret->members = xmlSchemaItemListCreate(); 5723 if (ret->members == NULL) { 5724 xmlSchemaSubstGroupFree(ret); 5725 return(NULL); 5726 } 5727 /* Add subst group to hash. */ 5728 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5729 head->name, head->targetNamespace, ret) != 0) { 5730 PERROR_INT("xmlSchemaSubstGroupAdd", 5731 "failed to add a new substitution container"); 5732 xmlSchemaSubstGroupFree(ret); 5733 return(NULL); 5734 } 5735 return(ret); 5736 } 5737 5738 static xmlSchemaSubstGroupPtr 5739 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5740 xmlSchemaElementPtr head) 5741 { 5742 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5743 return(NULL); 5744 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5745 head->name, head->targetNamespace)); 5746 5747 } 5748 5749 /** 5750 * xmlSchemaAddElementSubstitutionMember: 5751 * @pctxt: a schema parser context 5752 * @head: the head of the substitution group 5753 * @member: the new member of the substitution group 5754 * 5755 * Allocate a new annotation structure. 5756 * 5757 * Returns the newly allocated structure or NULL in case or error 5758 */ 5759 static int 5760 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5761 xmlSchemaElementPtr head, 5762 xmlSchemaElementPtr member) 5763 { 5764 xmlSchemaSubstGroupPtr substGroup = NULL; 5765 5766 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5767 return (-1); 5768 5769 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5770 if (substGroup == NULL) 5771 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5772 if (substGroup == NULL) 5773 return(-1); 5774 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5775 return(-1); 5776 return(0); 5777 } 5778 5779 /************************************************************************ 5780 * * 5781 * Utilities for parsing * 5782 * * 5783 ************************************************************************/ 5784 5785 /** 5786 * xmlSchemaPValAttrNodeQNameValue: 5787 * @ctxt: a schema parser context 5788 * @schema: the schema context 5789 * @ownerDes: the designation of the parent element 5790 * @ownerItem: the parent as a schema object 5791 * @value: the QName value 5792 * @local: the resulting local part if found, the attribute value otherwise 5793 * @uri: the resulting namespace URI if found 5794 * 5795 * Extracts the local name and the URI of a QName value and validates it. 5796 * This one is intended to be used on attribute values that 5797 * should resolve to schema components. 5798 * 5799 * Returns 0, in case the QName is valid, a positive error code 5800 * if not valid and -1 if an internal error occurs. 5801 */ 5802 static int 5803 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5804 xmlSchemaPtr schema, 5805 xmlSchemaBasicItemPtr ownerItem, 5806 xmlAttrPtr attr, 5807 const xmlChar *value, 5808 const xmlChar **uri, 5809 const xmlChar **local) 5810 { 5811 const xmlChar *pref; 5812 xmlNsPtr ns; 5813 int len, ret; 5814 5815 *uri = NULL; 5816 *local = NULL; 5817 ret = xmlValidateQName(value, 1); 5818 if (ret > 0) { 5819 xmlSchemaPSimpleTypeErr(ctxt, 5820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5821 ownerItem, (xmlNodePtr) attr, 5822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5823 NULL, value, NULL, NULL, NULL); 5824 *local = value; 5825 return (ctxt->err); 5826 } else if (ret < 0) 5827 return (-1); 5828 5829 if (!strchr((char *) value, ':')) { 5830 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5831 if (ns) 5832 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5833 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5834 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5835 * parser context. */ 5836 /* 5837 * This one takes care of included schemas with no 5838 * target namespace. 5839 */ 5840 *uri = ctxt->targetNamespace; 5841 } 5842 *local = xmlDictLookup(ctxt->dict, value, -1); 5843 return (0); 5844 } 5845 /* 5846 * At this point xmlSplitQName3 has to return a local name. 5847 */ 5848 *local = xmlSplitQName3(value, &len); 5849 *local = xmlDictLookup(ctxt->dict, *local, -1); 5850 pref = xmlDictLookup(ctxt->dict, value, len); 5851 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5852 if (ns == NULL) { 5853 xmlSchemaPSimpleTypeErr(ctxt, 5854 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5855 ownerItem, (xmlNodePtr) attr, 5856 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5857 "The value '%s' of simple type 'xs:QName' has no " 5858 "corresponding namespace declaration in scope", value, NULL); 5859 return (ctxt->err); 5860 } else { 5861 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5862 } 5863 return (0); 5864 } 5865 5866 /** 5867 * xmlSchemaPValAttrNodeQName: 5868 * @ctxt: a schema parser context 5869 * @schema: the schema context 5870 * @ownerDes: the designation of the owner element 5871 * @ownerItem: the owner as a schema object 5872 * @attr: the attribute node 5873 * @local: the resulting local part if found, the attribute value otherwise 5874 * @uri: the resulting namespace URI if found 5875 * 5876 * Extracts and validates the QName of an attribute value. 5877 * This one is intended to be used on attribute values that 5878 * should resolve to schema components. 5879 * 5880 * Returns 0, in case the QName is valid, a positive error code 5881 * if not valid and -1 if an internal error occurs. 5882 */ 5883 static int 5884 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5885 xmlSchemaPtr schema, 5886 xmlSchemaBasicItemPtr ownerItem, 5887 xmlAttrPtr attr, 5888 const xmlChar **uri, 5889 const xmlChar **local) 5890 { 5891 const xmlChar *value; 5892 5893 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5894 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5895 ownerItem, attr, value, uri, local)); 5896 } 5897 5898 /** 5899 * xmlSchemaPValAttrQName: 5900 * @ctxt: a schema parser context 5901 * @schema: the schema context 5902 * @ownerDes: the designation of the parent element 5903 * @ownerItem: the owner as a schema object 5904 * @ownerElem: the parent node of the attribute 5905 * @name: the name of the attribute 5906 * @local: the resulting local part if found, the attribute value otherwise 5907 * @uri: the resulting namespace URI if found 5908 * 5909 * Extracts and validates the QName of an attribute value. 5910 * 5911 * Returns 0, in case the QName is valid, a positive error code 5912 * if not valid and -1 if an internal error occurs. 5913 */ 5914 static int 5915 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5916 xmlSchemaPtr schema, 5917 xmlSchemaBasicItemPtr ownerItem, 5918 xmlNodePtr ownerElem, 5919 const char *name, 5920 const xmlChar **uri, 5921 const xmlChar **local) 5922 { 5923 xmlAttrPtr attr; 5924 5925 attr = xmlSchemaGetPropNode(ownerElem, name); 5926 if (attr == NULL) { 5927 *local = NULL; 5928 *uri = NULL; 5929 return (0); 5930 } 5931 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5932 ownerItem, attr, uri, local)); 5933 } 5934 5935 /** 5936 * xmlSchemaPValAttrID: 5937 * @ctxt: a schema parser context 5938 * @schema: the schema context 5939 * @ownerDes: the designation of the parent element 5940 * @ownerItem: the owner as a schema object 5941 * @ownerElem: the parent node of the attribute 5942 * @name: the name of the attribute 5943 * 5944 * Extracts and validates the ID of an attribute value. 5945 * 5946 * Returns 0, in case the ID is valid, a positive error code 5947 * if not valid and -1 if an internal error occurs. 5948 */ 5949 static int 5950 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5951 { 5952 int ret; 5953 const xmlChar *value; 5954 5955 if (attr == NULL) 5956 return(0); 5957 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5958 ret = xmlValidateNCName(value, 1); 5959 if (ret == 0) { 5960 /* 5961 * NOTE: the IDness might have already be declared in the DTD 5962 */ 5963 if (attr->atype != XML_ATTRIBUTE_ID) { 5964 xmlIDPtr res; 5965 xmlChar *strip; 5966 5967 /* 5968 * TODO: Use xmlSchemaStrip here; it's not exported at this 5969 * moment. 5970 */ 5971 strip = xmlSchemaCollapseString(value); 5972 if (strip != NULL) { 5973 xmlFree((xmlChar *) value); 5974 value = strip; 5975 } 5976 res = xmlAddID(NULL, attr->doc, value, attr); 5977 if (res == NULL) { 5978 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5979 xmlSchemaPSimpleTypeErr(ctxt, 5980 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5981 NULL, (xmlNodePtr) attr, 5982 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5983 NULL, NULL, "Duplicate value '%s' of simple " 5984 "type 'xs:ID'", value, NULL); 5985 } else 5986 attr->atype = XML_ATTRIBUTE_ID; 5987 } 5988 } else if (ret > 0) { 5989 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5990 xmlSchemaPSimpleTypeErr(ctxt, 5991 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5992 NULL, (xmlNodePtr) attr, 5993 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5994 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5995 "not a valid 'xs:NCName'", 5996 value, NULL); 5997 } 5998 if (value != NULL) 5999 xmlFree((xmlChar *)value); 6000 6001 return (ret); 6002 } 6003 6004 static int 6005 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 6006 xmlNodePtr ownerElem, 6007 const xmlChar *name) 6008 { 6009 xmlAttrPtr attr; 6010 6011 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 6012 if (attr == NULL) 6013 return(0); 6014 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6015 6016 } 6017 6018 /** 6019 * xmlGetMaxOccurs: 6020 * @ctxt: a schema validation context 6021 * @node: a subtree containing XML Schema informations 6022 * 6023 * Get the maxOccurs property 6024 * 6025 * Returns the default if not found, or the value 6026 */ 6027 static int 6028 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6029 int min, int max, int def, const char *expected) 6030 { 6031 const xmlChar *val, *cur; 6032 int ret = 0; 6033 xmlAttrPtr attr; 6034 6035 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6036 if (attr == NULL) 6037 return (def); 6038 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6039 6040 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6041 if (max != UNBOUNDED) { 6042 xmlSchemaPSimpleTypeErr(ctxt, 6043 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6044 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6045 NULL, (xmlNodePtr) attr, NULL, expected, 6046 val, NULL, NULL, NULL); 6047 return (def); 6048 } else 6049 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6050 } 6051 6052 cur = val; 6053 while (IS_BLANK_CH(*cur)) 6054 cur++; 6055 if (*cur == 0) { 6056 xmlSchemaPSimpleTypeErr(ctxt, 6057 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6058 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6059 NULL, (xmlNodePtr) attr, NULL, expected, 6060 val, NULL, NULL, NULL); 6061 return (def); 6062 } 6063 while ((*cur >= '0') && (*cur <= '9')) { 6064 ret = ret * 10 + (*cur - '0'); 6065 cur++; 6066 } 6067 while (IS_BLANK_CH(*cur)) 6068 cur++; 6069 /* 6070 * TODO: Restrict the maximal value to Integer. 6071 */ 6072 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6073 xmlSchemaPSimpleTypeErr(ctxt, 6074 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6075 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6076 NULL, (xmlNodePtr) attr, NULL, expected, 6077 val, NULL, NULL, NULL); 6078 return (def); 6079 } 6080 return (ret); 6081 } 6082 6083 /** 6084 * xmlGetMinOccurs: 6085 * @ctxt: a schema validation context 6086 * @node: a subtree containing XML Schema informations 6087 * 6088 * Get the minOccurs property 6089 * 6090 * Returns the default if not found, or the value 6091 */ 6092 static int 6093 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6094 int min, int max, int def, const char *expected) 6095 { 6096 const xmlChar *val, *cur; 6097 int ret = 0; 6098 xmlAttrPtr attr; 6099 6100 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6101 if (attr == NULL) 6102 return (def); 6103 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6104 cur = val; 6105 while (IS_BLANK_CH(*cur)) 6106 cur++; 6107 if (*cur == 0) { 6108 xmlSchemaPSimpleTypeErr(ctxt, 6109 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6110 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6111 NULL, (xmlNodePtr) attr, NULL, expected, 6112 val, NULL, NULL, NULL); 6113 return (def); 6114 } 6115 while ((*cur >= '0') && (*cur <= '9')) { 6116 ret = ret * 10 + (*cur - '0'); 6117 cur++; 6118 } 6119 while (IS_BLANK_CH(*cur)) 6120 cur++; 6121 /* 6122 * TODO: Restrict the maximal value to Integer. 6123 */ 6124 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6125 xmlSchemaPSimpleTypeErr(ctxt, 6126 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6127 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6128 NULL, (xmlNodePtr) attr, NULL, expected, 6129 val, NULL, NULL, NULL); 6130 return (def); 6131 } 6132 return (ret); 6133 } 6134 6135 /** 6136 * xmlSchemaPGetBoolNodeValue: 6137 * @ctxt: a schema validation context 6138 * @ownerDes: owner designation 6139 * @ownerItem: the owner as a schema item 6140 * @node: the node holding the value 6141 * 6142 * Converts a boolean string value into 1 or 0. 6143 * 6144 * Returns 0 or 1. 6145 */ 6146 static int 6147 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6148 xmlSchemaBasicItemPtr ownerItem, 6149 xmlNodePtr node) 6150 { 6151 xmlChar *value = NULL; 6152 int res = 0; 6153 6154 value = xmlNodeGetContent(node); 6155 /* 6156 * 3.2.2.1 Lexical representation 6157 * An instance of a datatype that is defined as `boolean` 6158 * can have the following legal literals {true, false, 1, 0}. 6159 */ 6160 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6161 res = 1; 6162 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6163 res = 0; 6164 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6165 res = 1; 6166 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6167 res = 0; 6168 else { 6169 xmlSchemaPSimpleTypeErr(ctxt, 6170 XML_SCHEMAP_INVALID_BOOLEAN, 6171 ownerItem, node, 6172 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6173 NULL, BAD_CAST value, 6174 NULL, NULL, NULL); 6175 } 6176 if (value != NULL) 6177 xmlFree(value); 6178 return (res); 6179 } 6180 6181 /** 6182 * xmlGetBooleanProp: 6183 * @ctxt: a schema validation context 6184 * @node: a subtree containing XML Schema informations 6185 * @name: the attribute name 6186 * @def: the default value 6187 * 6188 * Evaluate if a boolean property is set 6189 * 6190 * Returns the default if not found, 0 if found to be false, 6191 * 1 if found to be true 6192 */ 6193 static int 6194 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6195 xmlNodePtr node, 6196 const char *name, int def) 6197 { 6198 const xmlChar *val; 6199 6200 val = xmlSchemaGetProp(ctxt, node, name); 6201 if (val == NULL) 6202 return (def); 6203 /* 6204 * 3.2.2.1 Lexical representation 6205 * An instance of a datatype that is defined as `boolean` 6206 * can have the following legal literals {true, false, 1, 0}. 6207 */ 6208 if (xmlStrEqual(val, BAD_CAST "true")) 6209 def = 1; 6210 else if (xmlStrEqual(val, BAD_CAST "false")) 6211 def = 0; 6212 else if (xmlStrEqual(val, BAD_CAST "1")) 6213 def = 1; 6214 else if (xmlStrEqual(val, BAD_CAST "0")) 6215 def = 0; 6216 else { 6217 xmlSchemaPSimpleTypeErr(ctxt, 6218 XML_SCHEMAP_INVALID_BOOLEAN, 6219 NULL, 6220 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6221 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6222 NULL, val, NULL, NULL, NULL); 6223 } 6224 return (def); 6225 } 6226 6227 /************************************************************************ 6228 * * 6229 * Shema extraction from an Infoset * 6230 * * 6231 ************************************************************************/ 6232 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6233 ctxt, xmlSchemaPtr schema, 6234 xmlNodePtr node, 6235 int topLevel); 6236 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6237 ctxt, 6238 xmlSchemaPtr schema, 6239 xmlNodePtr node, 6240 int topLevel); 6241 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6242 ctxt, 6243 xmlSchemaPtr schema, 6244 xmlNodePtr node, 6245 xmlSchemaTypeType parentType); 6246 static xmlSchemaBasicItemPtr 6247 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6248 xmlSchemaPtr schema, 6249 xmlNodePtr node, 6250 xmlSchemaItemListPtr uses, 6251 int parentType); 6252 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6253 xmlSchemaPtr schema, 6254 xmlNodePtr node); 6255 static xmlSchemaWildcardPtr 6256 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6257 xmlSchemaPtr schema, xmlNodePtr node); 6258 6259 /** 6260 * xmlSchemaPValAttrNodeValue: 6261 * 6262 * @ctxt: a schema parser context 6263 * @ownerDes: the designation of the parent element 6264 * @ownerItem: the schema object owner if existent 6265 * @attr: the schema attribute node being validated 6266 * @value: the value 6267 * @type: the built-in type to be validated against 6268 * 6269 * Validates a value against the given built-in type. 6270 * This one is intended to be used internally for validation 6271 * of schema attribute values during parsing of the schema. 6272 * 6273 * Returns 0 if the value is valid, a positive error code 6274 * number otherwise and -1 in case of an internal or API error. 6275 */ 6276 static int 6277 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6278 xmlSchemaBasicItemPtr ownerItem, 6279 xmlAttrPtr attr, 6280 const xmlChar *value, 6281 xmlSchemaTypePtr type) 6282 { 6283 6284 int ret = 0; 6285 6286 /* 6287 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6288 * one is really meant to be used internally, so better not. 6289 */ 6290 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6291 return (-1); 6292 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6293 PERROR_INT("xmlSchemaPValAttrNodeValue", 6294 "the given type is not a built-in type"); 6295 return (-1); 6296 } 6297 switch (type->builtInType) { 6298 case XML_SCHEMAS_NCNAME: 6299 case XML_SCHEMAS_QNAME: 6300 case XML_SCHEMAS_ANYURI: 6301 case XML_SCHEMAS_TOKEN: 6302 case XML_SCHEMAS_LANGUAGE: 6303 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6304 (xmlNodePtr) attr); 6305 break; 6306 default: { 6307 PERROR_INT("xmlSchemaPValAttrNodeValue", 6308 "validation using the given type is not supported while " 6309 "parsing a schema"); 6310 return (-1); 6311 } 6312 } 6313 /* 6314 * TODO: Should we use the S4S error codes instead? 6315 */ 6316 if (ret < 0) { 6317 PERROR_INT("xmlSchemaPValAttrNodeValue", 6318 "failed to validate a schema attribute value"); 6319 return (-1); 6320 } else if (ret > 0) { 6321 if (WXS_IS_LIST(type)) 6322 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6323 else 6324 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6325 xmlSchemaPSimpleTypeErr(pctxt, 6326 ret, ownerItem, (xmlNodePtr) attr, 6327 type, NULL, value, NULL, NULL, NULL); 6328 } 6329 return (ret); 6330 } 6331 6332 /** 6333 * xmlSchemaPValAttrNode: 6334 * 6335 * @ctxt: a schema parser context 6336 * @ownerDes: the designation of the parent element 6337 * @ownerItem: the schema object owner if existent 6338 * @attr: the schema attribute node being validated 6339 * @type: the built-in type to be validated against 6340 * @value: the resulting value if any 6341 * 6342 * Extracts and validates a value against the given built-in type. 6343 * This one is intended to be used internally for validation 6344 * of schema attribute values during parsing of the schema. 6345 * 6346 * Returns 0 if the value is valid, a positive error code 6347 * number otherwise and -1 in case of an internal or API error. 6348 */ 6349 static int 6350 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6351 xmlSchemaBasicItemPtr ownerItem, 6352 xmlAttrPtr attr, 6353 xmlSchemaTypePtr type, 6354 const xmlChar **value) 6355 { 6356 const xmlChar *val; 6357 6358 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6359 return (-1); 6360 6361 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6362 if (value != NULL) 6363 *value = val; 6364 6365 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6366 val, type)); 6367 } 6368 6369 /** 6370 * xmlSchemaPValAttr: 6371 * 6372 * @ctxt: a schema parser context 6373 * @node: the element node of the attribute 6374 * @ownerDes: the designation of the parent element 6375 * @ownerItem: the schema object owner if existent 6376 * @ownerElem: the owner element node 6377 * @name: the name of the schema attribute node 6378 * @type: the built-in type to be validated against 6379 * @value: the resulting value if any 6380 * 6381 * Extracts and validates a value against the given built-in type. 6382 * This one is intended to be used internally for validation 6383 * of schema attribute values during parsing of the schema. 6384 * 6385 * Returns 0 if the value is valid, a positive error code 6386 * number otherwise and -1 in case of an internal or API error. 6387 */ 6388 static int 6389 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6390 xmlSchemaBasicItemPtr ownerItem, 6391 xmlNodePtr ownerElem, 6392 const char *name, 6393 xmlSchemaTypePtr type, 6394 const xmlChar **value) 6395 { 6396 xmlAttrPtr attr; 6397 6398 if ((ctxt == NULL) || (type == NULL)) { 6399 if (value != NULL) 6400 *value = NULL; 6401 return (-1); 6402 } 6403 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6404 if (value != NULL) 6405 *value = NULL; 6406 xmlSchemaPErr(ctxt, ownerElem, 6407 XML_SCHEMAP_INTERNAL, 6408 "Internal error: xmlSchemaPValAttr, the given " 6409 "type '%s' is not a built-in type.\n", 6410 type->name, NULL); 6411 return (-1); 6412 } 6413 attr = xmlSchemaGetPropNode(ownerElem, name); 6414 if (attr == NULL) { 6415 if (value != NULL) 6416 *value = NULL; 6417 return (0); 6418 } 6419 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6420 type, value)); 6421 } 6422 6423 static int 6424 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6425 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6426 xmlNodePtr node, 6427 xmlAttrPtr attr, 6428 const xmlChar *namespaceName) 6429 { 6430 /* TODO: Pointer comparison instead? */ 6431 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6432 return (0); 6433 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6434 return (0); 6435 /* 6436 * Check if the referenced namespace was <import>ed. 6437 */ 6438 if (WXS_BUCKET(pctxt)->relations != NULL) { 6439 xmlSchemaSchemaRelationPtr rel; 6440 6441 rel = WXS_BUCKET(pctxt)->relations; 6442 do { 6443 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6444 xmlStrEqual(namespaceName, rel->importNamespace)) 6445 return (0); 6446 rel = rel->next; 6447 } while (rel != NULL); 6448 } 6449 /* 6450 * No matching <import>ed namespace found. 6451 */ 6452 { 6453 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6454 6455 if (namespaceName == NULL) 6456 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6457 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6458 "References from this schema to components in no " 6459 "namespace are not allowed, since not indicated by an " 6460 "import statement", NULL, NULL); 6461 else 6462 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6463 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6464 "References from this schema to components in the " 6465 "namespace '%s' are not allowed, since not indicated by an " 6466 "import statement", namespaceName, NULL); 6467 } 6468 return (XML_SCHEMAP_SRC_RESOLVE); 6469 } 6470 6471 /** 6472 * xmlSchemaParseLocalAttributes: 6473 * @ctxt: a schema validation context 6474 * @schema: the schema being built 6475 * @node: a subtree containing XML Schema informations 6476 * @type: the hosting type where the attributes will be anchored 6477 * 6478 * Parses attribute uses and attribute declarations and 6479 * attribute group references. 6480 */ 6481 static int 6482 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6483 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6484 int parentType, int *hasRefs) 6485 { 6486 void *item; 6487 6488 while ((IS_SCHEMA((*child), "attribute")) || 6489 (IS_SCHEMA((*child), "attributeGroup"))) { 6490 if (IS_SCHEMA((*child), "attribute")) { 6491 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6492 *list, parentType); 6493 } else { 6494 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6495 if ((item != NULL) && (hasRefs != NULL)) 6496 *hasRefs = 1; 6497 } 6498 if (item != NULL) { 6499 if (*list == NULL) { 6500 /* TODO: Customize grow factor. */ 6501 *list = xmlSchemaItemListCreate(); 6502 if (*list == NULL) 6503 return(-1); 6504 } 6505 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6506 return(-1); 6507 } 6508 *child = (*child)->next; 6509 } 6510 return (0); 6511 } 6512 6513 /** 6514 * xmlSchemaParseAnnotation: 6515 * @ctxt: a schema validation context 6516 * @schema: the schema being built 6517 * @node: a subtree containing XML Schema informations 6518 * 6519 * parse a XML schema Attrribute declaration 6520 * *WARNING* this interface is highly subject to change 6521 * 6522 * Returns -1 in case of error, 0 if the declaration is improper and 6523 * 1 in case of success. 6524 */ 6525 static xmlSchemaAnnotPtr 6526 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6527 { 6528 xmlSchemaAnnotPtr ret; 6529 xmlNodePtr child = NULL; 6530 xmlAttrPtr attr; 6531 int barked = 0; 6532 6533 /* 6534 * INFO: S4S completed. 6535 */ 6536 /* 6537 * id = ID 6538 * {any attributes with non-schema namespace . . .}> 6539 * Content: (appinfo | documentation)* 6540 */ 6541 if ((ctxt == NULL) || (node == NULL)) 6542 return (NULL); 6543 if (needed) 6544 ret = xmlSchemaNewAnnot(ctxt, node); 6545 else 6546 ret = NULL; 6547 attr = node->properties; 6548 while (attr != NULL) { 6549 if (((attr->ns == NULL) && 6550 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6551 ((attr->ns != NULL) && 6552 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6553 6554 xmlSchemaPIllegalAttrErr(ctxt, 6555 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6556 } 6557 attr = attr->next; 6558 } 6559 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6560 /* 6561 * And now for the children... 6562 */ 6563 child = node->children; 6564 while (child != NULL) { 6565 if (IS_SCHEMA(child, "appinfo")) { 6566 /* TODO: make available the content of "appinfo". */ 6567 /* 6568 * source = anyURI 6569 * {any attributes with non-schema namespace . . .}> 6570 * Content: ({any})* 6571 */ 6572 attr = child->properties; 6573 while (attr != NULL) { 6574 if (((attr->ns == NULL) && 6575 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6576 ((attr->ns != NULL) && 6577 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6578 6579 xmlSchemaPIllegalAttrErr(ctxt, 6580 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6581 } 6582 attr = attr->next; 6583 } 6584 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6585 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6586 child = child->next; 6587 } else if (IS_SCHEMA(child, "documentation")) { 6588 /* TODO: make available the content of "documentation". */ 6589 /* 6590 * source = anyURI 6591 * {any attributes with non-schema namespace . . .}> 6592 * Content: ({any})* 6593 */ 6594 attr = child->properties; 6595 while (attr != NULL) { 6596 if (attr->ns == NULL) { 6597 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6598 xmlSchemaPIllegalAttrErr(ctxt, 6599 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6600 } 6601 } else { 6602 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6603 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6604 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6605 6606 xmlSchemaPIllegalAttrErr(ctxt, 6607 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6608 } 6609 } 6610 attr = attr->next; 6611 } 6612 /* 6613 * Attribute "xml:lang". 6614 */ 6615 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6616 if (attr != NULL) 6617 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6618 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6619 child = child->next; 6620 } else { 6621 if (!barked) 6622 xmlSchemaPContentErr(ctxt, 6623 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6624 NULL, node, child, NULL, "(appinfo | documentation)*"); 6625 barked = 1; 6626 child = child->next; 6627 } 6628 } 6629 6630 return (ret); 6631 } 6632 6633 /** 6634 * xmlSchemaParseFacet: 6635 * @ctxt: a schema validation context 6636 * @schema: the schema being built 6637 * @node: a subtree containing XML Schema informations 6638 * 6639 * parse a XML schema Facet declaration 6640 * *WARNING* this interface is highly subject to change 6641 * 6642 * Returns the new type structure or NULL in case of error 6643 */ 6644 static xmlSchemaFacetPtr 6645 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6646 xmlNodePtr node) 6647 { 6648 xmlSchemaFacetPtr facet; 6649 xmlNodePtr child = NULL; 6650 const xmlChar *value; 6651 6652 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6653 return (NULL); 6654 6655 facet = xmlSchemaNewFacet(); 6656 if (facet == NULL) { 6657 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6658 return (NULL); 6659 } 6660 facet->node = node; 6661 value = xmlSchemaGetProp(ctxt, node, "value"); 6662 if (value == NULL) { 6663 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6664 "Facet %s has no value\n", node->name, NULL); 6665 xmlSchemaFreeFacet(facet); 6666 return (NULL); 6667 } 6668 if (IS_SCHEMA(node, "minInclusive")) { 6669 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6670 } else if (IS_SCHEMA(node, "minExclusive")) { 6671 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6672 } else if (IS_SCHEMA(node, "maxInclusive")) { 6673 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6674 } else if (IS_SCHEMA(node, "maxExclusive")) { 6675 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6676 } else if (IS_SCHEMA(node, "totalDigits")) { 6677 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6678 } else if (IS_SCHEMA(node, "fractionDigits")) { 6679 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6680 } else if (IS_SCHEMA(node, "pattern")) { 6681 facet->type = XML_SCHEMA_FACET_PATTERN; 6682 } else if (IS_SCHEMA(node, "enumeration")) { 6683 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6684 } else if (IS_SCHEMA(node, "whiteSpace")) { 6685 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6686 } else if (IS_SCHEMA(node, "length")) { 6687 facet->type = XML_SCHEMA_FACET_LENGTH; 6688 } else if (IS_SCHEMA(node, "maxLength")) { 6689 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6690 } else if (IS_SCHEMA(node, "minLength")) { 6691 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6692 } else { 6693 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6694 "Unknown facet type %s\n", node->name, NULL); 6695 xmlSchemaFreeFacet(facet); 6696 return (NULL); 6697 } 6698 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6699 facet->value = value; 6700 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6701 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6702 const xmlChar *fixed; 6703 6704 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6705 if (fixed != NULL) { 6706 if (xmlStrEqual(fixed, BAD_CAST "true")) 6707 facet->fixed = 1; 6708 } 6709 } 6710 child = node->children; 6711 6712 if (IS_SCHEMA(child, "annotation")) { 6713 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6714 child = child->next; 6715 } 6716 if (child != NULL) { 6717 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6718 "Facet %s has unexpected child content\n", 6719 node->name, NULL); 6720 } 6721 return (facet); 6722 } 6723 6724 /** 6725 * xmlSchemaParseWildcardNs: 6726 * @ctxt: a schema parser context 6727 * @wildc: the wildcard, already created 6728 * @node: a subtree containing XML Schema informations 6729 * 6730 * Parses the attribute "processContents" and "namespace" 6731 * of a xsd:anyAttribute and xsd:any. 6732 * *WARNING* this interface is highly subject to change 6733 * 6734 * Returns 0 if everything goes fine, a positive error code 6735 * if something is not valid and -1 if an internal error occurs. 6736 */ 6737 static int 6738 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6739 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6740 xmlSchemaWildcardPtr wildc, 6741 xmlNodePtr node) 6742 { 6743 const xmlChar *pc, *ns, *dictnsItem; 6744 int ret = 0; 6745 xmlChar *nsItem; 6746 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6747 xmlAttrPtr attr; 6748 6749 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6750 if ((pc == NULL) 6751 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6752 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6753 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6754 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6755 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6756 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6757 } else { 6758 xmlSchemaPSimpleTypeErr(ctxt, 6759 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6760 NULL, node, 6761 NULL, "(strict | skip | lax)", pc, 6762 NULL, NULL, NULL); 6763 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6764 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6765 } 6766 /* 6767 * Build the namespace constraints. 6768 */ 6769 attr = xmlSchemaGetPropNode(node, "namespace"); 6770 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6771 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6772 wildc->any = 1; 6773 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6774 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6775 if (wildc->negNsSet == NULL) { 6776 return (-1); 6777 } 6778 wildc->negNsSet->value = ctxt->targetNamespace; 6779 } else { 6780 const xmlChar *end, *cur; 6781 6782 cur = ns; 6783 do { 6784 while (IS_BLANK_CH(*cur)) 6785 cur++; 6786 end = cur; 6787 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6788 end++; 6789 if (end == cur) 6790 break; 6791 nsItem = xmlStrndup(cur, end - cur); 6792 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6793 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6794 xmlSchemaPSimpleTypeErr(ctxt, 6795 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6796 NULL, (xmlNodePtr) attr, 6797 NULL, 6798 "((##any | ##other) | List of (xs:anyURI | " 6799 "(##targetNamespace | ##local)))", 6800 nsItem, NULL, NULL, NULL); 6801 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6802 } else { 6803 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6804 dictnsItem = ctxt->targetNamespace; 6805 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6806 dictnsItem = NULL; 6807 } else { 6808 /* 6809 * Validate the item (anyURI). 6810 */ 6811 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6812 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6813 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6814 } 6815 /* 6816 * Avoid dublicate namespaces. 6817 */ 6818 tmp = wildc->nsSet; 6819 while (tmp != NULL) { 6820 if (dictnsItem == tmp->value) 6821 break; 6822 tmp = tmp->next; 6823 } 6824 if (tmp == NULL) { 6825 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6826 if (tmp == NULL) { 6827 xmlFree(nsItem); 6828 return (-1); 6829 } 6830 tmp->value = dictnsItem; 6831 tmp->next = NULL; 6832 if (wildc->nsSet == NULL) 6833 wildc->nsSet = tmp; 6834 else if (lastNs != NULL) 6835 lastNs->next = tmp; 6836 lastNs = tmp; 6837 } 6838 6839 } 6840 xmlFree(nsItem); 6841 cur = end; 6842 } while (*cur != 0); 6843 } 6844 return (ret); 6845 } 6846 6847 static int 6848 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6849 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6850 xmlNodePtr node, 6851 int minOccurs, 6852 int maxOccurs) { 6853 6854 if ((maxOccurs == 0) && ( minOccurs == 0)) 6855 return (0); 6856 if (maxOccurs != UNBOUNDED) { 6857 /* 6858 * TODO: Maybe we should better not create the particle, 6859 * if min/max is invalid, since it could confuse the build of the 6860 * content model. 6861 */ 6862 /* 6863 * 3.9.6 Schema Component Constraint: Particle Correct 6864 * 6865 */ 6866 if (maxOccurs < 1) { 6867 /* 6868 * 2.2 {max occurs} must be greater than or equal to 1. 6869 */ 6870 xmlSchemaPCustomAttrErr(ctxt, 6871 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6872 NULL, NULL, 6873 xmlSchemaGetPropNode(node, "maxOccurs"), 6874 "The value must be greater than or equal to 1"); 6875 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6876 } else if (minOccurs > maxOccurs) { 6877 /* 6878 * 2.1 {min occurs} must not be greater than {max occurs}. 6879 */ 6880 xmlSchemaPCustomAttrErr(ctxt, 6881 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6882 NULL, NULL, 6883 xmlSchemaGetPropNode(node, "minOccurs"), 6884 "The value must not be greater than the value of 'maxOccurs'"); 6885 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6886 } 6887 } 6888 return (0); 6889 } 6890 6891 /** 6892 * xmlSchemaParseAny: 6893 * @ctxt: a schema validation context 6894 * @schema: the schema being built 6895 * @node: a subtree containing XML Schema informations 6896 * 6897 * Parsea a XML schema <any> element. A particle and wildcard 6898 * will be created (except if minOccurs==maxOccurs==0, in this case 6899 * nothing will be created). 6900 * *WARNING* this interface is highly subject to change 6901 * 6902 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6903 */ 6904 static xmlSchemaParticlePtr 6905 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6906 xmlNodePtr node) 6907 { 6908 xmlSchemaParticlePtr particle; 6909 xmlNodePtr child = NULL; 6910 xmlSchemaWildcardPtr wild; 6911 int min, max; 6912 xmlAttrPtr attr; 6913 xmlSchemaAnnotPtr annot = NULL; 6914 6915 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6916 return (NULL); 6917 /* 6918 * Check for illegal attributes. 6919 */ 6920 attr = node->properties; 6921 while (attr != NULL) { 6922 if (attr->ns == NULL) { 6923 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6924 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6925 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6926 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6927 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6928 xmlSchemaPIllegalAttrErr(ctxt, 6929 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6930 } 6931 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6932 xmlSchemaPIllegalAttrErr(ctxt, 6933 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6934 } 6935 attr = attr->next; 6936 } 6937 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6938 /* 6939 * minOccurs/maxOccurs. 6940 */ 6941 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6942 "(xs:nonNegativeInteger | unbounded)"); 6943 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6944 "xs:nonNegativeInteger"); 6945 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6946 /* 6947 * Create & parse the wildcard. 6948 */ 6949 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6950 if (wild == NULL) 6951 return (NULL); 6952 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6953 /* 6954 * And now for the children... 6955 */ 6956 child = node->children; 6957 if (IS_SCHEMA(child, "annotation")) { 6958 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6959 child = child->next; 6960 } 6961 if (child != NULL) { 6962 xmlSchemaPContentErr(ctxt, 6963 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6964 NULL, node, child, 6965 NULL, "(annotation?)"); 6966 } 6967 /* 6968 * No component if minOccurs==maxOccurs==0. 6969 */ 6970 if ((min == 0) && (max == 0)) { 6971 /* Don't free the wildcard, since it's already on the list. */ 6972 return (NULL); 6973 } 6974 /* 6975 * Create the particle. 6976 */ 6977 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6978 if (particle == NULL) 6979 return (NULL); 6980 particle->annot = annot; 6981 particle->children = (xmlSchemaTreeItemPtr) wild; 6982 6983 return (particle); 6984 } 6985 6986 /** 6987 * xmlSchemaParseNotation: 6988 * @ctxt: a schema validation context 6989 * @schema: the schema being built 6990 * @node: a subtree containing XML Schema informations 6991 * 6992 * parse a XML schema Notation declaration 6993 * 6994 * Returns the new structure or NULL in case of error 6995 */ 6996 static xmlSchemaNotationPtr 6997 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6998 xmlNodePtr node) 6999 { 7000 const xmlChar *name; 7001 xmlSchemaNotationPtr ret; 7002 xmlNodePtr child = NULL; 7003 7004 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7005 return (NULL); 7006 name = xmlSchemaGetProp(ctxt, node, "name"); 7007 if (name == NULL) { 7008 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 7009 "Notation has no name\n", NULL, NULL); 7010 return (NULL); 7011 } 7012 ret = xmlSchemaAddNotation(ctxt, schema, name, 7013 ctxt->targetNamespace, node); 7014 if (ret == NULL) 7015 return (NULL); 7016 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7017 7018 child = node->children; 7019 if (IS_SCHEMA(child, "annotation")) { 7020 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7021 child = child->next; 7022 } 7023 if (child != NULL) { 7024 xmlSchemaPContentErr(ctxt, 7025 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7026 NULL, node, child, 7027 NULL, "(annotation?)"); 7028 } 7029 7030 return (ret); 7031 } 7032 7033 /** 7034 * xmlSchemaParseAnyAttribute: 7035 * @ctxt: a schema validation context 7036 * @schema: the schema being built 7037 * @node: a subtree containing XML Schema informations 7038 * 7039 * parse a XML schema AnyAttrribute declaration 7040 * *WARNING* this interface is highly subject to change 7041 * 7042 * Returns a wildcard or NULL. 7043 */ 7044 static xmlSchemaWildcardPtr 7045 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7046 xmlSchemaPtr schema, xmlNodePtr node) 7047 { 7048 xmlSchemaWildcardPtr ret; 7049 xmlNodePtr child = NULL; 7050 xmlAttrPtr attr; 7051 7052 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7053 return (NULL); 7054 7055 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7056 node); 7057 if (ret == NULL) { 7058 return (NULL); 7059 } 7060 /* 7061 * Check for illegal attributes. 7062 */ 7063 attr = node->properties; 7064 while (attr != NULL) { 7065 if (attr->ns == NULL) { 7066 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7067 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7068 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7069 xmlSchemaPIllegalAttrErr(ctxt, 7070 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7071 } 7072 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7073 xmlSchemaPIllegalAttrErr(ctxt, 7074 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7075 } 7076 attr = attr->next; 7077 } 7078 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7079 /* 7080 * Parse the namespace list. 7081 */ 7082 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7083 return (NULL); 7084 /* 7085 * And now for the children... 7086 */ 7087 child = node->children; 7088 if (IS_SCHEMA(child, "annotation")) { 7089 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7090 child = child->next; 7091 } 7092 if (child != NULL) { 7093 xmlSchemaPContentErr(ctxt, 7094 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7095 NULL, node, child, 7096 NULL, "(annotation?)"); 7097 } 7098 7099 return (ret); 7100 } 7101 7102 7103 /** 7104 * xmlSchemaParseAttribute: 7105 * @ctxt: a schema validation context 7106 * @schema: the schema being built 7107 * @node: a subtree containing XML Schema informations 7108 * 7109 * parse a XML schema Attrribute declaration 7110 * *WARNING* this interface is highly subject to change 7111 * 7112 * Returns the attribute declaration. 7113 */ 7114 static xmlSchemaBasicItemPtr 7115 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7116 xmlSchemaPtr schema, 7117 xmlNodePtr node, 7118 xmlSchemaItemListPtr uses, 7119 int parentType) 7120 { 7121 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7122 xmlSchemaAttributeUsePtr use = NULL; 7123 xmlNodePtr child = NULL; 7124 xmlAttrPtr attr; 7125 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7126 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7127 int nberrors, hasForm = 0, defValueType = 0; 7128 7129 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7130 #define WXS_ATTR_DEF_VAL_FIXED 2 7131 7132 /* 7133 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7134 */ 7135 7136 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7137 return (NULL); 7138 attr = xmlSchemaGetPropNode(node, "ref"); 7139 if (attr != NULL) { 7140 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7141 NULL, attr, &tmpNs, &tmpName) != 0) { 7142 return (NULL); 7143 } 7144 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7145 return(NULL); 7146 isRef = 1; 7147 } 7148 nberrors = pctxt->nberrors; 7149 /* 7150 * Check for illegal attributes. 7151 */ 7152 attr = node->properties; 7153 while (attr != NULL) { 7154 if (attr->ns == NULL) { 7155 if (isRef) { 7156 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7157 xmlSchemaPValAttrNodeID(pctxt, attr); 7158 goto attr_next; 7159 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7160 goto attr_next; 7161 } 7162 } else { 7163 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7164 goto attr_next; 7165 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7166 xmlSchemaPValAttrNodeID(pctxt, attr); 7167 goto attr_next; 7168 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7169 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7170 attr, &tmpNs, &tmpName); 7171 goto attr_next; 7172 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7173 /* 7174 * Evaluate the target namespace 7175 */ 7176 hasForm = 1; 7177 attrValue = xmlSchemaGetNodeContent(pctxt, 7178 (xmlNodePtr) attr); 7179 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7180 ns = pctxt->targetNamespace; 7181 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7182 { 7183 xmlSchemaPSimpleTypeErr(pctxt, 7184 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7185 NULL, (xmlNodePtr) attr, 7186 NULL, "(qualified | unqualified)", 7187 attrValue, NULL, NULL, NULL); 7188 } 7189 goto attr_next; 7190 } 7191 } 7192 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7193 7194 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7195 /* TODO: Maybe we need to normalize the value beforehand. */ 7196 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7197 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7198 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7199 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7200 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7201 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7202 else { 7203 xmlSchemaPSimpleTypeErr(pctxt, 7204 XML_SCHEMAP_INVALID_ATTR_USE, 7205 NULL, (xmlNodePtr) attr, 7206 NULL, "(optional | prohibited | required)", 7207 attrValue, NULL, NULL, NULL); 7208 } 7209 goto attr_next; 7210 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7211 /* 7212 * 3.2.3 : 1 7213 * default and fixed must not both be present. 7214 */ 7215 if (defValue) { 7216 xmlSchemaPMutualExclAttrErr(pctxt, 7217 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7218 NULL, attr, "default", "fixed"); 7219 } else { 7220 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7221 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7222 } 7223 goto attr_next; 7224 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7225 /* 7226 * 3.2.3 : 1 7227 * default and fixed must not both be present. 7228 */ 7229 if (defValue) { 7230 xmlSchemaPMutualExclAttrErr(pctxt, 7231 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7232 NULL, attr, "default", "fixed"); 7233 } else { 7234 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7235 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7236 } 7237 goto attr_next; 7238 } 7239 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7240 goto attr_next; 7241 7242 xmlSchemaPIllegalAttrErr(pctxt, 7243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7244 7245 attr_next: 7246 attr = attr->next; 7247 } 7248 /* 7249 * 3.2.3 : 2 7250 * If default and use are both present, use must have 7251 * the actual value optional. 7252 */ 7253 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7254 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7255 xmlSchemaPSimpleTypeErr(pctxt, 7256 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7257 NULL, node, NULL, 7258 "(optional | prohibited | required)", NULL, 7259 "The value of the attribute 'use' must be 'optional' " 7260 "if the attribute 'default' is present", 7261 NULL, NULL); 7262 } 7263 /* 7264 * We want correct attributes. 7265 */ 7266 if (nberrors != pctxt->nberrors) 7267 return(NULL); 7268 if (! isRef) { 7269 xmlSchemaAttributePtr attrDecl; 7270 7271 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7272 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7273 ns = pctxt->targetNamespace; 7274 /* 7275 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7276 * TODO: Move this to the component layer. 7277 */ 7278 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7279 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7280 XML_SCHEMAP_NO_XSI, 7281 node, NULL, 7282 "The target namespace must not match '%s'", 7283 xmlSchemaInstanceNs, NULL); 7284 } 7285 attr = xmlSchemaGetPropNode(node, "name"); 7286 if (attr == NULL) { 7287 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7288 NULL, node, "name", NULL); 7289 return (NULL); 7290 } 7291 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7292 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7293 return (NULL); 7294 } 7295 /* 7296 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7297 * TODO: Move this to the component layer. 7298 */ 7299 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7300 xmlSchemaPSimpleTypeErr(pctxt, 7301 XML_SCHEMAP_NO_XMLNS, 7302 NULL, (xmlNodePtr) attr, 7303 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7304 "The value of the attribute must not match 'xmlns'", 7305 NULL, NULL); 7306 return (NULL); 7307 } 7308 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7309 goto check_children; 7310 /* 7311 * Create the attribute use component. 7312 */ 7313 use = xmlSchemaAddAttributeUse(pctxt, node); 7314 if (use == NULL) 7315 return(NULL); 7316 use->occurs = occurs; 7317 /* 7318 * Create the attribute declaration. 7319 */ 7320 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7321 if (attrDecl == NULL) 7322 return (NULL); 7323 if (tmpName != NULL) { 7324 attrDecl->typeName = tmpName; 7325 attrDecl->typeNs = tmpNs; 7326 } 7327 use->attrDecl = attrDecl; 7328 /* 7329 * Value constraint. 7330 */ 7331 if (defValue != NULL) { 7332 attrDecl->defValue = defValue; 7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7334 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7335 } 7336 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7337 xmlSchemaQNameRefPtr ref; 7338 7339 /* 7340 * Create the attribute use component. 7341 */ 7342 use = xmlSchemaAddAttributeUse(pctxt, node); 7343 if (use == NULL) 7344 return(NULL); 7345 /* 7346 * We need to resolve the reference at later stage. 7347 */ 7348 WXS_ADD_PENDING(pctxt, use); 7349 use->occurs = occurs; 7350 /* 7351 * Create a QName reference to the attribute declaration. 7352 */ 7353 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7354 tmpName, tmpNs); 7355 if (ref == NULL) 7356 return(NULL); 7357 /* 7358 * Assign the reference. This will be substituted for the 7359 * referenced attribute declaration when the QName is resolved. 7360 */ 7361 use->attrDecl = WXS_ATTR_CAST ref; 7362 /* 7363 * Value constraint. 7364 */ 7365 if (defValue != NULL) 7366 use->defValue = defValue; 7367 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7368 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7369 } 7370 7371 check_children: 7372 /* 7373 * And now for the children... 7374 */ 7375 child = node->children; 7376 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7377 xmlSchemaAttributeUseProhibPtr prohib; 7378 7379 if (IS_SCHEMA(child, "annotation")) { 7380 xmlSchemaParseAnnotation(pctxt, child, 0); 7381 child = child->next; 7382 } 7383 if (child != NULL) { 7384 xmlSchemaPContentErr(pctxt, 7385 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7386 NULL, node, child, NULL, 7387 "(annotation?)"); 7388 } 7389 /* 7390 * Check for pointlessness of attribute prohibitions. 7391 */ 7392 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7395 node, NULL, 7396 "Skipping attribute use prohibition, since it is " 7397 "pointless inside an <attributeGroup>", 7398 NULL, NULL, NULL); 7399 return(NULL); 7400 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7401 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7402 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7403 node, NULL, 7404 "Skipping attribute use prohibition, since it is " 7405 "pointless when extending a type", 7406 NULL, NULL, NULL); 7407 return(NULL); 7408 } 7409 if (! isRef) { 7410 tmpName = name; 7411 tmpNs = ns; 7412 } 7413 /* 7414 * Check for duplicate attribute prohibitions. 7415 */ 7416 if (uses) { 7417 int i; 7418 7419 for (i = 0; i < uses->nbItems; i++) { 7420 use = uses->items[i]; 7421 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7422 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7423 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7424 { 7425 xmlChar *str = NULL; 7426 7427 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7428 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7429 node, NULL, 7430 "Skipping duplicate attribute use prohibition '%s'", 7431 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7432 NULL, NULL); 7433 FREE_AND_NULL(str) 7434 return(NULL); 7435 } 7436 } 7437 } 7438 /* 7439 * Create the attribute prohibition helper component. 7440 */ 7441 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7442 if (prohib == NULL) 7443 return(NULL); 7444 prohib->node = node; 7445 prohib->name = tmpName; 7446 prohib->targetNamespace = tmpNs; 7447 if (isRef) { 7448 /* 7449 * We need at least to resolve to the attribute declaration. 7450 */ 7451 WXS_ADD_PENDING(pctxt, prohib); 7452 } 7453 return(WXS_BASIC_CAST prohib); 7454 } else { 7455 if (IS_SCHEMA(child, "annotation")) { 7456 /* 7457 * TODO: Should this go into the attr decl? 7458 */ 7459 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7460 child = child->next; 7461 } 7462 if (isRef) { 7463 if (child != NULL) { 7464 if (IS_SCHEMA(child, "simpleType")) 7465 /* 7466 * 3.2.3 : 3.2 7467 * If ref is present, then all of <simpleType>, 7468 * form and type must be absent. 7469 */ 7470 xmlSchemaPContentErr(pctxt, 7471 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7472 NULL, node, child, NULL, 7473 "(annotation?)"); 7474 else 7475 xmlSchemaPContentErr(pctxt, 7476 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7477 NULL, node, child, NULL, 7478 "(annotation?)"); 7479 } 7480 } else { 7481 if (IS_SCHEMA(child, "simpleType")) { 7482 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7483 /* 7484 * 3.2.3 : 4 7485 * type and <simpleType> must not both be present. 7486 */ 7487 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7488 NULL, node, child, 7489 "The attribute 'type' and the <simpleType> child " 7490 "are mutually exclusive", NULL); 7491 } else 7492 WXS_ATTRUSE_TYPEDEF(use) = 7493 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7494 child = child->next; 7495 } 7496 if (child != NULL) 7497 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7498 NULL, node, child, NULL, 7499 "(annotation?, simpleType?)"); 7500 } 7501 } 7502 return (WXS_BASIC_CAST use); 7503 } 7504 7505 7506 static xmlSchemaAttributePtr 7507 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7508 xmlSchemaPtr schema, 7509 xmlNodePtr node) 7510 { 7511 const xmlChar *attrValue; 7512 xmlSchemaAttributePtr ret; 7513 xmlNodePtr child = NULL; 7514 xmlAttrPtr attr; 7515 7516 /* 7517 * Note that the w3c spec assumes the schema to be validated with schema 7518 * for schemas beforehand. 7519 * 7520 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7521 */ 7522 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7523 return (NULL); 7524 /* 7525 * 3.2.3 : 3.1 7526 * One of ref or name must be present, but not both 7527 */ 7528 attr = xmlSchemaGetPropNode(node, "name"); 7529 if (attr == NULL) { 7530 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7531 NULL, node, "name", NULL); 7532 return (NULL); 7533 } 7534 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7535 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7536 return (NULL); 7537 } 7538 /* 7539 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7540 * TODO: Move this to the component layer. 7541 */ 7542 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7543 xmlSchemaPSimpleTypeErr(pctxt, 7544 XML_SCHEMAP_NO_XMLNS, 7545 NULL, (xmlNodePtr) attr, 7546 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7547 "The value of the attribute must not match 'xmlns'", 7548 NULL, NULL); 7549 return (NULL); 7550 } 7551 /* 7552 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7553 * TODO: Move this to the component layer. 7554 * Or better leave it here and add it to the component layer 7555 * if we have a schema construction API. 7556 */ 7557 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7558 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7559 XML_SCHEMAP_NO_XSI, node, NULL, 7560 "The target namespace must not match '%s'", 7561 xmlSchemaInstanceNs, NULL); 7562 } 7563 7564 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7565 pctxt->targetNamespace, node, 1); 7566 if (ret == NULL) 7567 return (NULL); 7568 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7569 7570 /* 7571 * Check for illegal attributes. 7572 */ 7573 attr = node->properties; 7574 while (attr != NULL) { 7575 if (attr->ns == NULL) { 7576 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7577 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7578 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7579 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7580 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7581 { 7582 xmlSchemaPIllegalAttrErr(pctxt, 7583 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7584 } 7585 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7586 xmlSchemaPIllegalAttrErr(pctxt, 7587 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7588 } 7589 attr = attr->next; 7590 } 7591 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7592 node, "type", &ret->typeNs, &ret->typeName); 7593 7594 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7595 /* 7596 * Attribute "fixed". 7597 */ 7598 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7599 if (ret->defValue != NULL) 7600 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7601 /* 7602 * Attribute "default". 7603 */ 7604 attr = xmlSchemaGetPropNode(node, "default"); 7605 if (attr != NULL) { 7606 /* 7607 * 3.2.3 : 1 7608 * default and fixed must not both be present. 7609 */ 7610 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7611 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7612 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7613 } else 7614 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7615 } 7616 /* 7617 * And now for the children... 7618 */ 7619 child = node->children; 7620 if (IS_SCHEMA(child, "annotation")) { 7621 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7622 child = child->next; 7623 } 7624 if (IS_SCHEMA(child, "simpleType")) { 7625 if (ret->typeName != NULL) { 7626 /* 7627 * 3.2.3 : 4 7628 * type and <simpleType> must not both be present. 7629 */ 7630 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7631 NULL, node, child, 7632 "The attribute 'type' and the <simpleType> child " 7633 "are mutually exclusive", NULL); 7634 } else 7635 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7636 child = child->next; 7637 } 7638 if (child != NULL) 7639 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7640 NULL, node, child, NULL, 7641 "(annotation?, simpleType?)"); 7642 7643 return (ret); 7644 } 7645 7646 /** 7647 * xmlSchemaParseAttributeGroupRef: 7648 * @ctxt: a schema validation context 7649 * @schema: the schema being built 7650 * @node: a subtree containing XML Schema informations 7651 * 7652 * Parse an attribute group definition reference. 7653 * Note that a reference to an attribute group does not 7654 * correspond to any component at all. 7655 * *WARNING* this interface is highly subject to change 7656 * 7657 * Returns the attribute group or NULL in case of error. 7658 */ 7659 static xmlSchemaQNameRefPtr 7660 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7661 xmlSchemaPtr schema, 7662 xmlNodePtr node) 7663 { 7664 xmlSchemaQNameRefPtr ret; 7665 xmlNodePtr child = NULL; 7666 xmlAttrPtr attr; 7667 const xmlChar *refNs = NULL, *ref = NULL; 7668 7669 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7670 return (NULL); 7671 7672 attr = xmlSchemaGetPropNode(node, "ref"); 7673 if (attr == NULL) { 7674 xmlSchemaPMissingAttrErr(pctxt, 7675 XML_SCHEMAP_S4S_ATTR_MISSING, 7676 NULL, node, "ref", NULL); 7677 return (NULL); 7678 } 7679 xmlSchemaPValAttrNodeQName(pctxt, schema, 7680 NULL, attr, &refNs, &ref); 7681 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7682 return(NULL); 7683 7684 /* 7685 * Check for illegal attributes. 7686 */ 7687 attr = node->properties; 7688 while (attr != NULL) { 7689 if (attr->ns == NULL) { 7690 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7691 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7692 { 7693 xmlSchemaPIllegalAttrErr(pctxt, 7694 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7695 } 7696 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7697 xmlSchemaPIllegalAttrErr(pctxt, 7698 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7699 } 7700 attr = attr->next; 7701 } 7702 /* Attribute ID */ 7703 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7704 7705 /* 7706 * And now for the children... 7707 */ 7708 child = node->children; 7709 if (IS_SCHEMA(child, "annotation")) { 7710 /* 7711 * TODO: We do not have a place to store the annotation, do we? 7712 */ 7713 xmlSchemaParseAnnotation(pctxt, child, 0); 7714 child = child->next; 7715 } 7716 if (child != NULL) { 7717 xmlSchemaPContentErr(pctxt, 7718 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7719 NULL, node, child, NULL, 7720 "(annotation?)"); 7721 } 7722 7723 /* 7724 * Handle attribute group redefinitions. 7725 */ 7726 if (pctxt->isRedefine && pctxt->redef && 7727 (pctxt->redef->item->type == 7728 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7729 (ref == pctxt->redef->refName) && 7730 (refNs == pctxt->redef->refTargetNs)) 7731 { 7732 /* 7733 * SPEC src-redefine: 7734 * (7.1) "If it has an <attributeGroup> among its contents 7735 * the `actual value` of whose ref [attribute] is the same 7736 * as the `actual value` of its own name attribute plus 7737 * target namespace, then it must have exactly one such group." 7738 */ 7739 if (pctxt->redefCounter != 0) { 7740 xmlChar *str = NULL; 7741 7742 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7743 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7744 "The redefining attribute group definition " 7745 "'%s' must not contain more than one " 7746 "reference to the redefined definition", 7747 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7748 FREE_AND_NULL(str); 7749 return(NULL); 7750 } 7751 pctxt->redefCounter++; 7752 /* 7753 * URGENT TODO: How to ensure that the reference will not be 7754 * handled by the normal component resolution mechanism? 7755 */ 7756 ret = xmlSchemaNewQNameRef(pctxt, 7757 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7758 if (ret == NULL) 7759 return(NULL); 7760 ret->node = node; 7761 pctxt->redef->reference = WXS_BASIC_CAST ret; 7762 } else { 7763 /* 7764 * Create a QName-reference helper component. We will substitute this 7765 * component for the attribute uses of the referenced attribute group 7766 * definition. 7767 */ 7768 ret = xmlSchemaNewQNameRef(pctxt, 7769 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7770 if (ret == NULL) 7771 return(NULL); 7772 ret->node = node; 7773 /* Add to pending items, to be able to resolve the reference. */ 7774 WXS_ADD_PENDING(pctxt, ret); 7775 } 7776 return (ret); 7777 } 7778 7779 /** 7780 * xmlSchemaParseAttributeGroupDefinition: 7781 * @pctxt: a schema validation context 7782 * @schema: the schema being built 7783 * @node: a subtree containing XML Schema informations 7784 * 7785 * parse a XML schema Attribute Group declaration 7786 * *WARNING* this interface is highly subject to change 7787 * 7788 * Returns the attribute group definition or NULL in case of error. 7789 */ 7790 static xmlSchemaAttributeGroupPtr 7791 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7792 xmlSchemaPtr schema, 7793 xmlNodePtr node) 7794 { 7795 const xmlChar *name; 7796 xmlSchemaAttributeGroupPtr ret; 7797 xmlNodePtr child = NULL; 7798 xmlAttrPtr attr; 7799 int hasRefs = 0; 7800 7801 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7802 return (NULL); 7803 7804 attr = xmlSchemaGetPropNode(node, "name"); 7805 if (attr == NULL) { 7806 xmlSchemaPMissingAttrErr(pctxt, 7807 XML_SCHEMAP_S4S_ATTR_MISSING, 7808 NULL, node, "name", NULL); 7809 return (NULL); 7810 } 7811 /* 7812 * The name is crucial, exit if invalid. 7813 */ 7814 if (xmlSchemaPValAttrNode(pctxt, 7815 NULL, attr, 7816 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7817 return (NULL); 7818 } 7819 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7820 name, pctxt->targetNamespace, node); 7821 if (ret == NULL) 7822 return (NULL); 7823 /* 7824 * Check for illegal attributes. 7825 */ 7826 attr = node->properties; 7827 while (attr != NULL) { 7828 if (attr->ns == NULL) { 7829 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7830 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7831 { 7832 xmlSchemaPIllegalAttrErr(pctxt, 7833 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7834 } 7835 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7836 xmlSchemaPIllegalAttrErr(pctxt, 7837 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7838 } 7839 attr = attr->next; 7840 } 7841 /* Attribute ID */ 7842 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7843 /* 7844 * And now for the children... 7845 */ 7846 child = node->children; 7847 if (IS_SCHEMA(child, "annotation")) { 7848 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7849 child = child->next; 7850 } 7851 /* 7852 * Parse contained attribute decls/refs. 7853 */ 7854 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7855 (xmlSchemaItemListPtr *) &(ret->attrUses), 7856 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7857 return(NULL); 7858 if (hasRefs) 7859 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7860 /* 7861 * Parse the attribute wildcard. 7862 */ 7863 if (IS_SCHEMA(child, "anyAttribute")) { 7864 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7865 schema, child); 7866 child = child->next; 7867 } 7868 if (child != NULL) { 7869 xmlSchemaPContentErr(pctxt, 7870 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7871 NULL, node, child, NULL, 7872 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7873 } 7874 return (ret); 7875 } 7876 7877 /** 7878 * xmlSchemaPValAttrFormDefault: 7879 * @value: the value 7880 * @flags: the flags to be modified 7881 * @flagQualified: the specific flag for "qualified" 7882 * 7883 * Returns 0 if the value is valid, 1 otherwise. 7884 */ 7885 static int 7886 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7887 int *flags, 7888 int flagQualified) 7889 { 7890 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7891 if ((*flags & flagQualified) == 0) 7892 *flags |= flagQualified; 7893 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7894 return (1); 7895 7896 return (0); 7897 } 7898 7899 /** 7900 * xmlSchemaPValAttrBlockFinal: 7901 * @value: the value 7902 * @flags: the flags to be modified 7903 * @flagAll: the specific flag for "#all" 7904 * @flagExtension: the specific flag for "extension" 7905 * @flagRestriction: the specific flag for "restriction" 7906 * @flagSubstitution: the specific flag for "substitution" 7907 * @flagList: the specific flag for "list" 7908 * @flagUnion: the specific flag for "union" 7909 * 7910 * Validates the value of the attribute "final" and "block". The value 7911 * is converted into the specified flag values and returned in @flags. 7912 * 7913 * Returns 0 if the value is valid, 1 otherwise. 7914 */ 7915 7916 static int 7917 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7918 int *flags, 7919 int flagAll, 7920 int flagExtension, 7921 int flagRestriction, 7922 int flagSubstitution, 7923 int flagList, 7924 int flagUnion) 7925 { 7926 int ret = 0; 7927 7928 /* 7929 * TODO: This does not check for dublicate entries. 7930 */ 7931 if ((flags == NULL) || (value == NULL)) 7932 return (-1); 7933 if (value[0] == 0) 7934 return (0); 7935 if (xmlStrEqual(value, BAD_CAST "#all")) { 7936 if (flagAll != -1) 7937 *flags |= flagAll; 7938 else { 7939 if (flagExtension != -1) 7940 *flags |= flagExtension; 7941 if (flagRestriction != -1) 7942 *flags |= flagRestriction; 7943 if (flagSubstitution != -1) 7944 *flags |= flagSubstitution; 7945 if (flagList != -1) 7946 *flags |= flagList; 7947 if (flagUnion != -1) 7948 *flags |= flagUnion; 7949 } 7950 } else { 7951 const xmlChar *end, *cur = value; 7952 xmlChar *item; 7953 7954 do { 7955 while (IS_BLANK_CH(*cur)) 7956 cur++; 7957 end = cur; 7958 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7959 end++; 7960 if (end == cur) 7961 break; 7962 item = xmlStrndup(cur, end - cur); 7963 if (xmlStrEqual(item, BAD_CAST "extension")) { 7964 if (flagExtension != -1) { 7965 if ((*flags & flagExtension) == 0) 7966 *flags |= flagExtension; 7967 } else 7968 ret = 1; 7969 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7970 if (flagRestriction != -1) { 7971 if ((*flags & flagRestriction) == 0) 7972 *flags |= flagRestriction; 7973 } else 7974 ret = 1; 7975 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7976 if (flagSubstitution != -1) { 7977 if ((*flags & flagSubstitution) == 0) 7978 *flags |= flagSubstitution; 7979 } else 7980 ret = 1; 7981 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7982 if (flagList != -1) { 7983 if ((*flags & flagList) == 0) 7984 *flags |= flagList; 7985 } else 7986 ret = 1; 7987 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7988 if (flagUnion != -1) { 7989 if ((*flags & flagUnion) == 0) 7990 *flags |= flagUnion; 7991 } else 7992 ret = 1; 7993 } else 7994 ret = 1; 7995 if (item != NULL) 7996 xmlFree(item); 7997 cur = end; 7998 } while ((ret == 0) && (*cur != 0)); 7999 } 8000 8001 return (ret); 8002 } 8003 8004 static int 8005 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 8006 xmlSchemaIDCPtr idc, 8007 xmlSchemaIDCSelectPtr selector, 8008 xmlAttrPtr attr, 8009 int isField) 8010 { 8011 xmlNodePtr node; 8012 8013 /* 8014 * c-selector-xpath: 8015 * Schema Component Constraint: Selector Value OK 8016 * 8017 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8018 * in [XPath]. 8019 */ 8020 if (selector == NULL) { 8021 xmlSchemaPErr(ctxt, idc->node, 8022 XML_SCHEMAP_INTERNAL, 8023 "Internal error: xmlSchemaCheckCSelectorXPath, " 8024 "the selector is not specified.\n", NULL, NULL); 8025 return (-1); 8026 } 8027 if (attr == NULL) 8028 node = idc->node; 8029 else 8030 node = (xmlNodePtr) attr; 8031 if (selector->xpath == NULL) { 8032 xmlSchemaPCustomErr(ctxt, 8033 /* TODO: Adjust error code. */ 8034 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8035 NULL, node, 8036 "The XPath expression of the selector is not valid", NULL); 8037 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8038 } else { 8039 const xmlChar **nsArray = NULL; 8040 xmlNsPtr *nsList = NULL; 8041 /* 8042 * Compile the XPath expression. 8043 */ 8044 /* 8045 * TODO: We need the array of in-scope namespaces for compilation. 8046 * TODO: Call xmlPatterncompile with different options for selector/ 8047 * field. 8048 */ 8049 if (attr == NULL) 8050 nsList = NULL; 8051 else 8052 nsList = xmlGetNsList(attr->doc, attr->parent); 8053 /* 8054 * Build an array of prefixes and namespaces. 8055 */ 8056 if (nsList != NULL) { 8057 int i, count = 0; 8058 8059 for (i = 0; nsList[i] != NULL; i++) 8060 count++; 8061 8062 nsArray = (const xmlChar **) xmlMalloc( 8063 (count * 2 + 1) * sizeof(const xmlChar *)); 8064 if (nsArray == NULL) { 8065 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8066 NULL); 8067 xmlFree(nsList); 8068 return (-1); 8069 } 8070 for (i = 0; i < count; i++) { 8071 nsArray[2 * i] = nsList[i]->href; 8072 nsArray[2 * i + 1] = nsList[i]->prefix; 8073 } 8074 nsArray[count * 2] = NULL; 8075 xmlFree(nsList); 8076 } 8077 /* 8078 * TODO: Differentiate between "selector" and "field". 8079 */ 8080 if (isField) 8081 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8082 NULL, XML_PATTERN_XSFIELD, nsArray); 8083 else 8084 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8085 NULL, XML_PATTERN_XSSEL, nsArray); 8086 if (nsArray != NULL) 8087 xmlFree((xmlChar **) nsArray); 8088 8089 if (selector->xpathComp == NULL) { 8090 xmlSchemaPCustomErr(ctxt, 8091 /* TODO: Adjust error code? */ 8092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8093 NULL, node, 8094 "The XPath expression '%s' could not be " 8095 "compiled", selector->xpath); 8096 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8097 } 8098 } 8099 return (0); 8100 } 8101 8102 #define ADD_ANNOTATION(annot) \ 8103 xmlSchemaAnnotPtr cur = item->annot; \ 8104 if (item->annot == NULL) { \ 8105 item->annot = annot; \ 8106 return (annot); \ 8107 } \ 8108 cur = item->annot; \ 8109 if (cur->next != NULL) { \ 8110 cur = cur->next; \ 8111 } \ 8112 cur->next = annot; 8113 8114 /** 8115 * xmlSchemaAssignAnnotation: 8116 * @item: the schema component 8117 * @annot: the annotation 8118 * 8119 * Adds the annotation to the given schema component. 8120 * 8121 * Returns the given annotaion. 8122 */ 8123 static xmlSchemaAnnotPtr 8124 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8125 xmlSchemaAnnotPtr annot) 8126 { 8127 if ((annItem == NULL) || (annot == NULL)) 8128 return (NULL); 8129 switch (annItem->type) { 8130 case XML_SCHEMA_TYPE_ELEMENT: { 8131 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8132 ADD_ANNOTATION(annot) 8133 } 8134 break; 8135 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8136 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8137 ADD_ANNOTATION(annot) 8138 } 8139 break; 8140 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8141 case XML_SCHEMA_TYPE_ANY: { 8142 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8143 ADD_ANNOTATION(annot) 8144 } 8145 break; 8146 case XML_SCHEMA_TYPE_PARTICLE: 8147 case XML_SCHEMA_TYPE_IDC_KEY: 8148 case XML_SCHEMA_TYPE_IDC_KEYREF: 8149 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8150 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8151 ADD_ANNOTATION(annot) 8152 } 8153 break; 8154 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8155 xmlSchemaAttributeGroupPtr item = 8156 (xmlSchemaAttributeGroupPtr) annItem; 8157 ADD_ANNOTATION(annot) 8158 } 8159 break; 8160 case XML_SCHEMA_TYPE_NOTATION: { 8161 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8162 ADD_ANNOTATION(annot) 8163 } 8164 break; 8165 case XML_SCHEMA_FACET_MININCLUSIVE: 8166 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8167 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8168 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8169 case XML_SCHEMA_FACET_TOTALDIGITS: 8170 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8171 case XML_SCHEMA_FACET_PATTERN: 8172 case XML_SCHEMA_FACET_ENUMERATION: 8173 case XML_SCHEMA_FACET_WHITESPACE: 8174 case XML_SCHEMA_FACET_LENGTH: 8175 case XML_SCHEMA_FACET_MAXLENGTH: 8176 case XML_SCHEMA_FACET_MINLENGTH: { 8177 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8178 ADD_ANNOTATION(annot) 8179 } 8180 break; 8181 case XML_SCHEMA_TYPE_SIMPLE: 8182 case XML_SCHEMA_TYPE_COMPLEX: { 8183 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8184 ADD_ANNOTATION(annot) 8185 } 8186 break; 8187 case XML_SCHEMA_TYPE_GROUP: { 8188 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8189 ADD_ANNOTATION(annot) 8190 } 8191 break; 8192 case XML_SCHEMA_TYPE_SEQUENCE: 8193 case XML_SCHEMA_TYPE_CHOICE: 8194 case XML_SCHEMA_TYPE_ALL: { 8195 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8196 ADD_ANNOTATION(annot) 8197 } 8198 break; 8199 default: 8200 xmlSchemaPCustomErr(NULL, 8201 XML_SCHEMAP_INTERNAL, 8202 NULL, NULL, 8203 "Internal error: xmlSchemaAddAnnotation, " 8204 "The item is not a annotated schema component", NULL); 8205 break; 8206 } 8207 return (annot); 8208 } 8209 8210 /** 8211 * xmlSchemaParseIDCSelectorAndField: 8212 * @ctxt: a schema validation context 8213 * @schema: the schema being built 8214 * @node: a subtree containing XML Schema informations 8215 * 8216 * Parses a XML Schema identity-contraint definition's 8217 * <selector> and <field> elements. 8218 * 8219 * Returns the parsed identity-constraint definition. 8220 */ 8221 static xmlSchemaIDCSelectPtr 8222 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8223 xmlSchemaIDCPtr idc, 8224 xmlNodePtr node, 8225 int isField) 8226 { 8227 xmlSchemaIDCSelectPtr item; 8228 xmlNodePtr child = NULL; 8229 xmlAttrPtr attr; 8230 8231 /* 8232 * Check for illegal attributes. 8233 */ 8234 attr = node->properties; 8235 while (attr != NULL) { 8236 if (attr->ns == NULL) { 8237 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8238 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8239 xmlSchemaPIllegalAttrErr(ctxt, 8240 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8241 } 8242 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8243 xmlSchemaPIllegalAttrErr(ctxt, 8244 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8245 } 8246 attr = attr->next; 8247 } 8248 /* 8249 * Create the item. 8250 */ 8251 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8252 if (item == NULL) { 8253 xmlSchemaPErrMemory(ctxt, 8254 "allocating a 'selector' of an identity-constraint definition", 8255 NULL); 8256 return (NULL); 8257 } 8258 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8259 /* 8260 * Attribute "xpath" (mandatory). 8261 */ 8262 attr = xmlSchemaGetPropNode(node, "xpath"); 8263 if (attr == NULL) { 8264 xmlSchemaPMissingAttrErr(ctxt, 8265 XML_SCHEMAP_S4S_ATTR_MISSING, 8266 NULL, node, 8267 "name", NULL); 8268 } else { 8269 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8270 /* 8271 * URGENT TODO: "field"s have an other syntax than "selector"s. 8272 */ 8273 8274 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8275 isField) == -1) { 8276 xmlSchemaPErr(ctxt, 8277 (xmlNodePtr) attr, 8278 XML_SCHEMAP_INTERNAL, 8279 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8280 "validating the XPath expression of a IDC selector.\n", 8281 NULL, NULL); 8282 } 8283 8284 } 8285 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8286 /* 8287 * And now for the children... 8288 */ 8289 child = node->children; 8290 if (IS_SCHEMA(child, "annotation")) { 8291 /* 8292 * Add the annotation to the parent IDC. 8293 */ 8294 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8295 xmlSchemaParseAnnotation(ctxt, child, 1)); 8296 child = child->next; 8297 } 8298 if (child != NULL) { 8299 xmlSchemaPContentErr(ctxt, 8300 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8301 NULL, node, child, 8302 NULL, "(annotation?)"); 8303 } 8304 8305 return (item); 8306 } 8307 8308 /** 8309 * xmlSchemaParseIDC: 8310 * @ctxt: a schema validation context 8311 * @schema: the schema being built 8312 * @node: a subtree containing XML Schema informations 8313 * 8314 * Parses a XML Schema identity-contraint definition. 8315 * 8316 * Returns the parsed identity-constraint definition. 8317 */ 8318 static xmlSchemaIDCPtr 8319 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8320 xmlSchemaPtr schema, 8321 xmlNodePtr node, 8322 xmlSchemaTypeType idcCategory, 8323 const xmlChar *targetNamespace) 8324 { 8325 xmlSchemaIDCPtr item = NULL; 8326 xmlNodePtr child = NULL; 8327 xmlAttrPtr attr; 8328 const xmlChar *name = NULL; 8329 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8330 8331 /* 8332 * Check for illegal attributes. 8333 */ 8334 attr = node->properties; 8335 while (attr != NULL) { 8336 if (attr->ns == NULL) { 8337 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8338 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8339 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8340 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8341 xmlSchemaPIllegalAttrErr(ctxt, 8342 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8343 } 8344 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8345 xmlSchemaPIllegalAttrErr(ctxt, 8346 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8347 } 8348 attr = attr->next; 8349 } 8350 /* 8351 * Attribute "name" (mandatory). 8352 */ 8353 attr = xmlSchemaGetPropNode(node, "name"); 8354 if (attr == NULL) { 8355 xmlSchemaPMissingAttrErr(ctxt, 8356 XML_SCHEMAP_S4S_ATTR_MISSING, 8357 NULL, node, 8358 "name", NULL); 8359 return (NULL); 8360 } else if (xmlSchemaPValAttrNode(ctxt, 8361 NULL, attr, 8362 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8363 return (NULL); 8364 } 8365 /* Create the component. */ 8366 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8367 idcCategory, node); 8368 if (item == NULL) 8369 return(NULL); 8370 8371 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8372 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8373 /* 8374 * Attribute "refer" (mandatory). 8375 */ 8376 attr = xmlSchemaGetPropNode(node, "refer"); 8377 if (attr == NULL) { 8378 xmlSchemaPMissingAttrErr(ctxt, 8379 XML_SCHEMAP_S4S_ATTR_MISSING, 8380 NULL, node, 8381 "refer", NULL); 8382 } else { 8383 /* 8384 * Create a reference item. 8385 */ 8386 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8387 NULL, NULL); 8388 if (item->ref == NULL) 8389 return (NULL); 8390 xmlSchemaPValAttrNodeQName(ctxt, schema, 8391 NULL, attr, 8392 &(item->ref->targetNamespace), 8393 &(item->ref->name)); 8394 xmlSchemaCheckReference(ctxt, schema, node, attr, 8395 item->ref->targetNamespace); 8396 } 8397 } 8398 /* 8399 * And now for the children... 8400 */ 8401 child = node->children; 8402 if (IS_SCHEMA(child, "annotation")) { 8403 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8404 child = child->next; 8405 } 8406 if (child == NULL) { 8407 xmlSchemaPContentErr(ctxt, 8408 XML_SCHEMAP_S4S_ELEM_MISSING, 8409 NULL, node, child, 8410 "A child element is missing", 8411 "(annotation?, (selector, field+))"); 8412 } 8413 /* 8414 * Child element <selector>. 8415 */ 8416 if (IS_SCHEMA(child, "selector")) { 8417 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8418 item, child, 0); 8419 child = child->next; 8420 /* 8421 * Child elements <field>. 8422 */ 8423 if (IS_SCHEMA(child, "field")) { 8424 do { 8425 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8426 item, child, 1); 8427 if (field != NULL) { 8428 field->index = item->nbFields; 8429 item->nbFields++; 8430 if (lastField != NULL) 8431 lastField->next = field; 8432 else 8433 item->fields = field; 8434 lastField = field; 8435 } 8436 child = child->next; 8437 } while (IS_SCHEMA(child, "field")); 8438 } else { 8439 xmlSchemaPContentErr(ctxt, 8440 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8441 NULL, node, child, 8442 NULL, "(annotation?, (selector, field+))"); 8443 } 8444 } 8445 if (child != NULL) { 8446 xmlSchemaPContentErr(ctxt, 8447 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8448 NULL, node, child, 8449 NULL, "(annotation?, (selector, field+))"); 8450 } 8451 8452 return (item); 8453 } 8454 8455 /** 8456 * xmlSchemaParseElement: 8457 * @ctxt: a schema validation context 8458 * @schema: the schema being built 8459 * @node: a subtree containing XML Schema informations 8460 * @topLevel: indicates if this is global declaration 8461 * 8462 * Parses a XML schema element declaration. 8463 * *WARNING* this interface is highly subject to change 8464 * 8465 * Returns the element declaration or a particle; NULL in case 8466 * of an error or if the particle has minOccurs==maxOccurs==0. 8467 */ 8468 static xmlSchemaBasicItemPtr 8469 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8470 xmlNodePtr node, int *isElemRef, int topLevel) 8471 { 8472 xmlSchemaElementPtr decl = NULL; 8473 xmlSchemaParticlePtr particle = NULL; 8474 xmlSchemaAnnotPtr annot = NULL; 8475 xmlNodePtr child = NULL; 8476 xmlAttrPtr attr, nameAttr; 8477 int min, max, isRef = 0; 8478 xmlChar *des = NULL; 8479 8480 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8481 /* TODO: Complete implementation of 3.3.6 */ 8482 8483 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8484 return (NULL); 8485 8486 if (isElemRef != NULL) 8487 *isElemRef = 0; 8488 /* 8489 * If we get a "ref" attribute on a local <element> we will assume it's 8490 * a reference - even if there's a "name" attribute; this seems to be more 8491 * robust. 8492 */ 8493 nameAttr = xmlSchemaGetPropNode(node, "name"); 8494 attr = xmlSchemaGetPropNode(node, "ref"); 8495 if ((topLevel) || (attr == NULL)) { 8496 if (nameAttr == NULL) { 8497 xmlSchemaPMissingAttrErr(ctxt, 8498 XML_SCHEMAP_S4S_ATTR_MISSING, 8499 NULL, node, "name", NULL); 8500 return (NULL); 8501 } 8502 } else 8503 isRef = 1; 8504 8505 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8506 child = node->children; 8507 if (IS_SCHEMA(child, "annotation")) { 8508 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8509 child = child->next; 8510 } 8511 /* 8512 * Skip particle part if a global declaration. 8513 */ 8514 if (topLevel) 8515 goto declaration_part; 8516 /* 8517 * The particle part ================================================== 8518 */ 8519 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8520 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8521 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8522 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8523 if (particle == NULL) 8524 goto return_null; 8525 8526 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8527 8528 if (isRef) { 8529 const xmlChar *refNs = NULL, *ref = NULL; 8530 xmlSchemaQNameRefPtr refer = NULL; 8531 /* 8532 * The reference part ============================================= 8533 */ 8534 if (isElemRef != NULL) 8535 *isElemRef = 1; 8536 8537 xmlSchemaPValAttrNodeQName(ctxt, schema, 8538 NULL, attr, &refNs, &ref); 8539 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8540 /* 8541 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8542 */ 8543 if (nameAttr != NULL) { 8544 xmlSchemaPMutualExclAttrErr(ctxt, 8545 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8546 } 8547 /* 8548 * Check for illegal attributes. 8549 */ 8550 attr = node->properties; 8551 while (attr != NULL) { 8552 if (attr->ns == NULL) { 8553 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8554 xmlStrEqual(attr->name, BAD_CAST "name") || 8555 xmlStrEqual(attr->name, BAD_CAST "id") || 8556 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8557 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8558 { 8559 attr = attr->next; 8560 continue; 8561 } else { 8562 /* SPEC (3.3.3 : 2.2) */ 8563 xmlSchemaPCustomAttrErr(ctxt, 8564 XML_SCHEMAP_SRC_ELEMENT_2_2, 8565 NULL, NULL, attr, 8566 "Only the attributes 'minOccurs', 'maxOccurs' and " 8567 "'id' are allowed in addition to 'ref'"); 8568 break; 8569 } 8570 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8571 xmlSchemaPIllegalAttrErr(ctxt, 8572 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8573 } 8574 attr = attr->next; 8575 } 8576 /* 8577 * No children except <annotation> expected. 8578 */ 8579 if (child != NULL) { 8580 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8581 NULL, node, child, NULL, "(annotation?)"); 8582 } 8583 if ((min == 0) && (max == 0)) 8584 goto return_null; 8585 /* 8586 * Create the reference item and attach it to the particle. 8587 */ 8588 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8589 ref, refNs); 8590 if (refer == NULL) 8591 goto return_null; 8592 particle->children = (xmlSchemaTreeItemPtr) refer; 8593 particle->annot = annot; 8594 /* 8595 * Add the particle to pending components, since the reference 8596 * need to be resolved. 8597 */ 8598 WXS_ADD_PENDING(ctxt, particle); 8599 return ((xmlSchemaBasicItemPtr) particle); 8600 } 8601 /* 8602 * The declaration part =============================================== 8603 */ 8604 declaration_part: 8605 { 8606 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8607 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8608 8609 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8610 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8611 goto return_null; 8612 /* 8613 * Evaluate the target namespace. 8614 */ 8615 if (topLevel) { 8616 ns = ctxt->targetNamespace; 8617 } else { 8618 attr = xmlSchemaGetPropNode(node, "form"); 8619 if (attr != NULL) { 8620 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8621 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8622 ns = ctxt->targetNamespace; 8623 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8624 xmlSchemaPSimpleTypeErr(ctxt, 8625 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8626 NULL, (xmlNodePtr) attr, 8627 NULL, "(qualified | unqualified)", 8628 attrValue, NULL, NULL, NULL); 8629 } 8630 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8631 ns = ctxt->targetNamespace; 8632 } 8633 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8634 if (decl == NULL) { 8635 goto return_null; 8636 } 8637 /* 8638 * Check for illegal attributes. 8639 */ 8640 attr = node->properties; 8641 while (attr != NULL) { 8642 if (attr->ns == NULL) { 8643 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8644 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8645 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8646 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8647 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8648 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8649 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8650 { 8651 if (topLevel == 0) { 8652 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8653 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8654 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8655 { 8656 xmlSchemaPIllegalAttrErr(ctxt, 8657 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8658 } 8659 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8660 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8661 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8662 8663 xmlSchemaPIllegalAttrErr(ctxt, 8664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8665 } 8666 } 8667 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8668 8669 xmlSchemaPIllegalAttrErr(ctxt, 8670 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8671 } 8672 attr = attr->next; 8673 } 8674 /* 8675 * Extract/validate attributes. 8676 */ 8677 if (topLevel) { 8678 /* 8679 * Process top attributes of global element declarations here. 8680 */ 8681 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8682 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8683 xmlSchemaPValAttrQName(ctxt, schema, 8684 NULL, node, "substitutionGroup", 8685 &(decl->substGroupNs), &(decl->substGroup)); 8686 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8687 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8688 /* 8689 * Attribute "final". 8690 */ 8691 attr = xmlSchemaGetPropNode(node, "final"); 8692 if (attr == NULL) { 8693 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8694 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8695 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8696 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8697 } else { 8698 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8699 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8700 -1, 8701 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8702 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8703 xmlSchemaPSimpleTypeErr(ctxt, 8704 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8705 NULL, (xmlNodePtr) attr, 8706 NULL, "(#all | List of (extension | restriction))", 8707 attrValue, NULL, NULL, NULL); 8708 } 8709 } 8710 } 8711 /* 8712 * Attribute "block". 8713 */ 8714 attr = xmlSchemaGetPropNode(node, "block"); 8715 if (attr == NULL) { 8716 /* 8717 * Apply default "block" values. 8718 */ 8719 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8720 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8721 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8722 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8723 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8724 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8725 } else { 8726 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8727 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8728 -1, 8729 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8730 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8731 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8732 xmlSchemaPSimpleTypeErr(ctxt, 8733 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8734 NULL, (xmlNodePtr) attr, 8735 NULL, "(#all | List of (extension | " 8736 "restriction | substitution))", attrValue, 8737 NULL, NULL, NULL); 8738 } 8739 } 8740 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8741 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8742 8743 attr = xmlSchemaGetPropNode(node, "type"); 8744 if (attr != NULL) { 8745 xmlSchemaPValAttrNodeQName(ctxt, schema, 8746 NULL, attr, 8747 &(decl->namedTypeNs), &(decl->namedType)); 8748 xmlSchemaCheckReference(ctxt, schema, node, 8749 attr, decl->namedTypeNs); 8750 } 8751 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8752 attr = xmlSchemaGetPropNode(node, "fixed"); 8753 if (attr != NULL) { 8754 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8755 if (decl->value != NULL) { 8756 /* 8757 * 3.3.3 : 1 8758 * default and fixed must not both be present. 8759 */ 8760 xmlSchemaPMutualExclAttrErr(ctxt, 8761 XML_SCHEMAP_SRC_ELEMENT_1, 8762 NULL, attr, "default", "fixed"); 8763 } else { 8764 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8765 decl->value = fixed; 8766 } 8767 } 8768 /* 8769 * And now for the children... 8770 */ 8771 if (IS_SCHEMA(child, "complexType")) { 8772 /* 8773 * 3.3.3 : 3 8774 * "type" and either <simpleType> or <complexType> are mutually 8775 * exclusive 8776 */ 8777 if (decl->namedType != NULL) { 8778 xmlSchemaPContentErr(ctxt, 8779 XML_SCHEMAP_SRC_ELEMENT_3, 8780 NULL, node, child, 8781 "The attribute 'type' and the <complexType> child are " 8782 "mutually exclusive", NULL); 8783 } else 8784 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8785 child = child->next; 8786 } else if (IS_SCHEMA(child, "simpleType")) { 8787 /* 8788 * 3.3.3 : 3 8789 * "type" and either <simpleType> or <complexType> are 8790 * mutually exclusive 8791 */ 8792 if (decl->namedType != NULL) { 8793 xmlSchemaPContentErr(ctxt, 8794 XML_SCHEMAP_SRC_ELEMENT_3, 8795 NULL, node, child, 8796 "The attribute 'type' and the <simpleType> child are " 8797 "mutually exclusive", NULL); 8798 } else 8799 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8800 child = child->next; 8801 } 8802 while ((IS_SCHEMA(child, "unique")) || 8803 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8804 if (IS_SCHEMA(child, "unique")) { 8805 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8806 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8807 } else if (IS_SCHEMA(child, "key")) { 8808 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8809 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8810 } else if (IS_SCHEMA(child, "keyref")) { 8811 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8812 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8813 } 8814 if (lastIDC != NULL) 8815 lastIDC->next = curIDC; 8816 else 8817 decl->idcs = (void *) curIDC; 8818 lastIDC = curIDC; 8819 child = child->next; 8820 } 8821 if (child != NULL) { 8822 xmlSchemaPContentErr(ctxt, 8823 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8824 NULL, node, child, 8825 NULL, "(annotation?, ((simpleType | complexType)?, " 8826 "(unique | key | keyref)*))"); 8827 } 8828 decl->annot = annot; 8829 } 8830 /* 8831 * NOTE: Element Declaration Representation OK 4. will be checked at a 8832 * different layer. 8833 */ 8834 FREE_AND_NULL(des) 8835 if (topLevel) 8836 return ((xmlSchemaBasicItemPtr) decl); 8837 else { 8838 particle->children = (xmlSchemaTreeItemPtr) decl; 8839 return ((xmlSchemaBasicItemPtr) particle); 8840 } 8841 8842 return_null: 8843 FREE_AND_NULL(des); 8844 if (annot != NULL) { 8845 if (particle != NULL) 8846 particle->annot = NULL; 8847 if (decl != NULL) 8848 decl->annot = NULL; 8849 xmlSchemaFreeAnnot(annot); 8850 } 8851 return (NULL); 8852 } 8853 8854 /** 8855 * xmlSchemaParseUnion: 8856 * @ctxt: a schema validation context 8857 * @schema: the schema being built 8858 * @node: a subtree containing XML Schema informations 8859 * 8860 * parse a XML schema Union definition 8861 * *WARNING* this interface is highly subject to change 8862 * 8863 * Returns -1 in case of internal error, 0 in case of success and a positive 8864 * error code otherwise. 8865 */ 8866 static int 8867 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8868 xmlNodePtr node) 8869 { 8870 xmlSchemaTypePtr type; 8871 xmlNodePtr child = NULL; 8872 xmlAttrPtr attr; 8873 const xmlChar *cur = NULL; 8874 8875 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8876 return (-1); 8877 /* Not a component, don't create it. */ 8878 type = ctxt->ctxtType; 8879 /* 8880 * Mark the simple type as being of variety "union". 8881 */ 8882 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8883 /* 8884 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8885 * then the `simple ur-type definition`." 8886 */ 8887 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8888 /* 8889 * Check for illegal attributes. 8890 */ 8891 attr = node->properties; 8892 while (attr != NULL) { 8893 if (attr->ns == NULL) { 8894 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8895 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8896 xmlSchemaPIllegalAttrErr(ctxt, 8897 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8898 } 8899 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8900 xmlSchemaPIllegalAttrErr(ctxt, 8901 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8902 } 8903 attr = attr->next; 8904 } 8905 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8906 /* 8907 * Attribute "memberTypes". This is a list of QNames. 8908 * TODO: Check the value to contain anything. 8909 */ 8910 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8911 if (attr != NULL) { 8912 const xmlChar *end; 8913 xmlChar *tmp; 8914 const xmlChar *localName, *nsName; 8915 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8916 xmlSchemaQNameRefPtr ref; 8917 8918 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8919 type->base = cur; 8920 do { 8921 while (IS_BLANK_CH(*cur)) 8922 cur++; 8923 end = cur; 8924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8925 end++; 8926 if (end == cur) 8927 break; 8928 tmp = xmlStrndup(cur, end - cur); 8929 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8930 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8931 /* 8932 * Create the member type link. 8933 */ 8934 link = (xmlSchemaTypeLinkPtr) 8935 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8936 if (link == NULL) { 8937 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8938 "allocating a type link", NULL); 8939 return (-1); 8940 } 8941 link->type = NULL; 8942 link->next = NULL; 8943 if (lastLink == NULL) 8944 type->memberTypes = link; 8945 else 8946 lastLink->next = link; 8947 lastLink = link; 8948 /* 8949 * Create a reference item. 8950 */ 8951 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8952 localName, nsName); 8953 if (ref == NULL) { 8954 FREE_AND_NULL(tmp) 8955 return (-1); 8956 } 8957 /* 8958 * Assign the reference to the link, it will be resolved 8959 * later during fixup of the union simple type. 8960 */ 8961 link->type = (xmlSchemaTypePtr) ref; 8962 } 8963 FREE_AND_NULL(tmp) 8964 cur = end; 8965 } while (*cur != 0); 8966 8967 } 8968 /* 8969 * And now for the children... 8970 */ 8971 child = node->children; 8972 if (IS_SCHEMA(child, "annotation")) { 8973 /* 8974 * Add the annotation to the simple type ancestor. 8975 */ 8976 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8977 xmlSchemaParseAnnotation(ctxt, child, 1)); 8978 child = child->next; 8979 } 8980 if (IS_SCHEMA(child, "simpleType")) { 8981 xmlSchemaTypePtr subtype, last = NULL; 8982 8983 /* 8984 * Anchor the member types in the "subtypes" field of the 8985 * simple type. 8986 */ 8987 while (IS_SCHEMA(child, "simpleType")) { 8988 subtype = (xmlSchemaTypePtr) 8989 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8990 if (subtype != NULL) { 8991 if (last == NULL) { 8992 type->subtypes = subtype; 8993 last = subtype; 8994 } else { 8995 last->next = subtype; 8996 last = subtype; 8997 } 8998 last->next = NULL; 8999 } 9000 child = child->next; 9001 } 9002 } 9003 if (child != NULL) { 9004 xmlSchemaPContentErr(ctxt, 9005 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9006 NULL, node, child, NULL, "(annotation?, simpleType*)"); 9007 } 9008 if ((attr == NULL) && (type->subtypes == NULL)) { 9009 /* 9010 * src-union-memberTypes-or-simpleTypes 9011 * Either the memberTypes [attribute] of the <union> element must 9012 * be non-empty or there must be at least one simpleType [child]. 9013 */ 9014 xmlSchemaPCustomErr(ctxt, 9015 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9016 NULL, node, 9017 "Either the attribute 'memberTypes' or " 9018 "at least one <simpleType> child must be present", NULL); 9019 } 9020 return (0); 9021 } 9022 9023 /** 9024 * xmlSchemaParseList: 9025 * @ctxt: a schema validation context 9026 * @schema: the schema being built 9027 * @node: a subtree containing XML Schema informations 9028 * 9029 * parse a XML schema List definition 9030 * *WARNING* this interface is highly subject to change 9031 * 9032 * Returns -1 in case of error, 0 if the declaration is improper and 9033 * 1 in case of success. 9034 */ 9035 static xmlSchemaTypePtr 9036 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9037 xmlNodePtr node) 9038 { 9039 xmlSchemaTypePtr type; 9040 xmlNodePtr child = NULL; 9041 xmlAttrPtr attr; 9042 9043 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9044 return (NULL); 9045 /* Not a component, don't create it. */ 9046 type = ctxt->ctxtType; 9047 /* 9048 * Mark the type as being of variety "list". 9049 */ 9050 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9051 /* 9052 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9053 * then the `simple ur-type definition`." 9054 */ 9055 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9056 /* 9057 * Check for illegal attributes. 9058 */ 9059 attr = node->properties; 9060 while (attr != NULL) { 9061 if (attr->ns == NULL) { 9062 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9063 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9064 xmlSchemaPIllegalAttrErr(ctxt, 9065 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9066 } 9067 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9068 xmlSchemaPIllegalAttrErr(ctxt, 9069 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9070 } 9071 attr = attr->next; 9072 } 9073 9074 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9075 9076 /* 9077 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9078 * fields for holding the reference to the itemType. 9079 * 9080 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9081 * the "ref" fields. 9082 */ 9083 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9084 node, "itemType", &(type->baseNs), &(type->base)); 9085 /* 9086 * And now for the children... 9087 */ 9088 child = node->children; 9089 if (IS_SCHEMA(child, "annotation")) { 9090 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9091 xmlSchemaParseAnnotation(ctxt, child, 1)); 9092 child = child->next; 9093 } 9094 if (IS_SCHEMA(child, "simpleType")) { 9095 /* 9096 * src-list-itemType-or-simpleType 9097 * Either the itemType [attribute] or the <simpleType> [child] of 9098 * the <list> element must be present, but not both. 9099 */ 9100 if (type->base != NULL) { 9101 xmlSchemaPCustomErr(ctxt, 9102 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9103 NULL, node, 9104 "The attribute 'itemType' and the <simpleType> child " 9105 "are mutually exclusive", NULL); 9106 } else { 9107 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9108 } 9109 child = child->next; 9110 } else if (type->base == NULL) { 9111 xmlSchemaPCustomErr(ctxt, 9112 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9113 NULL, node, 9114 "Either the attribute 'itemType' or the <simpleType> child " 9115 "must be present", NULL); 9116 } 9117 if (child != NULL) { 9118 xmlSchemaPContentErr(ctxt, 9119 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9120 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9121 } 9122 if ((type->base == NULL) && 9123 (type->subtypes == NULL) && 9124 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9125 xmlSchemaPCustomErr(ctxt, 9126 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9127 NULL, node, 9128 "Either the attribute 'itemType' or the <simpleType> child " 9129 "must be present", NULL); 9130 } 9131 return (NULL); 9132 } 9133 9134 /** 9135 * xmlSchemaParseSimpleType: 9136 * @ctxt: a schema validation context 9137 * @schema: the schema being built 9138 * @node: a subtree containing XML Schema informations 9139 * 9140 * parse a XML schema Simple Type definition 9141 * *WARNING* this interface is highly subject to change 9142 * 9143 * Returns -1 in case of error, 0 if the declaration is improper and 9144 * 1 in case of success. 9145 */ 9146 static xmlSchemaTypePtr 9147 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9148 xmlNodePtr node, int topLevel) 9149 { 9150 xmlSchemaTypePtr type, oldCtxtType; 9151 xmlNodePtr child = NULL; 9152 const xmlChar *attrValue = NULL; 9153 xmlAttrPtr attr; 9154 int hasRestriction = 0; 9155 9156 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9157 return (NULL); 9158 9159 if (topLevel) { 9160 attr = xmlSchemaGetPropNode(node, "name"); 9161 if (attr == NULL) { 9162 xmlSchemaPMissingAttrErr(ctxt, 9163 XML_SCHEMAP_S4S_ATTR_MISSING, 9164 NULL, node, 9165 "name", NULL); 9166 return (NULL); 9167 } else { 9168 if (xmlSchemaPValAttrNode(ctxt, 9169 NULL, attr, 9170 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9171 return (NULL); 9172 /* 9173 * Skip built-in types. 9174 */ 9175 if (ctxt->isS4S) { 9176 xmlSchemaTypePtr biType; 9177 9178 if (ctxt->isRedefine) { 9179 /* 9180 * REDEFINE: Disallow redefinition of built-in-types. 9181 * TODO: It seems that the spec does not say anything 9182 * about this case. 9183 */ 9184 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9185 NULL, node, 9186 "Redefinition of built-in simple types is not " 9187 "supported", NULL); 9188 return(NULL); 9189 } 9190 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9191 if (biType != NULL) 9192 return (biType); 9193 } 9194 } 9195 } 9196 /* 9197 * TargetNamespace: 9198 * SPEC "The `actual value` of the targetNamespace [attribute] 9199 * of the <schema> ancestor element information item if present, 9200 * otherwise `absent`. 9201 */ 9202 if (topLevel == 0) { 9203 #ifdef ENABLE_NAMED_LOCALS 9204 char buf[40]; 9205 #endif 9206 /* 9207 * Parse as local simple type definition. 9208 */ 9209 #ifdef ENABLE_NAMED_LOCALS 9210 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9211 type = xmlSchemaAddType(ctxt, schema, 9212 XML_SCHEMA_TYPE_SIMPLE, 9213 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9214 ctxt->targetNamespace, node, 0); 9215 #else 9216 type = xmlSchemaAddType(ctxt, schema, 9217 XML_SCHEMA_TYPE_SIMPLE, 9218 NULL, ctxt->targetNamespace, node, 0); 9219 #endif 9220 if (type == NULL) 9221 return (NULL); 9222 type->type = XML_SCHEMA_TYPE_SIMPLE; 9223 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9224 /* 9225 * Check for illegal attributes. 9226 */ 9227 attr = node->properties; 9228 while (attr != NULL) { 9229 if (attr->ns == NULL) { 9230 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9231 xmlSchemaPIllegalAttrErr(ctxt, 9232 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9233 } 9234 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9235 xmlSchemaPIllegalAttrErr(ctxt, 9236 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9237 } 9238 attr = attr->next; 9239 } 9240 } else { 9241 /* 9242 * Parse as global simple type definition. 9243 * 9244 * Note that attrValue is the value of the attribute "name" here. 9245 */ 9246 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9247 attrValue, ctxt->targetNamespace, node, 1); 9248 if (type == NULL) 9249 return (NULL); 9250 type->type = XML_SCHEMA_TYPE_SIMPLE; 9251 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9252 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9253 /* 9254 * Check for illegal attributes. 9255 */ 9256 attr = node->properties; 9257 while (attr != NULL) { 9258 if (attr->ns == NULL) { 9259 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9260 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9261 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9262 xmlSchemaPIllegalAttrErr(ctxt, 9263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9264 } 9265 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9266 xmlSchemaPIllegalAttrErr(ctxt, 9267 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9268 } 9269 attr = attr->next; 9270 } 9271 /* 9272 * Attribute "final". 9273 */ 9274 attr = xmlSchemaGetPropNode(node, "final"); 9275 if (attr == NULL) { 9276 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9277 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9278 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9279 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9280 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9281 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9282 } else { 9283 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9284 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9285 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9286 XML_SCHEMAS_TYPE_FINAL_LIST, 9287 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9288 9289 xmlSchemaPSimpleTypeErr(ctxt, 9290 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9291 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9292 NULL, "(#all | List of (list | union | restriction)", 9293 attrValue, NULL, NULL, NULL); 9294 } 9295 } 9296 } 9297 type->targetNamespace = ctxt->targetNamespace; 9298 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9299 /* 9300 * And now for the children... 9301 */ 9302 oldCtxtType = ctxt->ctxtType; 9303 9304 ctxt->ctxtType = type; 9305 9306 child = node->children; 9307 if (IS_SCHEMA(child, "annotation")) { 9308 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9309 child = child->next; 9310 } 9311 if (child == NULL) { 9312 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9313 NULL, node, child, NULL, 9314 "(annotation?, (restriction | list | union))"); 9315 } else if (IS_SCHEMA(child, "restriction")) { 9316 xmlSchemaParseRestriction(ctxt, schema, child, 9317 XML_SCHEMA_TYPE_SIMPLE); 9318 hasRestriction = 1; 9319 child = child->next; 9320 } else if (IS_SCHEMA(child, "list")) { 9321 xmlSchemaParseList(ctxt, schema, child); 9322 child = child->next; 9323 } else if (IS_SCHEMA(child, "union")) { 9324 xmlSchemaParseUnion(ctxt, schema, child); 9325 child = child->next; 9326 } 9327 if (child != NULL) { 9328 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9329 NULL, node, child, NULL, 9330 "(annotation?, (restriction | list | union))"); 9331 } 9332 /* 9333 * REDEFINE: SPEC src-redefine (5) 9334 * "Within the [children], each <simpleType> must have a 9335 * <restriction> among its [children] ... the `actual value` of whose 9336 * base [attribute] must be the same as the `actual value` of its own 9337 * name attribute plus target namespace;" 9338 */ 9339 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9340 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9341 NULL, node, "This is a redefinition, thus the " 9342 "<simpleType> must have a <restriction> child", NULL); 9343 } 9344 9345 ctxt->ctxtType = oldCtxtType; 9346 return (type); 9347 } 9348 9349 /** 9350 * xmlSchemaParseModelGroupDefRef: 9351 * @ctxt: the parser context 9352 * @schema: the schema being built 9353 * @node: the node 9354 * 9355 * Parses a reference to a model group definition. 9356 * 9357 * We will return a particle component with a qname-component or 9358 * NULL in case of an error. 9359 */ 9360 static xmlSchemaTreeItemPtr 9361 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9362 xmlSchemaPtr schema, 9363 xmlNodePtr node) 9364 { 9365 xmlSchemaParticlePtr item; 9366 xmlNodePtr child = NULL; 9367 xmlAttrPtr attr; 9368 const xmlChar *ref = NULL, *refNs = NULL; 9369 int min, max; 9370 9371 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9372 return (NULL); 9373 9374 attr = xmlSchemaGetPropNode(node, "ref"); 9375 if (attr == NULL) { 9376 xmlSchemaPMissingAttrErr(ctxt, 9377 XML_SCHEMAP_S4S_ATTR_MISSING, 9378 NULL, node, "ref", NULL); 9379 return (NULL); 9380 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9381 attr, &refNs, &ref) != 0) { 9382 return (NULL); 9383 } 9384 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9385 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9386 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9387 "(xs:nonNegativeInteger | unbounded)"); 9388 /* 9389 * Check for illegal attributes. 9390 */ 9391 attr = node->properties; 9392 while (attr != NULL) { 9393 if (attr->ns == NULL) { 9394 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9395 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9396 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9397 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9398 xmlSchemaPIllegalAttrErr(ctxt, 9399 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9400 } 9401 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9402 xmlSchemaPIllegalAttrErr(ctxt, 9403 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9404 } 9405 attr = attr->next; 9406 } 9407 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9408 item = xmlSchemaAddParticle(ctxt, node, min, max); 9409 if (item == NULL) 9410 return (NULL); 9411 /* 9412 * Create a qname-reference and set as the term; it will be substituted 9413 * for the model group after the reference has been resolved. 9414 */ 9415 item->children = (xmlSchemaTreeItemPtr) 9416 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9417 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9418 /* 9419 * And now for the children... 9420 */ 9421 child = node->children; 9422 /* TODO: Is annotation even allowed for a model group reference? */ 9423 if (IS_SCHEMA(child, "annotation")) { 9424 /* 9425 * TODO: What to do exactly with the annotation? 9426 */ 9427 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9428 child = child->next; 9429 } 9430 if (child != NULL) { 9431 xmlSchemaPContentErr(ctxt, 9432 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9433 NULL, node, child, NULL, 9434 "(annotation?)"); 9435 } 9436 /* 9437 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9438 */ 9439 if ((min == 0) && (max == 0)) 9440 return (NULL); 9441 9442 return ((xmlSchemaTreeItemPtr) item); 9443 } 9444 9445 /** 9446 * xmlSchemaParseModelGroupDefinition: 9447 * @ctxt: a schema validation context 9448 * @schema: the schema being built 9449 * @node: a subtree containing XML Schema informations 9450 * 9451 * Parses a XML schema model group definition. 9452 * 9453 * Note that the contraint src-redefine (6.2) can't be applied until 9454 * references have been resolved. So we will do this at the 9455 * component fixup level. 9456 * 9457 * *WARNING* this interface is highly subject to change 9458 * 9459 * Returns -1 in case of error, 0 if the declaration is improper and 9460 * 1 in case of success. 9461 */ 9462 static xmlSchemaModelGroupDefPtr 9463 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9464 xmlSchemaPtr schema, 9465 xmlNodePtr node) 9466 { 9467 xmlSchemaModelGroupDefPtr item; 9468 xmlNodePtr child = NULL; 9469 xmlAttrPtr attr; 9470 const xmlChar *name; 9471 9472 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9473 return (NULL); 9474 9475 attr = xmlSchemaGetPropNode(node, "name"); 9476 if (attr == NULL) { 9477 xmlSchemaPMissingAttrErr(ctxt, 9478 XML_SCHEMAP_S4S_ATTR_MISSING, 9479 NULL, node, 9480 "name", NULL); 9481 return (NULL); 9482 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9483 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9484 return (NULL); 9485 } 9486 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9487 ctxt->targetNamespace, node); 9488 if (item == NULL) 9489 return (NULL); 9490 /* 9491 * Check for illegal attributes. 9492 */ 9493 attr = node->properties; 9494 while (attr != NULL) { 9495 if (attr->ns == NULL) { 9496 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9497 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9498 xmlSchemaPIllegalAttrErr(ctxt, 9499 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9500 } 9501 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9502 xmlSchemaPIllegalAttrErr(ctxt, 9503 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9504 } 9505 attr = attr->next; 9506 } 9507 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9508 /* 9509 * And now for the children... 9510 */ 9511 child = node->children; 9512 if (IS_SCHEMA(child, "annotation")) { 9513 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9514 child = child->next; 9515 } 9516 if (IS_SCHEMA(child, "all")) { 9517 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9518 XML_SCHEMA_TYPE_ALL, 0); 9519 child = child->next; 9520 } else if (IS_SCHEMA(child, "choice")) { 9521 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9522 XML_SCHEMA_TYPE_CHOICE, 0); 9523 child = child->next; 9524 } else if (IS_SCHEMA(child, "sequence")) { 9525 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9526 XML_SCHEMA_TYPE_SEQUENCE, 0); 9527 child = child->next; 9528 } 9529 9530 9531 9532 if (child != NULL) { 9533 xmlSchemaPContentErr(ctxt, 9534 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9535 NULL, node, child, NULL, 9536 "(annotation?, (all | choice | sequence)?)"); 9537 } 9538 return (item); 9539 } 9540 9541 /** 9542 * xmlSchemaCleanupDoc: 9543 * @ctxt: a schema validation context 9544 * @node: the root of the document. 9545 * 9546 * removes unwanted nodes in a schemas document tree 9547 */ 9548 static void 9549 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9550 { 9551 xmlNodePtr delete, cur; 9552 9553 if ((ctxt == NULL) || (root == NULL)) return; 9554 9555 /* 9556 * Remove all the blank text nodes 9557 */ 9558 delete = NULL; 9559 cur = root; 9560 while (cur != NULL) { 9561 if (delete != NULL) { 9562 xmlUnlinkNode(delete); 9563 xmlFreeNode(delete); 9564 delete = NULL; 9565 } 9566 if (cur->type == XML_TEXT_NODE) { 9567 if (IS_BLANK_NODE(cur)) { 9568 if (xmlNodeGetSpacePreserve(cur) != 1) { 9569 delete = cur; 9570 } 9571 } 9572 } else if ((cur->type != XML_ELEMENT_NODE) && 9573 (cur->type != XML_CDATA_SECTION_NODE)) { 9574 delete = cur; 9575 goto skip_children; 9576 } 9577 9578 /* 9579 * Skip to next node 9580 */ 9581 if (cur->children != NULL) { 9582 if ((cur->children->type != XML_ENTITY_DECL) && 9583 (cur->children->type != XML_ENTITY_REF_NODE) && 9584 (cur->children->type != XML_ENTITY_NODE)) { 9585 cur = cur->children; 9586 continue; 9587 } 9588 } 9589 skip_children: 9590 if (cur->next != NULL) { 9591 cur = cur->next; 9592 continue; 9593 } 9594 9595 do { 9596 cur = cur->parent; 9597 if (cur == NULL) 9598 break; 9599 if (cur == root) { 9600 cur = NULL; 9601 break; 9602 } 9603 if (cur->next != NULL) { 9604 cur = cur->next; 9605 break; 9606 } 9607 } while (cur != NULL); 9608 } 9609 if (delete != NULL) { 9610 xmlUnlinkNode(delete); 9611 xmlFreeNode(delete); 9612 delete = NULL; 9613 } 9614 } 9615 9616 9617 static void 9618 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9619 { 9620 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9621 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9622 9623 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9624 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9625 9626 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9627 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9628 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9629 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9630 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9631 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9632 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9633 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9634 9635 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9636 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9637 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9638 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9639 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9640 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9641 } 9642 9643 static int 9644 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9645 xmlSchemaPtr schema, 9646 xmlNodePtr node) 9647 { 9648 xmlAttrPtr attr; 9649 const xmlChar *val; 9650 int res = 0, oldErrs = ctxt->nberrors; 9651 9652 /* 9653 * Those flags should be moved to the parser context flags, 9654 * since they are not visible at the component level. I.e. 9655 * they are used if processing schema *documents* only. 9656 */ 9657 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9658 HFAILURE; 9659 9660 /* 9661 * Since the version is of type xs:token, we won't bother to 9662 * check it. 9663 */ 9664 /* REMOVED: 9665 attr = xmlSchemaGetPropNode(node, "version"); 9666 if (attr != NULL) { 9667 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9668 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9669 HFAILURE; 9670 } 9671 */ 9672 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9673 if (attr != NULL) { 9674 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9675 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9676 HFAILURE; 9677 if (res != 0) { 9678 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9679 goto exit; 9680 } 9681 } 9682 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9683 if (attr != NULL) { 9684 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9685 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9686 XML_SCHEMAS_QUALIF_ELEM); 9687 HFAILURE; 9688 if (res != 0) { 9689 xmlSchemaPSimpleTypeErr(ctxt, 9690 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9691 NULL, (xmlNodePtr) attr, NULL, 9692 "(qualified | unqualified)", val, NULL, NULL, NULL); 9693 } 9694 } 9695 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9696 if (attr != NULL) { 9697 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9698 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9699 XML_SCHEMAS_QUALIF_ATTR); 9700 HFAILURE; 9701 if (res != 0) { 9702 xmlSchemaPSimpleTypeErr(ctxt, 9703 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9704 NULL, (xmlNodePtr) attr, NULL, 9705 "(qualified | unqualified)", val, NULL, NULL, NULL); 9706 } 9707 } 9708 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9709 if (attr != NULL) { 9710 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9711 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9712 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9713 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9714 -1, 9715 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9716 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9717 HFAILURE; 9718 if (res != 0) { 9719 xmlSchemaPSimpleTypeErr(ctxt, 9720 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9721 NULL, (xmlNodePtr) attr, NULL, 9722 "(#all | List of (extension | restriction | list | union))", 9723 val, NULL, NULL, NULL); 9724 } 9725 } 9726 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9727 if (attr != NULL) { 9728 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9729 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9730 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9731 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9732 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9733 HFAILURE; 9734 if (res != 0) { 9735 xmlSchemaPSimpleTypeErr(ctxt, 9736 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9737 NULL, (xmlNodePtr) attr, NULL, 9738 "(#all | List of (extension | restriction | substitution))", 9739 val, NULL, NULL, NULL); 9740 } 9741 } 9742 9743 exit: 9744 if (oldErrs != ctxt->nberrors) 9745 res = ctxt->err; 9746 return(res); 9747 exit_failure: 9748 return(-1); 9749 } 9750 9751 /** 9752 * xmlSchemaParseSchemaTopLevel: 9753 * @ctxt: a schema validation context 9754 * @schema: the schemas 9755 * @nodes: the list of top level nodes 9756 * 9757 * Returns the internal XML Schema structure built from the resource or 9758 * NULL in case of error 9759 */ 9760 static int 9761 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9762 xmlSchemaPtr schema, xmlNodePtr nodes) 9763 { 9764 xmlNodePtr child; 9765 xmlSchemaAnnotPtr annot; 9766 int res = 0, oldErrs, tmpOldErrs; 9767 9768 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9769 return(-1); 9770 9771 oldErrs = ctxt->nberrors; 9772 child = nodes; 9773 while ((IS_SCHEMA(child, "include")) || 9774 (IS_SCHEMA(child, "import")) || 9775 (IS_SCHEMA(child, "redefine")) || 9776 (IS_SCHEMA(child, "annotation"))) { 9777 if (IS_SCHEMA(child, "annotation")) { 9778 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9779 if (schema->annot == NULL) 9780 schema->annot = annot; 9781 else 9782 xmlSchemaFreeAnnot(annot); 9783 } else if (IS_SCHEMA(child, "import")) { 9784 tmpOldErrs = ctxt->nberrors; 9785 res = xmlSchemaParseImport(ctxt, schema, child); 9786 HFAILURE; 9787 HSTOP(ctxt); 9788 if (tmpOldErrs != ctxt->nberrors) 9789 goto exit; 9790 } else if (IS_SCHEMA(child, "include")) { 9791 tmpOldErrs = ctxt->nberrors; 9792 res = xmlSchemaParseInclude(ctxt, schema, child); 9793 HFAILURE; 9794 HSTOP(ctxt); 9795 if (tmpOldErrs != ctxt->nberrors) 9796 goto exit; 9797 } else if (IS_SCHEMA(child, "redefine")) { 9798 tmpOldErrs = ctxt->nberrors; 9799 res = xmlSchemaParseRedefine(ctxt, schema, child); 9800 HFAILURE; 9801 HSTOP(ctxt); 9802 if (tmpOldErrs != ctxt->nberrors) 9803 goto exit; 9804 } 9805 child = child->next; 9806 } 9807 /* 9808 * URGENT TODO: Change the functions to return int results. 9809 * We need especially to catch internal errors. 9810 */ 9811 while (child != NULL) { 9812 if (IS_SCHEMA(child, "complexType")) { 9813 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9814 child = child->next; 9815 } else if (IS_SCHEMA(child, "simpleType")) { 9816 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9817 child = child->next; 9818 } else if (IS_SCHEMA(child, "element")) { 9819 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9820 child = child->next; 9821 } else if (IS_SCHEMA(child, "attribute")) { 9822 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9823 child = child->next; 9824 } else if (IS_SCHEMA(child, "attributeGroup")) { 9825 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9826 child = child->next; 9827 } else if (IS_SCHEMA(child, "group")) { 9828 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9829 child = child->next; 9830 } else if (IS_SCHEMA(child, "notation")) { 9831 xmlSchemaParseNotation(ctxt, schema, child); 9832 child = child->next; 9833 } else { 9834 xmlSchemaPContentErr(ctxt, 9835 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9836 NULL, child->parent, child, 9837 NULL, "((include | import | redefine | annotation)*, " 9838 "(((simpleType | complexType | group | attributeGroup) " 9839 "| element | attribute | notation), annotation*)*)"); 9840 child = child->next; 9841 } 9842 while (IS_SCHEMA(child, "annotation")) { 9843 /* 9844 * TODO: We should add all annotations. 9845 */ 9846 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9847 if (schema->annot == NULL) 9848 schema->annot = annot; 9849 else 9850 xmlSchemaFreeAnnot(annot); 9851 child = child->next; 9852 } 9853 } 9854 exit: 9855 ctxt->ctxtType = NULL; 9856 if (oldErrs != ctxt->nberrors) 9857 res = ctxt->err; 9858 return(res); 9859 exit_failure: 9860 return(-1); 9861 } 9862 9863 static xmlSchemaSchemaRelationPtr 9864 xmlSchemaSchemaRelationCreate(void) 9865 { 9866 xmlSchemaSchemaRelationPtr ret; 9867 9868 ret = (xmlSchemaSchemaRelationPtr) 9869 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9870 if (ret == NULL) { 9871 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9872 return(NULL); 9873 } 9874 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9875 return(ret); 9876 } 9877 9878 #if 0 9879 static void 9880 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9881 { 9882 xmlFree(rel); 9883 } 9884 #endif 9885 9886 static void 9887 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9888 { 9889 xmlSchemaRedefPtr prev; 9890 9891 while (redef != NULL) { 9892 prev = redef; 9893 redef = redef->next; 9894 xmlFree(prev); 9895 } 9896 } 9897 9898 static void 9899 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9900 { 9901 /* 9902 * After the construction context has been freed, there will be 9903 * no schema graph available any more. Only the schema buckets 9904 * will stay alive, which are put into the "schemasImports" and 9905 * "includes" slots of the xmlSchema. 9906 */ 9907 if (con->buckets != NULL) 9908 xmlSchemaItemListFree(con->buckets); 9909 if (con->pending != NULL) 9910 xmlSchemaItemListFree(con->pending); 9911 if (con->substGroups != NULL) 9912 xmlHashFree(con->substGroups, 9913 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9914 if (con->redefs != NULL) 9915 xmlSchemaRedefListFree(con->redefs); 9916 if (con->dict != NULL) 9917 xmlDictFree(con->dict); 9918 xmlFree(con); 9919 } 9920 9921 static xmlSchemaConstructionCtxtPtr 9922 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9923 { 9924 xmlSchemaConstructionCtxtPtr ret; 9925 9926 ret = (xmlSchemaConstructionCtxtPtr) 9927 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9928 if (ret == NULL) { 9929 xmlSchemaPErrMemory(NULL, 9930 "allocating schema construction context", NULL); 9931 return (NULL); 9932 } 9933 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9934 9935 ret->buckets = xmlSchemaItemListCreate(); 9936 if (ret->buckets == NULL) { 9937 xmlSchemaPErrMemory(NULL, 9938 "allocating list of schema buckets", NULL); 9939 xmlFree(ret); 9940 return (NULL); 9941 } 9942 ret->pending = xmlSchemaItemListCreate(); 9943 if (ret->pending == NULL) { 9944 xmlSchemaPErrMemory(NULL, 9945 "allocating list of pending global components", NULL); 9946 xmlSchemaConstructionCtxtFree(ret); 9947 return (NULL); 9948 } 9949 ret->dict = dict; 9950 xmlDictReference(dict); 9951 return(ret); 9952 } 9953 9954 static xmlSchemaParserCtxtPtr 9955 xmlSchemaParserCtxtCreate(void) 9956 { 9957 xmlSchemaParserCtxtPtr ret; 9958 9959 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9960 if (ret == NULL) { 9961 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9962 NULL); 9963 return (NULL); 9964 } 9965 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9966 ret->type = XML_SCHEMA_CTXT_PARSER; 9967 ret->attrProhibs = xmlSchemaItemListCreate(); 9968 if (ret->attrProhibs == NULL) { 9969 xmlFree(ret); 9970 return(NULL); 9971 } 9972 return(ret); 9973 } 9974 9975 /** 9976 * xmlSchemaNewParserCtxtUseDict: 9977 * @URL: the location of the schema 9978 * @dict: the dictionary to be used 9979 * 9980 * Create an XML Schemas parse context for that file/resource expected 9981 * to contain an XML Schemas file. 9982 * 9983 * Returns the parser context or NULL in case of error 9984 */ 9985 static xmlSchemaParserCtxtPtr 9986 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9987 { 9988 xmlSchemaParserCtxtPtr ret; 9989 9990 ret = xmlSchemaParserCtxtCreate(); 9991 if (ret == NULL) 9992 return (NULL); 9993 ret->dict = dict; 9994 xmlDictReference(dict); 9995 if (URL != NULL) 9996 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9997 return (ret); 9998 } 9999 10000 static int 10001 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 10002 { 10003 if (vctxt->pctxt == NULL) { 10004 if (vctxt->schema != NULL) 10005 vctxt->pctxt = 10006 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 10007 else 10008 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 10009 if (vctxt->pctxt == NULL) { 10010 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 10011 "failed to create a temp. parser context"); 10012 return (-1); 10013 } 10014 /* TODO: Pass user data. */ 10015 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10016 vctxt->warning, vctxt->errCtxt); 10017 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10018 vctxt->errCtxt); 10019 } 10020 return (0); 10021 } 10022 10023 /** 10024 * xmlSchemaGetSchemaBucket: 10025 * @pctxt: the schema parser context 10026 * @schemaLocation: the URI of the schema document 10027 * 10028 * Returns a schema bucket if it was already parsed. 10029 * 10030 * Returns a schema bucket if it was already parsed from 10031 * @schemaLocation, NULL otherwise. 10032 */ 10033 static xmlSchemaBucketPtr 10034 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10035 const xmlChar *schemaLocation) 10036 { 10037 xmlSchemaBucketPtr cur; 10038 xmlSchemaItemListPtr list; 10039 10040 list = pctxt->constructor->buckets; 10041 if (list->nbItems == 0) 10042 return(NULL); 10043 else { 10044 int i; 10045 for (i = 0; i < list->nbItems; i++) { 10046 cur = (xmlSchemaBucketPtr) list->items[i]; 10047 /* Pointer comparison! */ 10048 if (cur->schemaLocation == schemaLocation) 10049 return(cur); 10050 } 10051 } 10052 return(NULL); 10053 } 10054 10055 static xmlSchemaBucketPtr 10056 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10057 const xmlChar *schemaLocation, 10058 const xmlChar *targetNamespace) 10059 { 10060 xmlSchemaBucketPtr cur; 10061 xmlSchemaItemListPtr list; 10062 10063 list = pctxt->constructor->buckets; 10064 if (list->nbItems == 0) 10065 return(NULL); 10066 else { 10067 int i; 10068 for (i = 0; i < list->nbItems; i++) { 10069 cur = (xmlSchemaBucketPtr) list->items[i]; 10070 /* Pointer comparison! */ 10071 if ((cur->origTargetNamespace == NULL) && 10072 (cur->schemaLocation == schemaLocation) && 10073 (cur->targetNamespace == targetNamespace)) 10074 return(cur); 10075 } 10076 } 10077 return(NULL); 10078 } 10079 10080 10081 #define IS_BAD_SCHEMA_DOC(b) \ 10082 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10083 10084 static xmlSchemaBucketPtr 10085 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10086 const xmlChar *targetNamespace, 10087 int imported) 10088 { 10089 xmlSchemaBucketPtr cur; 10090 xmlSchemaItemListPtr list; 10091 10092 list = pctxt->constructor->buckets; 10093 if (list->nbItems == 0) 10094 return(NULL); 10095 else { 10096 int i; 10097 for (i = 0; i < list->nbItems; i++) { 10098 cur = (xmlSchemaBucketPtr) list->items[i]; 10099 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10100 (cur->origTargetNamespace == targetNamespace) && 10101 ((imported && cur->imported) || 10102 ((!imported) && (!cur->imported)))) 10103 return(cur); 10104 } 10105 } 10106 return(NULL); 10107 } 10108 10109 static int 10110 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10111 xmlSchemaPtr schema, 10112 xmlSchemaBucketPtr bucket) 10113 { 10114 int oldFlags; 10115 xmlDocPtr oldDoc; 10116 xmlNodePtr node; 10117 int ret, oldErrs; 10118 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10119 10120 /* 10121 * Save old values; reset the *main* schema. 10122 * URGENT TODO: This is not good; move the per-document information 10123 * to the parser. Get rid of passing the main schema to the 10124 * parsing functions. 10125 */ 10126 oldFlags = schema->flags; 10127 oldDoc = schema->doc; 10128 if (schema->flags != 0) 10129 xmlSchemaClearSchemaDefaults(schema); 10130 schema->doc = bucket->doc; 10131 pctxt->schema = schema; 10132 /* 10133 * Keep the current target namespace on the parser *not* on the 10134 * main schema. 10135 */ 10136 pctxt->targetNamespace = bucket->targetNamespace; 10137 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10138 10139 if ((bucket->targetNamespace != NULL) && 10140 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10141 /* 10142 * We are parsing the schema for schemas! 10143 */ 10144 pctxt->isS4S = 1; 10145 } 10146 /* Mark it as parsed, even if parsing fails. */ 10147 bucket->parsed++; 10148 /* Compile the schema doc. */ 10149 node = xmlDocGetRootElement(bucket->doc); 10150 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10151 if (ret != 0) 10152 goto exit; 10153 /* An empty schema; just get out. */ 10154 if (node->children == NULL) 10155 goto exit; 10156 oldErrs = pctxt->nberrors; 10157 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10158 if (ret != 0) 10159 goto exit; 10160 /* 10161 * TODO: Not nice, but I'm not 100% sure we will get always an error 10162 * as a result of the obove functions; so better rely on pctxt->err 10163 * as well. 10164 */ 10165 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10166 ret = pctxt->err; 10167 goto exit; 10168 } 10169 10170 exit: 10171 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10172 /* Restore schema values. */ 10173 schema->doc = oldDoc; 10174 schema->flags = oldFlags; 10175 return(ret); 10176 } 10177 10178 static int 10179 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10180 xmlSchemaPtr schema, 10181 xmlSchemaBucketPtr bucket) 10182 { 10183 xmlSchemaParserCtxtPtr newpctxt; 10184 int res = 0; 10185 10186 if (bucket == NULL) 10187 return(0); 10188 if (bucket->parsed) { 10189 PERROR_INT("xmlSchemaParseNewDoc", 10190 "reparsing a schema doc"); 10191 return(-1); 10192 } 10193 if (bucket->doc == NULL) { 10194 PERROR_INT("xmlSchemaParseNewDoc", 10195 "parsing a schema doc, but there's no doc"); 10196 return(-1); 10197 } 10198 if (pctxt->constructor == NULL) { 10199 PERROR_INT("xmlSchemaParseNewDoc", 10200 "no constructor"); 10201 return(-1); 10202 } 10203 /* Create and init the temporary parser context. */ 10204 newpctxt = xmlSchemaNewParserCtxtUseDict( 10205 (const char *) bucket->schemaLocation, pctxt->dict); 10206 if (newpctxt == NULL) 10207 return(-1); 10208 newpctxt->constructor = pctxt->constructor; 10209 /* 10210 * TODO: Can we avoid that the parser knows about the main schema? 10211 * It would be better if he knows about the current schema bucket 10212 * only. 10213 */ 10214 newpctxt->schema = schema; 10215 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10216 pctxt->errCtxt); 10217 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10218 pctxt->errCtxt); 10219 newpctxt->counter = pctxt->counter; 10220 10221 10222 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10223 10224 /* Channel back errors and cleanup the temporary parser context. */ 10225 if (res != 0) 10226 pctxt->err = res; 10227 pctxt->nberrors += newpctxt->nberrors; 10228 pctxt->counter = newpctxt->counter; 10229 newpctxt->constructor = NULL; 10230 /* Free the parser context. */ 10231 xmlSchemaFreeParserCtxt(newpctxt); 10232 return(res); 10233 } 10234 10235 static void 10236 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10237 xmlSchemaSchemaRelationPtr rel) 10238 { 10239 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10240 10241 if (cur == NULL) { 10242 bucket->relations = rel; 10243 return; 10244 } 10245 while (cur->next != NULL) 10246 cur = cur->next; 10247 cur->next = rel; 10248 } 10249 10250 10251 static const xmlChar * 10252 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10253 xmlNodePtr ctxtNode) 10254 { 10255 /* 10256 * Build an absolue location URI. 10257 */ 10258 if (location != NULL) { 10259 if (ctxtNode == NULL) 10260 return(location); 10261 else { 10262 xmlChar *base, *URI; 10263 const xmlChar *ret = NULL; 10264 10265 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10266 if (base == NULL) { 10267 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10268 } else { 10269 URI = xmlBuildURI(location, base); 10270 xmlFree(base); 10271 } 10272 if (URI != NULL) { 10273 ret = xmlDictLookup(dict, URI, -1); 10274 xmlFree(URI); 10275 return(ret); 10276 } 10277 } 10278 } 10279 return(NULL); 10280 } 10281 10282 10283 10284 /** 10285 * xmlSchemaAddSchemaDoc: 10286 * @pctxt: a schema validation context 10287 * @schema: the schema being built 10288 * @node: a subtree containing XML Schema informations 10289 * 10290 * Parse an included (and to-be-redefined) XML schema document. 10291 * 10292 * Returns 0 on success, a positive error code on errors and 10293 * -1 in case of an internal or API error. 10294 */ 10295 10296 static int 10297 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10298 int type, /* import or include or redefine */ 10299 const xmlChar *schemaLocation, 10300 xmlDocPtr schemaDoc, 10301 const char *schemaBuffer, 10302 int schemaBufferLen, 10303 xmlNodePtr invokingNode, 10304 const xmlChar *sourceTargetNamespace, 10305 const xmlChar *importNamespace, 10306 xmlSchemaBucketPtr *bucket) 10307 { 10308 const xmlChar *targetNamespace = NULL; 10309 xmlSchemaSchemaRelationPtr relation = NULL; 10310 xmlDocPtr doc = NULL; 10311 int res = 0, err = 0, located = 0, preserveDoc = 0; 10312 xmlSchemaBucketPtr bkt = NULL; 10313 10314 if (bucket != NULL) 10315 *bucket = NULL; 10316 10317 switch (type) { 10318 case XML_SCHEMA_SCHEMA_IMPORT: 10319 case XML_SCHEMA_SCHEMA_MAIN: 10320 err = XML_SCHEMAP_SRC_IMPORT; 10321 break; 10322 case XML_SCHEMA_SCHEMA_INCLUDE: 10323 err = XML_SCHEMAP_SRC_INCLUDE; 10324 break; 10325 case XML_SCHEMA_SCHEMA_REDEFINE: 10326 err = XML_SCHEMAP_SRC_REDEFINE; 10327 break; 10328 } 10329 10330 10331 /* Special handling for the main schema: 10332 * skip the location and relation logic and just parse the doc. 10333 * We need just a bucket to be returned in this case. 10334 */ 10335 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10336 goto doc_load; 10337 10338 /* Note that we expect the location to be an absulute URI. */ 10339 if (schemaLocation != NULL) { 10340 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10341 if ((bkt != NULL) && 10342 (pctxt->constructor->bucket == bkt)) { 10343 /* Report self-imports/inclusions/redefinitions. */ 10344 10345 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10346 invokingNode, NULL, 10347 "The schema must not import/include/redefine itself", 10348 NULL, NULL); 10349 goto exit; 10350 } 10351 } 10352 /* 10353 * Create a relation for the graph of schemas. 10354 */ 10355 relation = xmlSchemaSchemaRelationCreate(); 10356 if (relation == NULL) 10357 return(-1); 10358 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10359 relation); 10360 relation->type = type; 10361 10362 /* 10363 * Save the namespace import information. 10364 */ 10365 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10366 relation->importNamespace = importNamespace; 10367 if (schemaLocation == NULL) { 10368 /* 10369 * No location; this is just an import of the namespace. 10370 * Note that we don't assign a bucket to the relation 10371 * in this case. 10372 */ 10373 goto exit; 10374 } 10375 targetNamespace = importNamespace; 10376 } 10377 10378 /* Did we already fetch the doc? */ 10379 if (bkt != NULL) { 10380 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10381 /* 10382 * We included/redefined and then try to import a schema, 10383 * but the new location provided for import was different. 10384 */ 10385 if (schemaLocation == NULL) 10386 schemaLocation = BAD_CAST "in_memory_buffer"; 10387 if (!xmlStrEqual(schemaLocation, 10388 bkt->schemaLocation)) { 10389 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10390 invokingNode, NULL, 10391 "The schema document '%s' cannot be imported, since " 10392 "it was already included or redefined", 10393 schemaLocation, NULL); 10394 goto exit; 10395 } 10396 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10397 /* 10398 * We imported and then try to include/redefine a schema, 10399 * but the new location provided for the include/redefine 10400 * was different. 10401 */ 10402 if (schemaLocation == NULL) 10403 schemaLocation = BAD_CAST "in_memory_buffer"; 10404 if (!xmlStrEqual(schemaLocation, 10405 bkt->schemaLocation)) { 10406 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10407 invokingNode, NULL, 10408 "The schema document '%s' cannot be included or " 10409 "redefined, since it was already imported", 10410 schemaLocation, NULL); 10411 goto exit; 10412 } 10413 } 10414 } 10415 10416 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10417 /* 10418 * Given that the schemaLocation [attribute] is only a hint, it is open 10419 * to applications to ignore all but the first <import> for a given 10420 * namespace, regardless of the `actual value` of schemaLocation, but 10421 * such a strategy risks missing useful information when new 10422 * schemaLocations are offered. 10423 * 10424 * We will use the first <import> that comes with a location. 10425 * Further <import>s *with* a location, will result in an error. 10426 * TODO: Better would be to just report a warning here, but 10427 * we'll try it this way until someone complains. 10428 * 10429 * Schema Document Location Strategy: 10430 * 3 Based on the namespace name, identify an existing schema document, 10431 * either as a resource which is an XML document or a <schema> element 10432 * information item, in some local schema repository; 10433 * 5 Attempt to resolve the namespace name to locate such a resource. 10434 * 10435 * NOTE: (3) and (5) are not supported. 10436 */ 10437 if (bkt != NULL) { 10438 relation->bucket = bkt; 10439 goto exit; 10440 } 10441 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10442 importNamespace, 1); 10443 10444 if (bkt != NULL) { 10445 relation->bucket = bkt; 10446 if (bkt->schemaLocation == NULL) { 10447 /* First given location of the schema; load the doc. */ 10448 bkt->schemaLocation = schemaLocation; 10449 } else { 10450 if (!xmlStrEqual(schemaLocation, 10451 bkt->schemaLocation)) { 10452 /* 10453 * Additional location given; just skip it. 10454 * URGENT TODO: We should report a warning here. 10455 * res = XML_SCHEMAP_SRC_IMPORT; 10456 */ 10457 if (schemaLocation == NULL) 10458 schemaLocation = BAD_CAST "in_memory_buffer"; 10459 10460 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10461 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10462 invokingNode, NULL, 10463 "Skipping import of schema located at '%s' for the " 10464 "namespace '%s', since this namespace was already " 10465 "imported with the schema located at '%s'", 10466 schemaLocation, importNamespace, bkt->schemaLocation); 10467 } 10468 goto exit; 10469 } 10470 } 10471 /* 10472 * No bucket + first location: load the doc and create a 10473 * bucket. 10474 */ 10475 } else { 10476 /* <include> and <redefine> */ 10477 if (bkt != NULL) { 10478 10479 if ((bkt->origTargetNamespace == NULL) && 10480 (bkt->targetNamespace != sourceTargetNamespace)) { 10481 xmlSchemaBucketPtr chamel; 10482 10483 /* 10484 * Chameleon include/redefine: skip loading only if it was 10485 * aleady build for the targetNamespace of the including 10486 * schema. 10487 */ 10488 /* 10489 * URGENT TODO: If the schema is a chameleon-include then copy 10490 * the components into the including schema and modify the 10491 * targetNamespace of those components, do nothing otherwise. 10492 * NOTE: This is currently worked-around by compiling the 10493 * chameleon for every destinct including targetNamespace; thus 10494 * not performant at the moment. 10495 * TODO: Check when the namespace in wildcards for chameleons 10496 * needs to be converted: before we built wildcard intersections 10497 * or after. 10498 * Answer: after! 10499 */ 10500 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10501 schemaLocation, sourceTargetNamespace); 10502 if (chamel != NULL) { 10503 /* A fitting chameleon was already parsed; NOP. */ 10504 relation->bucket = chamel; 10505 goto exit; 10506 } 10507 /* 10508 * We need to parse the chameleon again for a different 10509 * targetNamespace. 10510 * CHAMELEON TODO: Optimize this by only parsing the 10511 * chameleon once, and then copying the components to 10512 * the new targetNamespace. 10513 */ 10514 bkt = NULL; 10515 } else { 10516 relation->bucket = bkt; 10517 goto exit; 10518 } 10519 } 10520 } 10521 if ((bkt != NULL) && (bkt->doc != NULL)) { 10522 PERROR_INT("xmlSchemaAddSchemaDoc", 10523 "trying to load a schema doc, but a doc is already " 10524 "assigned to the schema bucket"); 10525 goto exit_failure; 10526 } 10527 10528 doc_load: 10529 /* 10530 * Load the document. 10531 */ 10532 if (schemaDoc != NULL) { 10533 doc = schemaDoc; 10534 /* Don' free this one, since it was provided by the caller. */ 10535 preserveDoc = 1; 10536 /* TODO: Does the context or the doc hold the location? */ 10537 if (schemaDoc->URL != NULL) 10538 schemaLocation = xmlDictLookup(pctxt->dict, 10539 schemaDoc->URL, -1); 10540 else 10541 schemaLocation = BAD_CAST "in_memory_buffer"; 10542 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10543 xmlParserCtxtPtr parserCtxt; 10544 10545 parserCtxt = xmlNewParserCtxt(); 10546 if (parserCtxt == NULL) { 10547 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10548 "allocating a parser context", NULL); 10549 goto exit_failure; 10550 } 10551 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10552 /* 10553 * TODO: Do we have to burden the schema parser dict with all 10554 * the content of the schema doc? 10555 */ 10556 xmlDictFree(parserCtxt->dict); 10557 parserCtxt->dict = pctxt->dict; 10558 xmlDictReference(parserCtxt->dict); 10559 } 10560 if (schemaLocation != NULL) { 10561 /* Parse from file. */ 10562 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10563 NULL, SCHEMAS_PARSE_OPTIONS); 10564 } else if (schemaBuffer != NULL) { 10565 /* Parse from memory buffer. */ 10566 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10567 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10568 schemaLocation = BAD_CAST "in_memory_buffer"; 10569 if (doc != NULL) 10570 doc->URL = xmlStrdup(schemaLocation); 10571 } 10572 /* 10573 * For <import>: 10574 * 2.1 The referent is (a fragment of) a resource which is an 10575 * XML document (see clause 1.1), which in turn corresponds to 10576 * a <schema> element information item in a well-formed information 10577 * set, which in turn corresponds to a valid schema. 10578 * TODO: (2.1) fragments of XML documents are not supported. 10579 * 10580 * 2.2 The referent is a <schema> element information item in 10581 * a well-formed information set, which in turn corresponds 10582 * to a valid schema. 10583 * TODO: (2.2) is not supported. 10584 */ 10585 if (doc == NULL) { 10586 xmlErrorPtr lerr; 10587 lerr = xmlGetLastError(); 10588 /* 10589 * Check if this a parser error, or if the document could 10590 * just not be located. 10591 * TODO: Try to find specific error codes to react only on 10592 * localisation failures. 10593 */ 10594 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10595 /* 10596 * We assume a parser error here. 10597 */ 10598 located = 1; 10599 /* TODO: Error code ?? */ 10600 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10601 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10602 invokingNode, NULL, 10603 "Failed to parse the XML resource '%s'", 10604 schemaLocation, NULL); 10605 } 10606 } 10607 xmlFreeParserCtxt(parserCtxt); 10608 if ((doc == NULL) && located) 10609 goto exit_error; 10610 } else { 10611 xmlSchemaPErr(pctxt, NULL, 10612 XML_SCHEMAP_NOTHING_TO_PARSE, 10613 "No information for parsing was provided with the " 10614 "given schema parser context.\n", 10615 NULL, NULL); 10616 goto exit_failure; 10617 } 10618 /* 10619 * Preprocess the document. 10620 */ 10621 if (doc != NULL) { 10622 xmlNodePtr docElem = NULL; 10623 10624 located = 1; 10625 docElem = xmlDocGetRootElement(doc); 10626 if (docElem == NULL) { 10627 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10628 invokingNode, NULL, 10629 "The document '%s' has no document element", 10630 schemaLocation, NULL); 10631 goto exit_error; 10632 } 10633 /* 10634 * Remove all the blank text nodes. 10635 */ 10636 xmlSchemaCleanupDoc(pctxt, docElem); 10637 /* 10638 * Check the schema's top level element. 10639 */ 10640 if (!IS_SCHEMA(docElem, "schema")) { 10641 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10642 invokingNode, NULL, 10643 "The XML document '%s' is not a schema document", 10644 schemaLocation, NULL); 10645 goto exit_error; 10646 } 10647 /* 10648 * Note that we don't apply a type check for the 10649 * targetNamespace value here. 10650 */ 10651 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10652 "targetNamespace"); 10653 } 10654 10655 /* after_doc_loading: */ 10656 if ((bkt == NULL) && located) { 10657 /* Only create a bucket if the schema was located. */ 10658 bkt = xmlSchemaBucketCreate(pctxt, type, 10659 targetNamespace); 10660 if (bkt == NULL) 10661 goto exit_failure; 10662 } 10663 if (bkt != NULL) { 10664 bkt->schemaLocation = schemaLocation; 10665 bkt->located = located; 10666 if (doc != NULL) { 10667 bkt->doc = doc; 10668 bkt->targetNamespace = targetNamespace; 10669 bkt->origTargetNamespace = targetNamespace; 10670 if (preserveDoc) 10671 bkt->preserveDoc = 1; 10672 } 10673 if (WXS_IS_BUCKET_IMPMAIN(type)) 10674 bkt->imported++; 10675 /* 10676 * Add it to the graph of schemas. 10677 */ 10678 if (relation != NULL) 10679 relation->bucket = bkt; 10680 } 10681 10682 exit: 10683 /* 10684 * Return the bucket explicitely; this is needed for the 10685 * main schema. 10686 */ 10687 if (bucket != NULL) 10688 *bucket = bkt; 10689 return (0); 10690 10691 exit_error: 10692 if ((doc != NULL) && (! preserveDoc)) { 10693 xmlFreeDoc(doc); 10694 if (bkt != NULL) 10695 bkt->doc = NULL; 10696 } 10697 return(pctxt->err); 10698 10699 exit_failure: 10700 if ((doc != NULL) && (! preserveDoc)) { 10701 xmlFreeDoc(doc); 10702 if (bkt != NULL) 10703 bkt->doc = NULL; 10704 } 10705 return (-1); 10706 } 10707 10708 /** 10709 * xmlSchemaParseImport: 10710 * @ctxt: a schema validation context 10711 * @schema: the schema being built 10712 * @node: a subtree containing XML Schema informations 10713 * 10714 * parse a XML schema Import definition 10715 * *WARNING* this interface is highly subject to change 10716 * 10717 * Returns 0 in case of success, a positive error code if 10718 * not valid and -1 in case of an internal error. 10719 */ 10720 static int 10721 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10722 xmlNodePtr node) 10723 { 10724 xmlNodePtr child; 10725 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10726 const xmlChar *thisTargetNamespace; 10727 xmlAttrPtr attr; 10728 int ret = 0; 10729 xmlSchemaBucketPtr bucket = NULL; 10730 10731 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10732 return (-1); 10733 10734 /* 10735 * Check for illegal attributes. 10736 */ 10737 attr = node->properties; 10738 while (attr != NULL) { 10739 if (attr->ns == NULL) { 10740 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10741 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10742 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10743 xmlSchemaPIllegalAttrErr(pctxt, 10744 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10745 } 10746 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10747 xmlSchemaPIllegalAttrErr(pctxt, 10748 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10749 } 10750 attr = attr->next; 10751 } 10752 /* 10753 * Extract and validate attributes. 10754 */ 10755 if (xmlSchemaPValAttr(pctxt, NULL, node, 10756 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10757 &namespaceName) != 0) { 10758 xmlSchemaPSimpleTypeErr(pctxt, 10759 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10760 NULL, node, 10761 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10762 NULL, namespaceName, NULL, NULL, NULL); 10763 return (pctxt->err); 10764 } 10765 10766 if (xmlSchemaPValAttr(pctxt, NULL, node, 10767 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10768 &schemaLocation) != 0) { 10769 xmlSchemaPSimpleTypeErr(pctxt, 10770 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10771 NULL, node, 10772 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10773 NULL, schemaLocation, NULL, NULL, NULL); 10774 return (pctxt->err); 10775 } 10776 /* 10777 * And now for the children... 10778 */ 10779 child = node->children; 10780 if (IS_SCHEMA(child, "annotation")) { 10781 /* 10782 * the annotation here is simply discarded ... 10783 * TODO: really? 10784 */ 10785 child = child->next; 10786 } 10787 if (child != NULL) { 10788 xmlSchemaPContentErr(pctxt, 10789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10790 NULL, node, child, NULL, 10791 "(annotation?)"); 10792 } 10793 /* 10794 * Apply additional constraints. 10795 * 10796 * Note that it is important to use the original @targetNamespace 10797 * (or none at all), to rule out imports of schemas _with_ a 10798 * @targetNamespace if the importing schema is a chameleon schema 10799 * (with no @targetNamespace). 10800 */ 10801 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10802 if (namespaceName != NULL) { 10803 /* 10804 * 1.1 If the namespace [attribute] is present, then its `actual value` 10805 * must not match the `actual value` of the enclosing <schema>'s 10806 * targetNamespace [attribute]. 10807 */ 10808 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10809 xmlSchemaPCustomErr(pctxt, 10810 XML_SCHEMAP_SRC_IMPORT_1_1, 10811 NULL, node, 10812 "The value of the attribute 'namespace' must not match " 10813 "the target namespace '%s' of the importing schema", 10814 thisTargetNamespace); 10815 return (pctxt->err); 10816 } 10817 } else { 10818 /* 10819 * 1.2 If the namespace [attribute] is not present, then the enclosing 10820 * <schema> must have a targetNamespace [attribute]. 10821 */ 10822 if (thisTargetNamespace == NULL) { 10823 xmlSchemaPCustomErr(pctxt, 10824 XML_SCHEMAP_SRC_IMPORT_1_2, 10825 NULL, node, 10826 "The attribute 'namespace' must be existent if " 10827 "the importing schema has no target namespace", 10828 NULL); 10829 return (pctxt->err); 10830 } 10831 } 10832 /* 10833 * Locate and acquire the schema document. 10834 */ 10835 if (schemaLocation != NULL) 10836 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10837 schemaLocation, node); 10838 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10839 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10840 namespaceName, &bucket); 10841 10842 if (ret != 0) 10843 return(ret); 10844 10845 /* 10846 * For <import>: "It is *not* an error for the application 10847 * schema reference strategy to fail." 10848 * So just don't parse if no schema document was found. 10849 * Note that we will get no bucket if the schema could not be 10850 * located or if there was no schemaLocation. 10851 */ 10852 if ((bucket == NULL) && (schemaLocation != NULL)) { 10853 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10854 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10855 node, NULL, 10856 "Failed to locate a schema at location '%s'. " 10857 "Skipping the import", schemaLocation, NULL, NULL); 10858 } 10859 10860 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10861 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10862 } 10863 10864 return (ret); 10865 } 10866 10867 static int 10868 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10869 xmlSchemaPtr schema, 10870 xmlNodePtr node, 10871 xmlChar **schemaLocation, 10872 int type) 10873 { 10874 xmlAttrPtr attr; 10875 10876 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10877 (schemaLocation == NULL)) 10878 return (-1); 10879 10880 *schemaLocation = NULL; 10881 /* 10882 * Check for illegal attributes. 10883 * Applies for both <include> and <redefine>. 10884 */ 10885 attr = node->properties; 10886 while (attr != NULL) { 10887 if (attr->ns == NULL) { 10888 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10889 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10890 xmlSchemaPIllegalAttrErr(pctxt, 10891 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10892 } 10893 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10894 xmlSchemaPIllegalAttrErr(pctxt, 10895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10896 } 10897 attr = attr->next; 10898 } 10899 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10900 /* 10901 * Preliminary step, extract the URI-Reference and make an URI 10902 * from the base. 10903 */ 10904 /* 10905 * Attribute "schemaLocation" is mandatory. 10906 */ 10907 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10908 if (attr != NULL) { 10909 xmlChar *base = NULL; 10910 xmlChar *uri = NULL; 10911 10912 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10913 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10914 (const xmlChar **) schemaLocation) != 0) 10915 goto exit_error; 10916 base = xmlNodeGetBase(node->doc, node); 10917 if (base == NULL) { 10918 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10919 } else { 10920 uri = xmlBuildURI(*schemaLocation, base); 10921 xmlFree(base); 10922 } 10923 if (uri == NULL) { 10924 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10925 "could not build an URI from the schemaLocation") 10926 goto exit_failure; 10927 } 10928 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10929 xmlFree(uri); 10930 } else { 10931 xmlSchemaPMissingAttrErr(pctxt, 10932 XML_SCHEMAP_S4S_ATTR_MISSING, 10933 NULL, node, "schemaLocation", NULL); 10934 goto exit_error; 10935 } 10936 /* 10937 * Report self-inclusion and self-redefinition. 10938 */ 10939 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10940 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10941 xmlSchemaPCustomErr(pctxt, 10942 XML_SCHEMAP_SRC_REDEFINE, 10943 NULL, node, 10944 "The schema document '%s' cannot redefine itself.", 10945 *schemaLocation); 10946 } else { 10947 xmlSchemaPCustomErr(pctxt, 10948 XML_SCHEMAP_SRC_INCLUDE, 10949 NULL, node, 10950 "The schema document '%s' cannot include itself.", 10951 *schemaLocation); 10952 } 10953 goto exit_error; 10954 } 10955 10956 return(0); 10957 exit_error: 10958 return(pctxt->err); 10959 exit_failure: 10960 return(-1); 10961 } 10962 10963 static int 10964 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10965 xmlSchemaPtr schema, 10966 xmlNodePtr node, 10967 int type) 10968 { 10969 xmlNodePtr child = NULL; 10970 const xmlChar *schemaLocation = NULL; 10971 int res = 0; /* hasRedefinitions = 0 */ 10972 int isChameleon = 0, wasChameleon = 0; 10973 xmlSchemaBucketPtr bucket = NULL; 10974 10975 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10976 return (-1); 10977 10978 /* 10979 * Parse attributes. Note that the returned schemaLocation will 10980 * be already converted to an absolute URI. 10981 */ 10982 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10983 node, (xmlChar **) (&schemaLocation), type); 10984 if (res != 0) 10985 return(res); 10986 /* 10987 * Load and add the schema document. 10988 */ 10989 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10990 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10991 if (res != 0) 10992 return(res); 10993 /* 10994 * If we get no schema bucket back, then this means that the schema 10995 * document could not be located or was broken XML or was not 10996 * a schema document. 10997 */ 10998 if ((bucket == NULL) || (bucket->doc == NULL)) { 10999 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 11000 /* 11001 * WARNING for <include>: 11002 * We will raise an error if the schema cannot be located 11003 * for inclusions, since the that was the feedback from the 11004 * schema people. I.e. the following spec piece will *not* be 11005 * satisfied: 11006 * SPEC src-include: "It is not an error for the `actual value` of the 11007 * schemaLocation [attribute] to fail to resolve it all, in which 11008 * case no corresponding inclusion is performed. 11009 * So do we need a warning report here?" 11010 */ 11011 res = XML_SCHEMAP_SRC_INCLUDE; 11012 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11013 node, NULL, 11014 "Failed to load the document '%s' for inclusion", 11015 schemaLocation, NULL); 11016 } else { 11017 /* 11018 * NOTE: This was changed to raise an error even if no redefinitions 11019 * are specified. 11020 * 11021 * SPEC src-redefine (1) 11022 * "If there are any element information items among the [children] 11023 * other than <annotation> then the `actual value` of the 11024 * schemaLocation [attribute] must successfully resolve." 11025 * TODO: Ask the WG if a the location has always to resolve 11026 * here as well! 11027 */ 11028 res = XML_SCHEMAP_SRC_REDEFINE; 11029 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11030 node, NULL, 11031 "Failed to load the document '%s' for redefinition", 11032 schemaLocation, NULL); 11033 } 11034 } else { 11035 /* 11036 * Check targetNamespace sanity before parsing the new schema. 11037 * TODO: Note that we won't check further content if the 11038 * targetNamespace was bad. 11039 */ 11040 if (bucket->origTargetNamespace != NULL) { 11041 /* 11042 * SPEC src-include (2.1) 11043 * "SII has a targetNamespace [attribute], and its `actual 11044 * value` is identical to the `actual value` of the targetNamespace 11045 * [attribute] of SII' (which must have such an [attribute])." 11046 */ 11047 if (pctxt->targetNamespace == NULL) { 11048 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11049 XML_SCHEMAP_SRC_INCLUDE, 11050 node, NULL, 11051 "The target namespace of the included/redefined schema " 11052 "'%s' has to be absent, since the including/redefining " 11053 "schema has no target namespace", 11054 schemaLocation, NULL); 11055 goto exit_error; 11056 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11057 pctxt->targetNamespace)) { 11058 /* TODO: Change error function. */ 11059 xmlSchemaPCustomErrExt(pctxt, 11060 XML_SCHEMAP_SRC_INCLUDE, 11061 NULL, node, 11062 "The target namespace '%s' of the included/redefined " 11063 "schema '%s' differs from '%s' of the " 11064 "including/redefining schema", 11065 bucket->origTargetNamespace, schemaLocation, 11066 pctxt->targetNamespace); 11067 goto exit_error; 11068 } 11069 } else if (pctxt->targetNamespace != NULL) { 11070 /* 11071 * Chameleons: the original target namespace will 11072 * differ from the resulting namespace. 11073 */ 11074 isChameleon = 1; 11075 if (bucket->parsed && 11076 bucket->origTargetNamespace != NULL) { 11077 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11078 XML_SCHEMAP_SRC_INCLUDE, 11079 node, NULL, 11080 "The target namespace of the included/redefined schema " 11081 "'%s' has to be absent or the same as the " 11082 "including/redefining schema's target namespace", 11083 schemaLocation, NULL); 11084 goto exit_error; 11085 } 11086 bucket->targetNamespace = pctxt->targetNamespace; 11087 } 11088 } 11089 /* 11090 * Parse the schema. 11091 */ 11092 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11093 if (isChameleon) { 11094 /* TODO: Get rid of this flag on the schema itself. */ 11095 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11096 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11097 } else 11098 wasChameleon = 1; 11099 } 11100 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11101 /* Restore chameleon flag. */ 11102 if (isChameleon && (!wasChameleon)) 11103 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11104 } 11105 /* 11106 * And now for the children... 11107 */ 11108 child = node->children; 11109 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11110 /* 11111 * Parse (simpleType | complexType | group | attributeGroup))* 11112 */ 11113 pctxt->redefined = bucket; 11114 /* 11115 * How to proceed if the redefined schema was not located? 11116 */ 11117 pctxt->isRedefine = 1; 11118 while (IS_SCHEMA(child, "annotation") || 11119 IS_SCHEMA(child, "simpleType") || 11120 IS_SCHEMA(child, "complexType") || 11121 IS_SCHEMA(child, "group") || 11122 IS_SCHEMA(child, "attributeGroup")) { 11123 if (IS_SCHEMA(child, "annotation")) { 11124 /* 11125 * TODO: discard or not? 11126 */ 11127 } else if (IS_SCHEMA(child, "simpleType")) { 11128 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11129 } else if (IS_SCHEMA(child, "complexType")) { 11130 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11131 /* hasRedefinitions = 1; */ 11132 } else if (IS_SCHEMA(child, "group")) { 11133 /* hasRedefinitions = 1; */ 11134 xmlSchemaParseModelGroupDefinition(pctxt, 11135 schema, child); 11136 } else if (IS_SCHEMA(child, "attributeGroup")) { 11137 /* hasRedefinitions = 1; */ 11138 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11139 child); 11140 } 11141 child = child->next; 11142 } 11143 pctxt->redefined = NULL; 11144 pctxt->isRedefine = 0; 11145 } else { 11146 if (IS_SCHEMA(child, "annotation")) { 11147 /* 11148 * TODO: discard or not? 11149 */ 11150 child = child->next; 11151 } 11152 } 11153 if (child != NULL) { 11154 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11155 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11156 xmlSchemaPContentErr(pctxt, res, 11157 NULL, node, child, NULL, 11158 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11159 } else { 11160 xmlSchemaPContentErr(pctxt, res, 11161 NULL, node, child, NULL, 11162 "(annotation?)"); 11163 } 11164 } 11165 return(res); 11166 11167 exit_error: 11168 return(pctxt->err); 11169 } 11170 11171 static int 11172 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11173 xmlNodePtr node) 11174 { 11175 int res; 11176 #ifndef ENABLE_REDEFINE 11177 TODO 11178 return(0); 11179 #endif 11180 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11181 XML_SCHEMA_SCHEMA_REDEFINE); 11182 if (res != 0) 11183 return(res); 11184 return(0); 11185 } 11186 11187 static int 11188 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11189 xmlNodePtr node) 11190 { 11191 int res; 11192 11193 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11194 XML_SCHEMA_SCHEMA_INCLUDE); 11195 if (res != 0) 11196 return(res); 11197 return(0); 11198 } 11199 11200 /** 11201 * xmlSchemaParseModelGroup: 11202 * @ctxt: a schema validation context 11203 * @schema: the schema being built 11204 * @node: a subtree containing XML Schema informations 11205 * @type: the "compositor" type 11206 * @particleNeeded: if a a model group with a particle 11207 * 11208 * parse a XML schema Sequence definition. 11209 * Applies parts of: 11210 * Schema Representation Constraint: 11211 * Redefinition Constraints and Semantics (src-redefine) 11212 * (6.1), (6.1.1), (6.1.2) 11213 * 11214 * Schema Component Constraint: 11215 * All Group Limited (cos-all-limited) (2) 11216 * TODO: Actually this should go to component-level checks, 11217 * but is done here due to performance. Move it to an other layer 11218 * is schema construction via an API is implemented. 11219 * 11220 * *WARNING* this interface is highly subject to change 11221 * 11222 * Returns -1 in case of error, 0 if the declaration is improper and 11223 * 1 in case of success. 11224 */ 11225 static xmlSchemaTreeItemPtr 11226 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11227 xmlNodePtr node, xmlSchemaTypeType type, 11228 int withParticle) 11229 { 11230 xmlSchemaModelGroupPtr item; 11231 xmlSchemaParticlePtr particle = NULL; 11232 xmlNodePtr child = NULL; 11233 xmlAttrPtr attr; 11234 int min = 1, max = 1, isElemRef, hasRefs = 0; 11235 11236 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11237 return (NULL); 11238 /* 11239 * Create a model group with the given compositor. 11240 */ 11241 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11242 if (item == NULL) 11243 return (NULL); 11244 11245 if (withParticle) { 11246 if (type == XML_SCHEMA_TYPE_ALL) { 11247 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11248 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11249 } else { 11250 /* choice + sequence */ 11251 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11252 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11253 "(xs:nonNegativeInteger | unbounded)"); 11254 } 11255 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11256 /* 11257 * Create a particle 11258 */ 11259 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11260 if (particle == NULL) 11261 return (NULL); 11262 particle->children = (xmlSchemaTreeItemPtr) item; 11263 /* 11264 * Check for illegal attributes. 11265 */ 11266 attr = node->properties; 11267 while (attr != NULL) { 11268 if (attr->ns == NULL) { 11269 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11270 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11271 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11272 xmlSchemaPIllegalAttrErr(ctxt, 11273 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11274 } 11275 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11276 xmlSchemaPIllegalAttrErr(ctxt, 11277 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11278 } 11279 attr = attr->next; 11280 } 11281 } else { 11282 /* 11283 * Check for illegal attributes. 11284 */ 11285 attr = node->properties; 11286 while (attr != NULL) { 11287 if (attr->ns == NULL) { 11288 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11289 xmlSchemaPIllegalAttrErr(ctxt, 11290 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11291 } 11292 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11293 xmlSchemaPIllegalAttrErr(ctxt, 11294 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11295 } 11296 attr = attr->next; 11297 } 11298 } 11299 11300 /* 11301 * Extract and validate attributes. 11302 */ 11303 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11304 /* 11305 * And now for the children... 11306 */ 11307 child = node->children; 11308 if (IS_SCHEMA(child, "annotation")) { 11309 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11310 child = child->next; 11311 } 11312 if (type == XML_SCHEMA_TYPE_ALL) { 11313 xmlSchemaParticlePtr part, last = NULL; 11314 11315 while (IS_SCHEMA(child, "element")) { 11316 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11317 schema, child, &isElemRef, 0); 11318 /* 11319 * SPEC cos-all-limited (2) 11320 * "The {max occurs} of all the particles in the {particles} 11321 * of the ('all') group must be 0 or 1. 11322 */ 11323 if (part != NULL) { 11324 if (isElemRef) 11325 hasRefs++; 11326 if (part->minOccurs > 1) { 11327 xmlSchemaPCustomErr(ctxt, 11328 XML_SCHEMAP_COS_ALL_LIMITED, 11329 NULL, child, 11330 "Invalid value for minOccurs (must be 0 or 1)", 11331 NULL); 11332 /* Reset to 1. */ 11333 part->minOccurs = 1; 11334 } 11335 if (part->maxOccurs > 1) { 11336 xmlSchemaPCustomErr(ctxt, 11337 XML_SCHEMAP_COS_ALL_LIMITED, 11338 NULL, child, 11339 "Invalid value for maxOccurs (must be 0 or 1)", 11340 NULL); 11341 /* Reset to 1. */ 11342 part->maxOccurs = 1; 11343 } 11344 if (last == NULL) 11345 item->children = (xmlSchemaTreeItemPtr) part; 11346 else 11347 last->next = (xmlSchemaTreeItemPtr) part; 11348 last = part; 11349 } 11350 child = child->next; 11351 } 11352 if (child != NULL) { 11353 xmlSchemaPContentErr(ctxt, 11354 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11355 NULL, node, child, NULL, 11356 "(annotation?, (annotation?, element*)"); 11357 } 11358 } else { 11359 /* choice + sequence */ 11360 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11361 11362 while ((IS_SCHEMA(child, "element")) || 11363 (IS_SCHEMA(child, "group")) || 11364 (IS_SCHEMA(child, "any")) || 11365 (IS_SCHEMA(child, "choice")) || 11366 (IS_SCHEMA(child, "sequence"))) { 11367 11368 if (IS_SCHEMA(child, "element")) { 11369 part = (xmlSchemaTreeItemPtr) 11370 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11371 if (part && isElemRef) 11372 hasRefs++; 11373 } else if (IS_SCHEMA(child, "group")) { 11374 part = 11375 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11376 if (part != NULL) 11377 hasRefs++; 11378 /* 11379 * Handle redefinitions. 11380 */ 11381 if (ctxt->isRedefine && ctxt->redef && 11382 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11383 part && part->children) 11384 { 11385 if ((xmlSchemaGetQNameRefName(part->children) == 11386 ctxt->redef->refName) && 11387 (xmlSchemaGetQNameRefTargetNs(part->children) == 11388 ctxt->redef->refTargetNs)) 11389 { 11390 /* 11391 * SPEC src-redefine: 11392 * (6.1) "If it has a <group> among its contents at 11393 * some level the `actual value` of whose ref 11394 * [attribute] is the same as the `actual value` of 11395 * its own name attribute plus target namespace, then 11396 * all of the following must be true:" 11397 * (6.1.1) "It must have exactly one such group." 11398 */ 11399 if (ctxt->redefCounter != 0) { 11400 xmlChar *str = NULL; 11401 11402 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11403 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11404 "The redefining model group definition " 11405 "'%s' must not contain more than one " 11406 "reference to the redefined definition", 11407 xmlSchemaFormatQName(&str, 11408 ctxt->redef->refTargetNs, 11409 ctxt->redef->refName), 11410 NULL); 11411 FREE_AND_NULL(str) 11412 part = NULL; 11413 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11414 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11415 { 11416 xmlChar *str = NULL; 11417 /* 11418 * SPEC src-redefine: 11419 * (6.1.2) "The `actual value` of both that 11420 * group's minOccurs and maxOccurs [attribute] 11421 * must be 1 (or `absent`). 11422 */ 11423 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11424 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11425 "The redefining model group definition " 11426 "'%s' must not contain a reference to the " 11427 "redefined definition with a " 11428 "maxOccurs/minOccurs other than 1", 11429 xmlSchemaFormatQName(&str, 11430 ctxt->redef->refTargetNs, 11431 ctxt->redef->refName), 11432 NULL); 11433 FREE_AND_NULL(str) 11434 part = NULL; 11435 } 11436 ctxt->redef->reference = WXS_BASIC_CAST part; 11437 ctxt->redefCounter++; 11438 } 11439 } 11440 } else if (IS_SCHEMA(child, "any")) { 11441 part = (xmlSchemaTreeItemPtr) 11442 xmlSchemaParseAny(ctxt, schema, child); 11443 } else if (IS_SCHEMA(child, "choice")) { 11444 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11445 XML_SCHEMA_TYPE_CHOICE, 1); 11446 } else if (IS_SCHEMA(child, "sequence")) { 11447 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11448 XML_SCHEMA_TYPE_SEQUENCE, 1); 11449 } 11450 if (part != NULL) { 11451 if (last == NULL) 11452 item->children = part; 11453 else 11454 last->next = part; 11455 last = part; 11456 } 11457 child = child->next; 11458 } 11459 if (child != NULL) { 11460 xmlSchemaPContentErr(ctxt, 11461 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11462 NULL, node, child, NULL, 11463 "(annotation?, (element | group | choice | sequence | any)*)"); 11464 } 11465 } 11466 if ((max == 0) && (min == 0)) 11467 return (NULL); 11468 if (hasRefs) { 11469 /* 11470 * We need to resolve references. 11471 */ 11472 WXS_ADD_PENDING(ctxt, item); 11473 } 11474 if (withParticle) 11475 return ((xmlSchemaTreeItemPtr) particle); 11476 else 11477 return ((xmlSchemaTreeItemPtr) item); 11478 } 11479 11480 /** 11481 * xmlSchemaParseRestriction: 11482 * @ctxt: a schema validation context 11483 * @schema: the schema being built 11484 * @node: a subtree containing XML Schema informations 11485 * 11486 * parse a XML schema Restriction definition 11487 * *WARNING* this interface is highly subject to change 11488 * 11489 * Returns the type definition or NULL in case of error 11490 */ 11491 static xmlSchemaTypePtr 11492 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11493 xmlNodePtr node, xmlSchemaTypeType parentType) 11494 { 11495 xmlSchemaTypePtr type; 11496 xmlNodePtr child = NULL; 11497 xmlAttrPtr attr; 11498 11499 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11500 return (NULL); 11501 /* Not a component, don't create it. */ 11502 type = ctxt->ctxtType; 11503 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11504 11505 /* 11506 * Check for illegal attributes. 11507 */ 11508 attr = node->properties; 11509 while (attr != NULL) { 11510 if (attr->ns == NULL) { 11511 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11512 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11513 xmlSchemaPIllegalAttrErr(ctxt, 11514 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11515 } 11516 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11517 xmlSchemaPIllegalAttrErr(ctxt, 11518 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11519 } 11520 attr = attr->next; 11521 } 11522 /* 11523 * Extract and validate attributes. 11524 */ 11525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11526 /* 11527 * Attribute 11528 */ 11529 /* 11530 * Extract the base type. The "base" attribute is mandatory if inside 11531 * a complex type or if redefining. 11532 * 11533 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11534 * among its [children]), the simple type definition which is 11535 * the {content type} of the type definition `resolved` to by 11536 * the `actual value` of the base [attribute]" 11537 */ 11538 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11539 &(type->baseNs), &(type->base)) == 0) 11540 { 11541 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11542 xmlSchemaPMissingAttrErr(ctxt, 11543 XML_SCHEMAP_S4S_ATTR_MISSING, 11544 NULL, node, "base", NULL); 11545 } else if ((ctxt->isRedefine) && 11546 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11547 { 11548 if (type->base == NULL) { 11549 xmlSchemaPMissingAttrErr(ctxt, 11550 XML_SCHEMAP_S4S_ATTR_MISSING, 11551 NULL, node, "base", NULL); 11552 } else if ((! xmlStrEqual(type->base, type->name)) || 11553 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11554 { 11555 xmlChar *str1 = NULL, *str2 = NULL; 11556 /* 11557 * REDEFINE: SPEC src-redefine (5) 11558 * "Within the [children], each <simpleType> must have a 11559 * <restriction> among its [children] ... the `actual value` of 11560 * whose base [attribute] must be the same as the `actual value` 11561 * of its own name attribute plus target namespace;" 11562 */ 11563 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11564 NULL, node, "This is a redefinition, but the QName " 11565 "value '%s' of the 'base' attribute does not match the " 11566 "type's designation '%s'", 11567 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11568 xmlSchemaFormatQName(&str2, type->targetNamespace, 11569 type->name), NULL); 11570 FREE_AND_NULL(str1); 11571 FREE_AND_NULL(str2); 11572 /* Avoid confusion and erase the values. */ 11573 type->base = NULL; 11574 type->baseNs = NULL; 11575 } 11576 } 11577 } 11578 /* 11579 * And now for the children... 11580 */ 11581 child = node->children; 11582 if (IS_SCHEMA(child, "annotation")) { 11583 /* 11584 * Add the annotation to the simple type ancestor. 11585 */ 11586 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11587 xmlSchemaParseAnnotation(ctxt, child, 1)); 11588 child = child->next; 11589 } 11590 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11591 /* 11592 * Corresponds to <simpleType><restriction><simpleType>. 11593 */ 11594 if (IS_SCHEMA(child, "simpleType")) { 11595 if (type->base != NULL) { 11596 /* 11597 * src-restriction-base-or-simpleType 11598 * Either the base [attribute] or the simpleType [child] of the 11599 * <restriction> element must be present, but not both. 11600 */ 11601 xmlSchemaPContentErr(ctxt, 11602 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11603 NULL, node, child, 11604 "The attribute 'base' and the <simpleType> child are " 11605 "mutually exclusive", NULL); 11606 } else { 11607 type->baseType = (xmlSchemaTypePtr) 11608 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11609 } 11610 child = child->next; 11611 } else if (type->base == NULL) { 11612 xmlSchemaPContentErr(ctxt, 11613 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11614 NULL, node, child, 11615 "Either the attribute 'base' or a <simpleType> child " 11616 "must be present", NULL); 11617 } 11618 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11619 /* 11620 * Corresponds to <complexType><complexContent><restriction>... 11621 * followed by: 11622 * 11623 * Model groups <all>, <choice> and <sequence>. 11624 */ 11625 if (IS_SCHEMA(child, "all")) { 11626 type->subtypes = (xmlSchemaTypePtr) 11627 xmlSchemaParseModelGroup(ctxt, schema, child, 11628 XML_SCHEMA_TYPE_ALL, 1); 11629 child = child->next; 11630 } else if (IS_SCHEMA(child, "choice")) { 11631 type->subtypes = (xmlSchemaTypePtr) 11632 xmlSchemaParseModelGroup(ctxt, 11633 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11634 child = child->next; 11635 } else if (IS_SCHEMA(child, "sequence")) { 11636 type->subtypes = (xmlSchemaTypePtr) 11637 xmlSchemaParseModelGroup(ctxt, schema, child, 11638 XML_SCHEMA_TYPE_SEQUENCE, 1); 11639 child = child->next; 11640 /* 11641 * Model group reference <group>. 11642 */ 11643 } else if (IS_SCHEMA(child, "group")) { 11644 type->subtypes = (xmlSchemaTypePtr) 11645 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11646 /* 11647 * Note that the reference will be resolved in 11648 * xmlSchemaResolveTypeReferences(); 11649 */ 11650 child = child->next; 11651 } 11652 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11653 /* 11654 * Corresponds to <complexType><simpleContent><restriction>... 11655 * 11656 * "1.1 the simple type definition corresponding to the <simpleType> 11657 * among the [children] of <restriction> if there is one;" 11658 */ 11659 if (IS_SCHEMA(child, "simpleType")) { 11660 /* 11661 * We will store the to-be-restricted simple type in 11662 * type->contentTypeDef *temporarily*. 11663 */ 11664 type->contentTypeDef = (xmlSchemaTypePtr) 11665 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11666 if ( type->contentTypeDef == NULL) 11667 return (NULL); 11668 child = child->next; 11669 } 11670 } 11671 11672 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11673 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11674 xmlSchemaFacetPtr facet, lastfacet = NULL; 11675 /* 11676 * Corresponds to <complexType><simpleContent><restriction>... 11677 * <simpleType><restriction>... 11678 */ 11679 11680 /* 11681 * Add the facets to the simple type ancestor. 11682 */ 11683 /* 11684 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11685 * Simple Type Definition Schema Representation Constraint: 11686 * *Single Facet Value* 11687 */ 11688 while ((IS_SCHEMA(child, "minInclusive")) || 11689 (IS_SCHEMA(child, "minExclusive")) || 11690 (IS_SCHEMA(child, "maxInclusive")) || 11691 (IS_SCHEMA(child, "maxExclusive")) || 11692 (IS_SCHEMA(child, "totalDigits")) || 11693 (IS_SCHEMA(child, "fractionDigits")) || 11694 (IS_SCHEMA(child, "pattern")) || 11695 (IS_SCHEMA(child, "enumeration")) || 11696 (IS_SCHEMA(child, "whiteSpace")) || 11697 (IS_SCHEMA(child, "length")) || 11698 (IS_SCHEMA(child, "maxLength")) || 11699 (IS_SCHEMA(child, "minLength"))) { 11700 facet = xmlSchemaParseFacet(ctxt, schema, child); 11701 if (facet != NULL) { 11702 if (lastfacet == NULL) 11703 type->facets = facet; 11704 else 11705 lastfacet->next = facet; 11706 lastfacet = facet; 11707 lastfacet->next = NULL; 11708 } 11709 child = child->next; 11710 } 11711 /* 11712 * Create links for derivation and validation. 11713 */ 11714 if (type->facets != NULL) { 11715 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11716 11717 facet = type->facets; 11718 do { 11719 facetLink = (xmlSchemaFacetLinkPtr) 11720 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11721 if (facetLink == NULL) { 11722 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11723 xmlFree(facetLink); 11724 return (NULL); 11725 } 11726 facetLink->facet = facet; 11727 facetLink->next = NULL; 11728 if (lastFacetLink == NULL) 11729 type->facetSet = facetLink; 11730 else 11731 lastFacetLink->next = facetLink; 11732 lastFacetLink = facetLink; 11733 facet = facet->next; 11734 } while (facet != NULL); 11735 } 11736 } 11737 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11738 /* 11739 * Attribute uses/declarations. 11740 */ 11741 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11742 (xmlSchemaItemListPtr *) &(type->attrUses), 11743 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11744 return(NULL); 11745 /* 11746 * Attribute wildcard. 11747 */ 11748 if (IS_SCHEMA(child, "anyAttribute")) { 11749 type->attributeWildcard = 11750 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11751 child = child->next; 11752 } 11753 } 11754 if (child != NULL) { 11755 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11756 xmlSchemaPContentErr(ctxt, 11757 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11758 NULL, node, child, NULL, 11759 "annotation?, (group | all | choice | sequence)?, " 11760 "((attribute | attributeGroup)*, anyAttribute?))"); 11761 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11762 xmlSchemaPContentErr(ctxt, 11763 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11764 NULL, node, child, NULL, 11765 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11766 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11767 "length | minLength | maxLength | enumeration | whiteSpace | " 11768 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11769 } else { 11770 /* Simple type */ 11771 xmlSchemaPContentErr(ctxt, 11772 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11773 NULL, node, child, NULL, 11774 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11775 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11776 "length | minLength | maxLength | enumeration | whiteSpace | " 11777 "pattern)*))"); 11778 } 11779 } 11780 return (NULL); 11781 } 11782 11783 /** 11784 * xmlSchemaParseExtension: 11785 * @ctxt: a schema validation context 11786 * @schema: the schema being built 11787 * @node: a subtree containing XML Schema informations 11788 * 11789 * Parses an <extension>, which is found inside a 11790 * <simpleContent> or <complexContent>. 11791 * *WARNING* this interface is highly subject to change. 11792 * 11793 * TODO: Returns the type definition or NULL in case of error 11794 */ 11795 static xmlSchemaTypePtr 11796 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11797 xmlNodePtr node, xmlSchemaTypeType parentType) 11798 { 11799 xmlSchemaTypePtr type; 11800 xmlNodePtr child = NULL; 11801 xmlAttrPtr attr; 11802 11803 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11804 return (NULL); 11805 /* Not a component, don't create it. */ 11806 type = ctxt->ctxtType; 11807 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11808 11809 /* 11810 * Check for illegal attributes. 11811 */ 11812 attr = node->properties; 11813 while (attr != NULL) { 11814 if (attr->ns == NULL) { 11815 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11816 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11817 xmlSchemaPIllegalAttrErr(ctxt, 11818 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11819 } 11820 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11821 xmlSchemaPIllegalAttrErr(ctxt, 11822 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11823 } 11824 attr = attr->next; 11825 } 11826 11827 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11828 11829 /* 11830 * Attribute "base" - mandatory. 11831 */ 11832 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11833 "base", &(type->baseNs), &(type->base)) == 0) && 11834 (type->base == NULL)) { 11835 xmlSchemaPMissingAttrErr(ctxt, 11836 XML_SCHEMAP_S4S_ATTR_MISSING, 11837 NULL, node, "base", NULL); 11838 } 11839 /* 11840 * And now for the children... 11841 */ 11842 child = node->children; 11843 if (IS_SCHEMA(child, "annotation")) { 11844 /* 11845 * Add the annotation to the type ancestor. 11846 */ 11847 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11848 xmlSchemaParseAnnotation(ctxt, child, 1)); 11849 child = child->next; 11850 } 11851 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11852 /* 11853 * Corresponds to <complexType><complexContent><extension>... and: 11854 * 11855 * Model groups <all>, <choice>, <sequence> and <group>. 11856 */ 11857 if (IS_SCHEMA(child, "all")) { 11858 type->subtypes = (xmlSchemaTypePtr) 11859 xmlSchemaParseModelGroup(ctxt, schema, 11860 child, XML_SCHEMA_TYPE_ALL, 1); 11861 child = child->next; 11862 } else if (IS_SCHEMA(child, "choice")) { 11863 type->subtypes = (xmlSchemaTypePtr) 11864 xmlSchemaParseModelGroup(ctxt, schema, 11865 child, XML_SCHEMA_TYPE_CHOICE, 1); 11866 child = child->next; 11867 } else if (IS_SCHEMA(child, "sequence")) { 11868 type->subtypes = (xmlSchemaTypePtr) 11869 xmlSchemaParseModelGroup(ctxt, schema, 11870 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11871 child = child->next; 11872 } else if (IS_SCHEMA(child, "group")) { 11873 type->subtypes = (xmlSchemaTypePtr) 11874 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11875 /* 11876 * Note that the reference will be resolved in 11877 * xmlSchemaResolveTypeReferences(); 11878 */ 11879 child = child->next; 11880 } 11881 } 11882 if (child != NULL) { 11883 /* 11884 * Attribute uses/declarations. 11885 */ 11886 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11887 (xmlSchemaItemListPtr *) &(type->attrUses), 11888 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11889 return(NULL); 11890 /* 11891 * Attribute wildcard. 11892 */ 11893 if (IS_SCHEMA(child, "anyAttribute")) { 11894 ctxt->ctxtType->attributeWildcard = 11895 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11896 child = child->next; 11897 } 11898 } 11899 if (child != NULL) { 11900 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11901 /* Complex content extension. */ 11902 xmlSchemaPContentErr(ctxt, 11903 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11904 NULL, node, child, NULL, 11905 "(annotation?, ((group | all | choice | sequence)?, " 11906 "((attribute | attributeGroup)*, anyAttribute?)))"); 11907 } else { 11908 /* Simple content extension. */ 11909 xmlSchemaPContentErr(ctxt, 11910 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11911 NULL, node, child, NULL, 11912 "(annotation?, ((attribute | attributeGroup)*, " 11913 "anyAttribute?))"); 11914 } 11915 } 11916 return (NULL); 11917 } 11918 11919 /** 11920 * xmlSchemaParseSimpleContent: 11921 * @ctxt: a schema validation context 11922 * @schema: the schema being built 11923 * @node: a subtree containing XML Schema informations 11924 * 11925 * parse a XML schema SimpleContent definition 11926 * *WARNING* this interface is highly subject to change 11927 * 11928 * Returns the type definition or NULL in case of error 11929 */ 11930 static int 11931 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11932 xmlSchemaPtr schema, xmlNodePtr node, 11933 int *hasRestrictionOrExtension) 11934 { 11935 xmlSchemaTypePtr type; 11936 xmlNodePtr child = NULL; 11937 xmlAttrPtr attr; 11938 11939 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11940 (hasRestrictionOrExtension == NULL)) 11941 return (-1); 11942 *hasRestrictionOrExtension = 0; 11943 /* Not a component, don't create it. */ 11944 type = ctxt->ctxtType; 11945 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11946 /* 11947 * Check for illegal attributes. 11948 */ 11949 attr = node->properties; 11950 while (attr != NULL) { 11951 if (attr->ns == NULL) { 11952 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11953 xmlSchemaPIllegalAttrErr(ctxt, 11954 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11955 } 11956 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11957 xmlSchemaPIllegalAttrErr(ctxt, 11958 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11959 } 11960 attr = attr->next; 11961 } 11962 11963 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11964 11965 /* 11966 * And now for the children... 11967 */ 11968 child = node->children; 11969 if (IS_SCHEMA(child, "annotation")) { 11970 /* 11971 * Add the annotation to the complex type ancestor. 11972 */ 11973 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11974 xmlSchemaParseAnnotation(ctxt, child, 1)); 11975 child = child->next; 11976 } 11977 if (child == NULL) { 11978 xmlSchemaPContentErr(ctxt, 11979 XML_SCHEMAP_S4S_ELEM_MISSING, 11980 NULL, node, NULL, NULL, 11981 "(annotation?, (restriction | extension))"); 11982 } 11983 if (child == NULL) { 11984 xmlSchemaPContentErr(ctxt, 11985 XML_SCHEMAP_S4S_ELEM_MISSING, 11986 NULL, node, NULL, NULL, 11987 "(annotation?, (restriction | extension))"); 11988 } 11989 if (IS_SCHEMA(child, "restriction")) { 11990 xmlSchemaParseRestriction(ctxt, schema, child, 11991 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11992 (*hasRestrictionOrExtension) = 1; 11993 child = child->next; 11994 } else if (IS_SCHEMA(child, "extension")) { 11995 xmlSchemaParseExtension(ctxt, schema, child, 11996 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11997 (*hasRestrictionOrExtension) = 1; 11998 child = child->next; 11999 } 12000 if (child != NULL) { 12001 xmlSchemaPContentErr(ctxt, 12002 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12003 NULL, node, child, NULL, 12004 "(annotation?, (restriction | extension))"); 12005 } 12006 return (0); 12007 } 12008 12009 /** 12010 * xmlSchemaParseComplexContent: 12011 * @ctxt: a schema validation context 12012 * @schema: the schema being built 12013 * @node: a subtree containing XML Schema informations 12014 * 12015 * parse a XML schema ComplexContent definition 12016 * *WARNING* this interface is highly subject to change 12017 * 12018 * Returns the type definition or NULL in case of error 12019 */ 12020 static int 12021 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12022 xmlSchemaPtr schema, xmlNodePtr node, 12023 int *hasRestrictionOrExtension) 12024 { 12025 xmlSchemaTypePtr type; 12026 xmlNodePtr child = NULL; 12027 xmlAttrPtr attr; 12028 12029 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12030 (hasRestrictionOrExtension == NULL)) 12031 return (-1); 12032 *hasRestrictionOrExtension = 0; 12033 /* Not a component, don't create it. */ 12034 type = ctxt->ctxtType; 12035 /* 12036 * Check for illegal attributes. 12037 */ 12038 attr = node->properties; 12039 while (attr != NULL) { 12040 if (attr->ns == NULL) { 12041 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12042 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12043 { 12044 xmlSchemaPIllegalAttrErr(ctxt, 12045 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12046 } 12047 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12048 xmlSchemaPIllegalAttrErr(ctxt, 12049 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12050 } 12051 attr = attr->next; 12052 } 12053 12054 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12055 12056 /* 12057 * Set the 'mixed' on the complex type ancestor. 12058 */ 12059 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12060 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12061 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12062 } 12063 child = node->children; 12064 if (IS_SCHEMA(child, "annotation")) { 12065 /* 12066 * Add the annotation to the complex type ancestor. 12067 */ 12068 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12069 xmlSchemaParseAnnotation(ctxt, child, 1)); 12070 child = child->next; 12071 } 12072 if (child == NULL) { 12073 xmlSchemaPContentErr(ctxt, 12074 XML_SCHEMAP_S4S_ELEM_MISSING, 12075 NULL, node, NULL, 12076 NULL, "(annotation?, (restriction | extension))"); 12077 } 12078 if (child == NULL) { 12079 xmlSchemaPContentErr(ctxt, 12080 XML_SCHEMAP_S4S_ELEM_MISSING, 12081 NULL, node, NULL, 12082 NULL, "(annotation?, (restriction | extension))"); 12083 } 12084 if (IS_SCHEMA(child, "restriction")) { 12085 xmlSchemaParseRestriction(ctxt, schema, child, 12086 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12087 (*hasRestrictionOrExtension) = 1; 12088 child = child->next; 12089 } else if (IS_SCHEMA(child, "extension")) { 12090 xmlSchemaParseExtension(ctxt, schema, child, 12091 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12092 (*hasRestrictionOrExtension) = 1; 12093 child = child->next; 12094 } 12095 if (child != NULL) { 12096 xmlSchemaPContentErr(ctxt, 12097 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12098 NULL, node, child, 12099 NULL, "(annotation?, (restriction | extension))"); 12100 } 12101 return (0); 12102 } 12103 12104 /** 12105 * xmlSchemaParseComplexType: 12106 * @ctxt: a schema validation context 12107 * @schema: the schema being built 12108 * @node: a subtree containing XML Schema informations 12109 * 12110 * parse a XML schema Complex Type definition 12111 * *WARNING* this interface is highly subject to change 12112 * 12113 * Returns the type definition or NULL in case of error 12114 */ 12115 static xmlSchemaTypePtr 12116 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12117 xmlNodePtr node, int topLevel) 12118 { 12119 xmlSchemaTypePtr type, ctxtType; 12120 xmlNodePtr child = NULL; 12121 const xmlChar *name = NULL; 12122 xmlAttrPtr attr; 12123 const xmlChar *attrValue; 12124 #ifdef ENABLE_NAMED_LOCALS 12125 char buf[40]; 12126 #endif 12127 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12128 12129 12130 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12131 return (NULL); 12132 12133 ctxtType = ctxt->ctxtType; 12134 12135 if (topLevel) { 12136 attr = xmlSchemaGetPropNode(node, "name"); 12137 if (attr == NULL) { 12138 xmlSchemaPMissingAttrErr(ctxt, 12139 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12140 return (NULL); 12141 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12142 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12143 return (NULL); 12144 } 12145 } 12146 12147 if (topLevel == 0) { 12148 /* 12149 * Parse as local complex type definition. 12150 */ 12151 #ifdef ENABLE_NAMED_LOCALS 12152 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12153 type = xmlSchemaAddType(ctxt, schema, 12154 XML_SCHEMA_TYPE_COMPLEX, 12155 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12156 ctxt->targetNamespace, node, 0); 12157 #else 12158 type = xmlSchemaAddType(ctxt, schema, 12159 XML_SCHEMA_TYPE_COMPLEX, 12160 NULL, ctxt->targetNamespace, node, 0); 12161 #endif 12162 if (type == NULL) 12163 return (NULL); 12164 name = type->name; 12165 type->node = node; 12166 type->type = XML_SCHEMA_TYPE_COMPLEX; 12167 /* 12168 * TODO: We need the target namespace. 12169 */ 12170 } else { 12171 /* 12172 * Parse as global complex type definition. 12173 */ 12174 type = xmlSchemaAddType(ctxt, schema, 12175 XML_SCHEMA_TYPE_COMPLEX, 12176 name, ctxt->targetNamespace, node, 1); 12177 if (type == NULL) 12178 return (NULL); 12179 type->node = node; 12180 type->type = XML_SCHEMA_TYPE_COMPLEX; 12181 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12182 } 12183 type->targetNamespace = ctxt->targetNamespace; 12184 /* 12185 * Handle attributes. 12186 */ 12187 attr = node->properties; 12188 while (attr != NULL) { 12189 if (attr->ns == NULL) { 12190 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12191 /* 12192 * Attribute "id". 12193 */ 12194 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12195 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12196 /* 12197 * Attribute "mixed". 12198 */ 12199 if (xmlSchemaPGetBoolNodeValue(ctxt, 12200 NULL, (xmlNodePtr) attr)) 12201 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12202 } else if (topLevel) { 12203 /* 12204 * Attributes of global complex type definitions. 12205 */ 12206 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12207 /* Pass. */ 12208 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12209 /* 12210 * Attribute "abstract". 12211 */ 12212 if (xmlSchemaPGetBoolNodeValue(ctxt, 12213 NULL, (xmlNodePtr) attr)) 12214 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12215 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12216 /* 12217 * Attribute "final". 12218 */ 12219 attrValue = xmlSchemaGetNodeContent(ctxt, 12220 (xmlNodePtr) attr); 12221 if (xmlSchemaPValAttrBlockFinal(attrValue, 12222 &(type->flags), 12223 -1, 12224 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12225 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12226 -1, -1, -1) != 0) 12227 { 12228 xmlSchemaPSimpleTypeErr(ctxt, 12229 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12230 NULL, (xmlNodePtr) attr, NULL, 12231 "(#all | List of (extension | restriction))", 12232 attrValue, NULL, NULL, NULL); 12233 } else 12234 final = 1; 12235 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12236 /* 12237 * Attribute "block". 12238 */ 12239 attrValue = xmlSchemaGetNodeContent(ctxt, 12240 (xmlNodePtr) attr); 12241 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12242 -1, 12243 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12244 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12245 -1, -1, -1) != 0) { 12246 xmlSchemaPSimpleTypeErr(ctxt, 12247 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12248 NULL, (xmlNodePtr) attr, NULL, 12249 "(#all | List of (extension | restriction)) ", 12250 attrValue, NULL, NULL, NULL); 12251 } else 12252 block = 1; 12253 } else { 12254 xmlSchemaPIllegalAttrErr(ctxt, 12255 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12256 } 12257 } else { 12258 xmlSchemaPIllegalAttrErr(ctxt, 12259 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12260 } 12261 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12262 xmlSchemaPIllegalAttrErr(ctxt, 12263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12264 } 12265 attr = attr->next; 12266 } 12267 if (! block) { 12268 /* 12269 * Apply default "block" values. 12270 */ 12271 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12272 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12273 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12274 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12275 } 12276 if (! final) { 12277 /* 12278 * Apply default "block" values. 12279 */ 12280 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12281 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12282 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12283 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12284 } 12285 /* 12286 * And now for the children... 12287 */ 12288 child = node->children; 12289 if (IS_SCHEMA(child, "annotation")) { 12290 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12291 child = child->next; 12292 } 12293 ctxt->ctxtType = type; 12294 if (IS_SCHEMA(child, "simpleContent")) { 12295 /* 12296 * <complexType><simpleContent>... 12297 * 3.4.3 : 2.2 12298 * Specifying mixed='true' when the <simpleContent> 12299 * alternative is chosen has no effect 12300 */ 12301 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12302 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12303 xmlSchemaParseSimpleContent(ctxt, schema, child, 12304 &hasRestrictionOrExtension); 12305 child = child->next; 12306 } else if (IS_SCHEMA(child, "complexContent")) { 12307 /* 12308 * <complexType><complexContent>... 12309 */ 12310 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12311 xmlSchemaParseComplexContent(ctxt, schema, child, 12312 &hasRestrictionOrExtension); 12313 child = child->next; 12314 } else { 12315 /* 12316 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12317 * 12318 * SPEC 12319 * "...the third alternative (neither <simpleContent> nor 12320 * <complexContent>) is chosen. This case is understood as shorthand 12321 * for complex content restricting the `ur-type definition`, and the 12322 * details of the mappings should be modified as necessary. 12323 */ 12324 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12325 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12326 /* 12327 * Parse model groups. 12328 */ 12329 if (IS_SCHEMA(child, "all")) { 12330 type->subtypes = (xmlSchemaTypePtr) 12331 xmlSchemaParseModelGroup(ctxt, schema, child, 12332 XML_SCHEMA_TYPE_ALL, 1); 12333 child = child->next; 12334 } else if (IS_SCHEMA(child, "choice")) { 12335 type->subtypes = (xmlSchemaTypePtr) 12336 xmlSchemaParseModelGroup(ctxt, schema, child, 12337 XML_SCHEMA_TYPE_CHOICE, 1); 12338 child = child->next; 12339 } else if (IS_SCHEMA(child, "sequence")) { 12340 type->subtypes = (xmlSchemaTypePtr) 12341 xmlSchemaParseModelGroup(ctxt, schema, child, 12342 XML_SCHEMA_TYPE_SEQUENCE, 1); 12343 child = child->next; 12344 } else if (IS_SCHEMA(child, "group")) { 12345 type->subtypes = (xmlSchemaTypePtr) 12346 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12347 /* 12348 * Note that the reference will be resolved in 12349 * xmlSchemaResolveTypeReferences(); 12350 */ 12351 child = child->next; 12352 } 12353 /* 12354 * Parse attribute decls/refs. 12355 */ 12356 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12357 (xmlSchemaItemListPtr *) &(type->attrUses), 12358 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12359 return(NULL); 12360 /* 12361 * Parse attribute wildcard. 12362 */ 12363 if (IS_SCHEMA(child, "anyAttribute")) { 12364 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12365 child = child->next; 12366 } 12367 } 12368 if (child != NULL) { 12369 xmlSchemaPContentErr(ctxt, 12370 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12371 NULL, node, child, 12372 NULL, "(annotation?, (simpleContent | complexContent | " 12373 "((group | all | choice | sequence)?, ((attribute | " 12374 "attributeGroup)*, anyAttribute?))))"); 12375 } 12376 /* 12377 * REDEFINE: SPEC src-redefine (5) 12378 */ 12379 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12380 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12381 NULL, node, "This is a redefinition, thus the " 12382 "<complexType> must have a <restriction> or <extension> " 12383 "grand-child", NULL); 12384 } 12385 ctxt->ctxtType = ctxtType; 12386 return (type); 12387 } 12388 12389 /************************************************************************ 12390 * * 12391 * Validating using Schemas * 12392 * * 12393 ************************************************************************/ 12394 12395 /************************************************************************ 12396 * * 12397 * Reading/Writing Schemas * 12398 * * 12399 ************************************************************************/ 12400 12401 #if 0 /* Will be enabled if it is clear what options are needed. */ 12402 /** 12403 * xmlSchemaParserCtxtSetOptions: 12404 * @ctxt: a schema parser context 12405 * @options: a combination of xmlSchemaParserOption 12406 * 12407 * Sets the options to be used during the parse. 12408 * 12409 * Returns 0 in case of success, -1 in case of an 12410 * API error. 12411 */ 12412 static int 12413 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12414 int options) 12415 12416 { 12417 int i; 12418 12419 if (ctxt == NULL) 12420 return (-1); 12421 /* 12422 * WARNING: Change the start value if adding to the 12423 * xmlSchemaParseOption. 12424 */ 12425 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12426 if (options & 1<<i) { 12427 return (-1); 12428 } 12429 } 12430 ctxt->options = options; 12431 return (0); 12432 } 12433 12434 /** 12435 * xmlSchemaValidCtxtGetOptions: 12436 * @ctxt: a schema parser context 12437 * 12438 * Returns the option combination of the parser context. 12439 */ 12440 static int 12441 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12442 12443 { 12444 if (ctxt == NULL) 12445 return (-1); 12446 else 12447 return (ctxt->options); 12448 } 12449 #endif 12450 12451 /** 12452 * xmlSchemaNewParserCtxt: 12453 * @URL: the location of the schema 12454 * 12455 * Create an XML Schemas parse context for that file/resource expected 12456 * to contain an XML Schemas file. 12457 * 12458 * Returns the parser context or NULL in case of error 12459 */ 12460 xmlSchemaParserCtxtPtr 12461 xmlSchemaNewParserCtxt(const char *URL) 12462 { 12463 xmlSchemaParserCtxtPtr ret; 12464 12465 if (URL == NULL) 12466 return (NULL); 12467 12468 ret = xmlSchemaParserCtxtCreate(); 12469 if (ret == NULL) 12470 return(NULL); 12471 ret->dict = xmlDictCreate(); 12472 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12473 return (ret); 12474 } 12475 12476 /** 12477 * xmlSchemaNewMemParserCtxt: 12478 * @buffer: a pointer to a char array containing the schemas 12479 * @size: the size of the array 12480 * 12481 * Create an XML Schemas parse context for that memory buffer expected 12482 * to contain an XML Schemas file. 12483 * 12484 * Returns the parser context or NULL in case of error 12485 */ 12486 xmlSchemaParserCtxtPtr 12487 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12488 { 12489 xmlSchemaParserCtxtPtr ret; 12490 12491 if ((buffer == NULL) || (size <= 0)) 12492 return (NULL); 12493 ret = xmlSchemaParserCtxtCreate(); 12494 if (ret == NULL) 12495 return(NULL); 12496 ret->buffer = buffer; 12497 ret->size = size; 12498 ret->dict = xmlDictCreate(); 12499 return (ret); 12500 } 12501 12502 /** 12503 * xmlSchemaNewDocParserCtxt: 12504 * @doc: a preparsed document tree 12505 * 12506 * Create an XML Schemas parse context for that document. 12507 * NB. The document may be modified during the parsing process. 12508 * 12509 * Returns the parser context or NULL in case of error 12510 */ 12511 xmlSchemaParserCtxtPtr 12512 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12513 { 12514 xmlSchemaParserCtxtPtr ret; 12515 12516 if (doc == NULL) 12517 return (NULL); 12518 ret = xmlSchemaParserCtxtCreate(); 12519 if (ret == NULL) 12520 return(NULL); 12521 ret->doc = doc; 12522 ret->dict = xmlDictCreate(); 12523 /* The application has responsibility for the document */ 12524 ret->preserve = 1; 12525 12526 return (ret); 12527 } 12528 12529 /** 12530 * xmlSchemaFreeParserCtxt: 12531 * @ctxt: the schema parser context 12532 * 12533 * Free the resources associated to the schema parser context 12534 */ 12535 void 12536 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12537 { 12538 if (ctxt == NULL) 12539 return; 12540 if (ctxt->doc != NULL && !ctxt->preserve) 12541 xmlFreeDoc(ctxt->doc); 12542 if (ctxt->vctxt != NULL) { 12543 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12544 } 12545 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12546 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12547 ctxt->constructor = NULL; 12548 ctxt->ownsConstructor = 0; 12549 } 12550 if (ctxt->attrProhibs != NULL) 12551 xmlSchemaItemListFree(ctxt->attrProhibs); 12552 xmlDictFree(ctxt->dict); 12553 xmlFree(ctxt); 12554 } 12555 12556 /************************************************************************ 12557 * * 12558 * Building the content models * 12559 * * 12560 ************************************************************************/ 12561 12562 /** 12563 * xmlSchemaBuildContentModelForSubstGroup: 12564 * 12565 * Returns 1 if nillable, 0 otherwise 12566 */ 12567 static int 12568 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12569 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12570 { 12571 xmlAutomataStatePtr start, tmp; 12572 xmlSchemaElementPtr elemDecl, member; 12573 xmlSchemaSubstGroupPtr substGroup; 12574 int i; 12575 int ret = 0; 12576 12577 elemDecl = (xmlSchemaElementPtr) particle->children; 12578 /* 12579 * Wrap the substitution group with a CHOICE. 12580 */ 12581 start = pctxt->state; 12582 if (end == NULL) 12583 end = xmlAutomataNewState(pctxt->am); 12584 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12585 if (substGroup == NULL) { 12586 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12587 XML_SCHEMAP_INTERNAL, 12588 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12589 "declaration is marked having a subst. group but none " 12590 "available.\n", elemDecl->name, NULL); 12591 return(0); 12592 } 12593 if (counter >= 0) { 12594 /* 12595 * NOTE that we put the declaration in, even if it's abstract. 12596 * However, an error will be raised during *validation* if an element 12597 * information item shall be validated against an abstract element 12598 * declaration. 12599 */ 12600 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12601 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12602 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12603 /* 12604 * Add subst. group members. 12605 */ 12606 for (i = 0; i < substGroup->members->nbItems; i++) { 12607 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12608 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12609 member->name, member->targetNamespace, member); 12610 } 12611 } else if (particle->maxOccurs == 1) { 12612 /* 12613 * NOTE that we put the declaration in, even if it's abstract, 12614 */ 12615 xmlAutomataNewEpsilon(pctxt->am, 12616 xmlAutomataNewTransition2(pctxt->am, 12617 start, NULL, 12618 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12619 /* 12620 * Add subst. group members. 12621 */ 12622 for (i = 0; i < substGroup->members->nbItems; i++) { 12623 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12624 /* 12625 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12626 * was incorrectly used instead of xmlAutomataNewTransition2() 12627 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12628 * section in xmlSchemaBuildAContentModel() ). 12629 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12630 * intended for the above "counter" section originally. I.e., 12631 * check xs:all with subst-groups. 12632 * 12633 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12634 * member->name, member->targetNamespace, 12635 * 1, 1, member); 12636 */ 12637 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12638 member->name, member->targetNamespace, member); 12639 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12640 } 12641 } else { 12642 xmlAutomataStatePtr hop; 12643 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12644 UNBOUNDED : particle->maxOccurs - 1; 12645 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12646 12647 counter = 12648 xmlAutomataNewCounter(pctxt->am, minOccurs, 12649 maxOccurs); 12650 hop = xmlAutomataNewState(pctxt->am); 12651 12652 xmlAutomataNewEpsilon(pctxt->am, 12653 xmlAutomataNewTransition2(pctxt->am, 12654 start, NULL, 12655 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12656 hop); 12657 /* 12658 * Add subst. group members. 12659 */ 12660 for (i = 0; i < substGroup->members->nbItems; i++) { 12661 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12662 xmlAutomataNewEpsilon(pctxt->am, 12663 xmlAutomataNewTransition2(pctxt->am, 12664 start, NULL, 12665 member->name, member->targetNamespace, member), 12666 hop); 12667 } 12668 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12669 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12670 } 12671 if (particle->minOccurs == 0) { 12672 xmlAutomataNewEpsilon(pctxt->am, start, end); 12673 ret = 1; 12674 } 12675 pctxt->state = end; 12676 return(ret); 12677 } 12678 12679 /** 12680 * xmlSchemaBuildContentModelForElement: 12681 * 12682 * Returns 1 if nillable, 0 otherwise 12683 */ 12684 static int 12685 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12686 xmlSchemaParticlePtr particle) 12687 { 12688 int ret = 0; 12689 12690 if (((xmlSchemaElementPtr) particle->children)->flags & 12691 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12692 /* 12693 * Substitution groups. 12694 */ 12695 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12696 } else { 12697 xmlSchemaElementPtr elemDecl; 12698 xmlAutomataStatePtr start; 12699 12700 elemDecl = (xmlSchemaElementPtr) particle->children; 12701 12702 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12703 return(0); 12704 if (particle->maxOccurs == 1) { 12705 start = ctxt->state; 12706 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12707 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12708 } else if ((particle->maxOccurs >= UNBOUNDED) && 12709 (particle->minOccurs < 2)) { 12710 /* Special case. */ 12711 start = ctxt->state; 12712 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12713 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12714 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12715 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12716 } else { 12717 int counter; 12718 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12719 UNBOUNDED : particle->maxOccurs - 1; 12720 int minOccurs = particle->minOccurs < 1 ? 12721 0 : particle->minOccurs - 1; 12722 12723 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12724 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12725 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12726 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12727 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12728 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12729 NULL, counter); 12730 } 12731 if (particle->minOccurs == 0) { 12732 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12733 ret = 1; 12734 } 12735 } 12736 return(ret); 12737 } 12738 12739 /** 12740 * xmlSchemaBuildAContentModel: 12741 * @ctxt: the schema parser context 12742 * @particle: the particle component 12743 * @name: the complex type's name whose content is being built 12744 * 12745 * Create the automaton for the {content type} of a complex type. 12746 * 12747 * Returns 1 if the content is nillable, 0 otherwise 12748 */ 12749 static int 12750 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12751 xmlSchemaParticlePtr particle) 12752 { 12753 int ret = 0, tmp2; 12754 12755 if (particle == NULL) { 12756 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12757 return(1); 12758 } 12759 if (particle->children == NULL) { 12760 /* 12761 * Just return in this case. A missing "term" of the particle 12762 * might arise due to an invalid "term" component. 12763 */ 12764 return(1); 12765 } 12766 12767 switch (particle->children->type) { 12768 case XML_SCHEMA_TYPE_ANY: { 12769 xmlAutomataStatePtr start, end; 12770 xmlSchemaWildcardPtr wild; 12771 xmlSchemaWildcardNsPtr ns; 12772 12773 wild = (xmlSchemaWildcardPtr) particle->children; 12774 12775 start = pctxt->state; 12776 end = xmlAutomataNewState(pctxt->am); 12777 12778 if (particle->maxOccurs == 1) { 12779 if (wild->any == 1) { 12780 /* 12781 * We need to add both transitions: 12782 * 12783 * 1. the {"*", "*"} for elements in a namespace. 12784 */ 12785 pctxt->state = 12786 xmlAutomataNewTransition2(pctxt->am, 12787 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12788 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12789 /* 12790 * 2. the {"*"} for elements in no namespace. 12791 */ 12792 pctxt->state = 12793 xmlAutomataNewTransition2(pctxt->am, 12794 start, NULL, BAD_CAST "*", NULL, wild); 12795 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12796 12797 } else if (wild->nsSet != NULL) { 12798 ns = wild->nsSet; 12799 do { 12800 pctxt->state = start; 12801 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12802 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12803 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12804 ns = ns->next; 12805 } while (ns != NULL); 12806 12807 } else if (wild->negNsSet != NULL) { 12808 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12809 start, end, BAD_CAST "*", wild->negNsSet->value, 12810 wild); 12811 } 12812 } else { 12813 int counter; 12814 xmlAutomataStatePtr hop; 12815 int maxOccurs = 12816 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12817 particle->maxOccurs - 1; 12818 int minOccurs = 12819 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12820 12821 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12822 hop = xmlAutomataNewState(pctxt->am); 12823 if (wild->any == 1) { 12824 pctxt->state = 12825 xmlAutomataNewTransition2(pctxt->am, 12826 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12827 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12828 pctxt->state = 12829 xmlAutomataNewTransition2(pctxt->am, 12830 start, NULL, BAD_CAST "*", NULL, wild); 12831 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12832 } else if (wild->nsSet != NULL) { 12833 ns = wild->nsSet; 12834 do { 12835 pctxt->state = 12836 xmlAutomataNewTransition2(pctxt->am, 12837 start, NULL, BAD_CAST "*", ns->value, wild); 12838 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12839 ns = ns->next; 12840 } while (ns != NULL); 12841 12842 } else if (wild->negNsSet != NULL) { 12843 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12844 start, hop, BAD_CAST "*", wild->negNsSet->value, 12845 wild); 12846 } 12847 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12848 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12849 } 12850 if (particle->minOccurs == 0) { 12851 xmlAutomataNewEpsilon(pctxt->am, start, end); 12852 ret = 1; 12853 } 12854 pctxt->state = end; 12855 break; 12856 } 12857 case XML_SCHEMA_TYPE_ELEMENT: 12858 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12859 break; 12860 case XML_SCHEMA_TYPE_SEQUENCE:{ 12861 xmlSchemaTreeItemPtr sub; 12862 12863 ret = 1; 12864 /* 12865 * If max and min occurances are default (1) then 12866 * simply iterate over the particles of the <sequence>. 12867 */ 12868 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12869 sub = particle->children->children; 12870 12871 while (sub != NULL) { 12872 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12873 (xmlSchemaParticlePtr) sub); 12874 if (tmp2 != 1) ret = 0; 12875 sub = sub->next; 12876 } 12877 } else { 12878 xmlAutomataStatePtr oldstate = pctxt->state; 12879 12880 if (particle->maxOccurs >= UNBOUNDED) { 12881 if (particle->minOccurs > 1) { 12882 xmlAutomataStatePtr tmp; 12883 int counter; 12884 12885 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12886 oldstate, NULL); 12887 oldstate = pctxt->state; 12888 12889 counter = xmlAutomataNewCounter(pctxt->am, 12890 particle->minOccurs - 1, UNBOUNDED); 12891 12892 sub = particle->children->children; 12893 while (sub != NULL) { 12894 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12895 (xmlSchemaParticlePtr) sub); 12896 if (tmp2 != 1) ret = 0; 12897 sub = sub->next; 12898 } 12899 tmp = pctxt->state; 12900 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12901 oldstate, counter); 12902 pctxt->state = 12903 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12904 NULL, counter); 12905 if (ret == 1) 12906 xmlAutomataNewEpsilon(pctxt->am, 12907 oldstate, pctxt->state); 12908 12909 } else { 12910 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12911 oldstate, NULL); 12912 oldstate = pctxt->state; 12913 12914 sub = particle->children->children; 12915 while (sub != NULL) { 12916 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12917 (xmlSchemaParticlePtr) sub); 12918 if (tmp2 != 1) ret = 0; 12919 sub = sub->next; 12920 } 12921 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12922 oldstate); 12923 /* 12924 * epsilon needed to block previous trans from 12925 * being allowed to enter back from another 12926 * construct 12927 */ 12928 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12929 pctxt->state, NULL); 12930 if (particle->minOccurs == 0) { 12931 xmlAutomataNewEpsilon(pctxt->am, 12932 oldstate, pctxt->state); 12933 ret = 1; 12934 } 12935 } 12936 } else if ((particle->maxOccurs > 1) 12937 || (particle->minOccurs > 1)) { 12938 xmlAutomataStatePtr tmp; 12939 int counter; 12940 12941 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12942 oldstate, NULL); 12943 oldstate = pctxt->state; 12944 12945 counter = xmlAutomataNewCounter(pctxt->am, 12946 particle->minOccurs - 1, 12947 particle->maxOccurs - 1); 12948 12949 sub = particle->children->children; 12950 while (sub != NULL) { 12951 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12952 (xmlSchemaParticlePtr) sub); 12953 if (tmp2 != 1) ret = 0; 12954 sub = sub->next; 12955 } 12956 tmp = pctxt->state; 12957 xmlAutomataNewCountedTrans(pctxt->am, 12958 tmp, oldstate, counter); 12959 pctxt->state = 12960 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12961 counter); 12962 if ((particle->minOccurs == 0) || (ret == 1)) { 12963 xmlAutomataNewEpsilon(pctxt->am, 12964 oldstate, pctxt->state); 12965 ret = 1; 12966 } 12967 } else { 12968 sub = particle->children->children; 12969 while (sub != NULL) { 12970 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12971 (xmlSchemaParticlePtr) sub); 12972 if (tmp2 != 1) ret = 0; 12973 sub = sub->next; 12974 } 12975 12976 /* 12977 * epsilon needed to block previous trans from 12978 * being allowed to enter back from another 12979 * construct 12980 */ 12981 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12982 pctxt->state, NULL); 12983 12984 if (particle->minOccurs == 0) { 12985 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12986 pctxt->state); 12987 ret = 1; 12988 } 12989 } 12990 } 12991 break; 12992 } 12993 case XML_SCHEMA_TYPE_CHOICE:{ 12994 xmlSchemaTreeItemPtr sub; 12995 xmlAutomataStatePtr start, end; 12996 12997 ret = 0; 12998 start = pctxt->state; 12999 end = xmlAutomataNewState(pctxt->am); 13000 13001 /* 13002 * iterate over the subtypes and remerge the end with an 13003 * epsilon transition 13004 */ 13005 if (particle->maxOccurs == 1) { 13006 sub = particle->children->children; 13007 while (sub != NULL) { 13008 pctxt->state = start; 13009 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13010 (xmlSchemaParticlePtr) sub); 13011 if (tmp2 == 1) ret = 1; 13012 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13013 sub = sub->next; 13014 } 13015 } else { 13016 int counter; 13017 xmlAutomataStatePtr hop, base; 13018 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13019 UNBOUNDED : particle->maxOccurs - 1; 13020 int minOccurs = 13021 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13022 13023 /* 13024 * use a counter to keep track of the number of transtions 13025 * which went through the choice. 13026 */ 13027 counter = 13028 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13029 hop = xmlAutomataNewState(pctxt->am); 13030 base = xmlAutomataNewState(pctxt->am); 13031 13032 sub = particle->children->children; 13033 while (sub != NULL) { 13034 pctxt->state = base; 13035 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13036 (xmlSchemaParticlePtr) sub); 13037 if (tmp2 == 1) ret = 1; 13038 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13039 sub = sub->next; 13040 } 13041 xmlAutomataNewEpsilon(pctxt->am, start, base); 13042 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13043 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13044 if (ret == 1) 13045 xmlAutomataNewEpsilon(pctxt->am, base, end); 13046 } 13047 if (particle->minOccurs == 0) { 13048 xmlAutomataNewEpsilon(pctxt->am, start, end); 13049 ret = 1; 13050 } 13051 pctxt->state = end; 13052 break; 13053 } 13054 case XML_SCHEMA_TYPE_ALL:{ 13055 xmlAutomataStatePtr start, tmp; 13056 xmlSchemaParticlePtr sub; 13057 xmlSchemaElementPtr elemDecl; 13058 13059 ret = 1; 13060 13061 sub = (xmlSchemaParticlePtr) particle->children->children; 13062 if (sub == NULL) 13063 break; 13064 13065 ret = 0; 13066 13067 start = pctxt->state; 13068 tmp = xmlAutomataNewState(pctxt->am); 13069 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13070 pctxt->state = tmp; 13071 while (sub != NULL) { 13072 pctxt->state = tmp; 13073 13074 elemDecl = (xmlSchemaElementPtr) sub->children; 13075 if (elemDecl == NULL) { 13076 PERROR_INT("xmlSchemaBuildAContentModel", 13077 "<element> particle has no term"); 13078 return(ret); 13079 }; 13080 /* 13081 * NOTE: The {max occurs} of all the particles in the 13082 * {particles} of the group must be 0 or 1; this is 13083 * already ensured during the parse of the content of 13084 * <all>. 13085 */ 13086 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13087 int counter; 13088 13089 /* 13090 * This is an abstract group, we need to share 13091 * the same counter for all the element transitions 13092 * derived from the group 13093 */ 13094 counter = xmlAutomataNewCounter(pctxt->am, 13095 sub->minOccurs, sub->maxOccurs); 13096 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13097 sub, counter, pctxt->state); 13098 } else { 13099 if ((sub->minOccurs == 1) && 13100 (sub->maxOccurs == 1)) { 13101 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13102 pctxt->state, 13103 elemDecl->name, 13104 elemDecl->targetNamespace, 13105 1, 1, elemDecl); 13106 } else if ((sub->minOccurs == 0) && 13107 (sub->maxOccurs == 1)) { 13108 13109 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13110 pctxt->state, 13111 elemDecl->name, 13112 elemDecl->targetNamespace, 13113 0, 13114 1, 13115 elemDecl); 13116 } 13117 } 13118 sub = (xmlSchemaParticlePtr) sub->next; 13119 } 13120 pctxt->state = 13121 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13122 if (particle->minOccurs == 0) { 13123 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13124 ret = 1; 13125 } 13126 break; 13127 } 13128 case XML_SCHEMA_TYPE_GROUP: 13129 /* 13130 * If we hit a model group definition, then this means that 13131 * it was empty, thus was not substituted for the containing 13132 * model group. Just do nothing in this case. 13133 * TODO: But the group should be substituted and not occur at 13134 * all in the content model at this point. Fix this. 13135 */ 13136 ret = 1; 13137 break; 13138 default: 13139 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13140 "xmlSchemaBuildAContentModel", 13141 "found unexpected term of type '%s' in content model", 13142 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13143 return(ret); 13144 } 13145 return(ret); 13146 } 13147 13148 /** 13149 * xmlSchemaBuildContentModel: 13150 * @ctxt: the schema parser context 13151 * @type: the complex type definition 13152 * @name: the element name 13153 * 13154 * Builds the content model of the complex type. 13155 */ 13156 static void 13157 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13158 xmlSchemaParserCtxtPtr ctxt) 13159 { 13160 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13161 (type->contModel != NULL) || 13162 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13163 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13164 return; 13165 13166 #ifdef DEBUG_CONTENT 13167 xmlGenericError(xmlGenericErrorContext, 13168 "Building content model for %s\n", name); 13169 #endif 13170 ctxt->am = NULL; 13171 ctxt->am = xmlNewAutomata(); 13172 if (ctxt->am == NULL) { 13173 xmlGenericError(xmlGenericErrorContext, 13174 "Cannot create automata for complex type %s\n", type->name); 13175 return; 13176 } 13177 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13178 /* 13179 * Build the automaton. 13180 */ 13181 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13182 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13183 type->contModel = xmlAutomataCompile(ctxt->am); 13184 if (type->contModel == NULL) { 13185 xmlSchemaPCustomErr(ctxt, 13186 XML_SCHEMAP_INTERNAL, 13187 WXS_BASIC_CAST type, type->node, 13188 "Failed to compile the content model", NULL); 13189 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13190 xmlSchemaPCustomErr(ctxt, 13191 XML_SCHEMAP_NOT_DETERMINISTIC, 13192 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13193 WXS_BASIC_CAST type, type->node, 13194 "The content model is not determinist", NULL); 13195 } else { 13196 #ifdef DEBUG_CONTENT_REGEXP 13197 xmlGenericError(xmlGenericErrorContext, 13198 "Content model of %s:\n", type->name); 13199 xmlRegexpPrint(stderr, type->contModel); 13200 #endif 13201 } 13202 ctxt->state = NULL; 13203 xmlFreeAutomata(ctxt->am); 13204 ctxt->am = NULL; 13205 } 13206 13207 /** 13208 * xmlSchemaResolveElementReferences: 13209 * @elem: the schema element context 13210 * @ctxt: the schema parser context 13211 * 13212 * Resolves the references of an element declaration 13213 * or particle, which has an element declaration as it's 13214 * term. 13215 */ 13216 static void 13217 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13218 xmlSchemaParserCtxtPtr ctxt) 13219 { 13220 if ((ctxt == NULL) || (elemDecl == NULL) || 13221 ((elemDecl != NULL) && 13222 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13223 return; 13224 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13225 13226 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13227 xmlSchemaTypePtr type; 13228 13229 /* (type definition) ... otherwise the type definition `resolved` 13230 * to by the `actual value` of the type [attribute] ... 13231 */ 13232 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13233 elemDecl->namedTypeNs); 13234 if (type == NULL) { 13235 xmlSchemaPResCompAttrErr(ctxt, 13236 XML_SCHEMAP_SRC_RESOLVE, 13237 WXS_BASIC_CAST elemDecl, elemDecl->node, 13238 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13239 XML_SCHEMA_TYPE_BASIC, "type definition"); 13240 } else 13241 elemDecl->subtypes = type; 13242 } 13243 if (elemDecl->substGroup != NULL) { 13244 xmlSchemaElementPtr substHead; 13245 13246 /* 13247 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13248 * substitutionGroup? 13249 */ 13250 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13251 elemDecl->substGroupNs); 13252 if (substHead == NULL) { 13253 xmlSchemaPResCompAttrErr(ctxt, 13254 XML_SCHEMAP_SRC_RESOLVE, 13255 WXS_BASIC_CAST elemDecl, NULL, 13256 "substitutionGroup", elemDecl->substGroup, 13257 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13258 } else { 13259 xmlSchemaResolveElementReferences(substHead, ctxt); 13260 /* 13261 * Set the "substitution group affiliation". 13262 * NOTE that now we use the "refDecl" field for this. 13263 */ 13264 WXS_SUBST_HEAD(elemDecl) = substHead; 13265 /* 13266 * The type definitions is set to: 13267 * SPEC "...the {type definition} of the element 13268 * declaration `resolved` to by the `actual value` 13269 * of the substitutionGroup [attribute], if present" 13270 */ 13271 if (elemDecl->subtypes == NULL) 13272 elemDecl->subtypes = substHead->subtypes; 13273 } 13274 } 13275 /* 13276 * SPEC "The definition of anyType serves as the default type definition 13277 * for element declarations whose XML representation does not specify one." 13278 */ 13279 if ((elemDecl->subtypes == NULL) && 13280 (elemDecl->namedType == NULL) && 13281 (elemDecl->substGroup == NULL)) 13282 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13283 } 13284 13285 /** 13286 * xmlSchemaResolveUnionMemberTypes: 13287 * @ctxt: the schema parser context 13288 * @type: the schema simple type definition 13289 * 13290 * Checks and builds the "member type definitions" property of the union 13291 * simple type. This handles part (1), part (2) is done in 13292 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13293 * 13294 * Returns -1 in case of an internal error, 0 otherwise. 13295 */ 13296 static int 13297 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13298 xmlSchemaTypePtr type) 13299 { 13300 13301 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13302 xmlSchemaTypePtr memberType; 13303 13304 /* 13305 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13306 * define the explicit members as the type definitions `resolved` 13307 * to by the items in the `actual value` of the memberTypes [attribute], 13308 * if any, followed by the type definitions corresponding to the 13309 * <simpleType>s among the [children] of <union>, if any." 13310 */ 13311 /* 13312 * Resolve references. 13313 */ 13314 link = type->memberTypes; 13315 lastLink = NULL; 13316 while (link != NULL) { 13317 const xmlChar *name, *nsName; 13318 13319 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13320 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13321 13322 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13323 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13324 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13325 WXS_BASIC_CAST type, type->node, "memberTypes", 13326 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13327 /* 13328 * Remove the member type link. 13329 */ 13330 if (lastLink == NULL) 13331 type->memberTypes = link->next; 13332 else 13333 lastLink->next = link->next; 13334 newLink = link; 13335 link = link->next; 13336 xmlFree(newLink); 13337 } else { 13338 link->type = memberType; 13339 lastLink = link; 13340 link = link->next; 13341 } 13342 } 13343 /* 13344 * Add local simple types, 13345 */ 13346 memberType = type->subtypes; 13347 while (memberType != NULL) { 13348 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13349 if (link == NULL) { 13350 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13351 return (-1); 13352 } 13353 link->type = memberType; 13354 link->next = NULL; 13355 if (lastLink == NULL) 13356 type->memberTypes = link; 13357 else 13358 lastLink->next = link; 13359 lastLink = link; 13360 memberType = memberType->next; 13361 } 13362 return (0); 13363 } 13364 13365 /** 13366 * xmlSchemaIsDerivedFromBuiltInType: 13367 * @ctxt: the schema parser context 13368 * @type: the type definition 13369 * @valType: the value type 13370 * 13371 * 13372 * Returns 1 if the type has the given value type, or 13373 * is derived from such a type. 13374 */ 13375 static int 13376 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13377 { 13378 if (type == NULL) 13379 return (0); 13380 if (WXS_IS_COMPLEX(type)) 13381 return (0); 13382 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13383 if (type->builtInType == valType) 13384 return(1); 13385 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13386 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13387 return (0); 13388 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13389 } 13390 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13391 } 13392 13393 #if 0 13394 /** 13395 * xmlSchemaIsDerivedFromBuiltInType: 13396 * @ctxt: the schema parser context 13397 * @type: the type definition 13398 * @valType: the value type 13399 * 13400 * 13401 * Returns 1 if the type has the given value type, or 13402 * is derived from such a type. 13403 */ 13404 static int 13405 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13406 { 13407 if (type == NULL) 13408 return (0); 13409 if (WXS_IS_COMPLEX(type)) 13410 return (0); 13411 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13412 if (type->builtInType == valType) 13413 return(1); 13414 return (0); 13415 } else 13416 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13417 13418 return (0); 13419 } 13420 13421 static xmlSchemaTypePtr 13422 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13423 { 13424 if (type == NULL) 13425 return (NULL); 13426 if (WXS_IS_COMPLEX(type)) 13427 return (NULL); 13428 if (type->type == XML_SCHEMA_TYPE_BASIC) 13429 return(type); 13430 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13431 } 13432 #endif 13433 13434 /** 13435 * xmlSchemaGetPrimitiveType: 13436 * @type: the simpleType definition 13437 * 13438 * Returns the primitive type of the given type or 13439 * NULL in case of error. 13440 */ 13441 static xmlSchemaTypePtr 13442 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13443 { 13444 13445 while (type != NULL) { 13446 /* 13447 * Note that anySimpleType is actually not a primitive type 13448 * but we need that here. 13449 */ 13450 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13451 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13452 return (type); 13453 type = type->baseType; 13454 } 13455 13456 return (NULL); 13457 } 13458 13459 #if 0 13460 /** 13461 * xmlSchemaGetBuiltInTypeAncestor: 13462 * @type: the simpleType definition 13463 * 13464 * Returns the primitive type of the given type or 13465 * NULL in case of error. 13466 */ 13467 static xmlSchemaTypePtr 13468 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13469 { 13470 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13471 return (0); 13472 while (type != NULL) { 13473 if (type->type == XML_SCHEMA_TYPE_BASIC) 13474 return (type); 13475 type = type->baseType; 13476 } 13477 13478 return (NULL); 13479 } 13480 #endif 13481 13482 /** 13483 * xmlSchemaCloneWildcardNsConstraints: 13484 * @ctxt: the schema parser context 13485 * @dest: the destination wildcard 13486 * @source: the source wildcard 13487 * 13488 * Clones the namespace constraints of source 13489 * and assignes them to dest. 13490 * Returns -1 on internal error, 0 otherwise. 13491 */ 13492 static int 13493 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13494 xmlSchemaWildcardPtr dest, 13495 xmlSchemaWildcardPtr source) 13496 { 13497 xmlSchemaWildcardNsPtr cur, tmp, last; 13498 13499 if ((source == NULL) || (dest == NULL)) 13500 return(-1); 13501 dest->any = source->any; 13502 cur = source->nsSet; 13503 last = NULL; 13504 while (cur != NULL) { 13505 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13506 if (tmp == NULL) 13507 return(-1); 13508 tmp->value = cur->value; 13509 if (last == NULL) 13510 dest->nsSet = tmp; 13511 else 13512 last->next = tmp; 13513 last = tmp; 13514 cur = cur->next; 13515 } 13516 if (dest->negNsSet != NULL) 13517 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13518 if (source->negNsSet != NULL) { 13519 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13520 if (dest->negNsSet == NULL) 13521 return(-1); 13522 dest->negNsSet->value = source->negNsSet->value; 13523 } else 13524 dest->negNsSet = NULL; 13525 return(0); 13526 } 13527 13528 /** 13529 * xmlSchemaUnionWildcards: 13530 * @ctxt: the schema parser context 13531 * @completeWild: the first wildcard 13532 * @curWild: the second wildcard 13533 * 13534 * Unions the namespace constraints of the given wildcards. 13535 * @completeWild will hold the resulting union. 13536 * Returns a positive error code on failure, -1 in case of an 13537 * internal error, 0 otherwise. 13538 */ 13539 static int 13540 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13541 xmlSchemaWildcardPtr completeWild, 13542 xmlSchemaWildcardPtr curWild) 13543 { 13544 xmlSchemaWildcardNsPtr cur, curB, tmp; 13545 13546 /* 13547 * 1 If O1 and O2 are the same value, then that value must be the 13548 * value. 13549 */ 13550 if ((completeWild->any == curWild->any) && 13551 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13552 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13553 13554 if ((completeWild->negNsSet == NULL) || 13555 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13556 13557 if (completeWild->nsSet != NULL) { 13558 int found = 0; 13559 13560 /* 13561 * Check equality of sets. 13562 */ 13563 cur = completeWild->nsSet; 13564 while (cur != NULL) { 13565 found = 0; 13566 curB = curWild->nsSet; 13567 while (curB != NULL) { 13568 if (cur->value == curB->value) { 13569 found = 1; 13570 break; 13571 } 13572 curB = curB->next; 13573 } 13574 if (!found) 13575 break; 13576 cur = cur->next; 13577 } 13578 if (found) 13579 return(0); 13580 } else 13581 return(0); 13582 } 13583 } 13584 /* 13585 * 2 If either O1 or O2 is any, then any must be the value 13586 */ 13587 if (completeWild->any != curWild->any) { 13588 if (completeWild->any == 0) { 13589 completeWild->any = 1; 13590 if (completeWild->nsSet != NULL) { 13591 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13592 completeWild->nsSet = NULL; 13593 } 13594 if (completeWild->negNsSet != NULL) { 13595 xmlFree(completeWild->negNsSet); 13596 completeWild->negNsSet = NULL; 13597 } 13598 } 13599 return (0); 13600 } 13601 /* 13602 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13603 * then the union of those sets must be the value. 13604 */ 13605 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13606 int found; 13607 xmlSchemaWildcardNsPtr start; 13608 13609 cur = curWild->nsSet; 13610 start = completeWild->nsSet; 13611 while (cur != NULL) { 13612 found = 0; 13613 curB = start; 13614 while (curB != NULL) { 13615 if (cur->value == curB->value) { 13616 found = 1; 13617 break; 13618 } 13619 curB = curB->next; 13620 } 13621 if (!found) { 13622 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13623 if (tmp == NULL) 13624 return (-1); 13625 tmp->value = cur->value; 13626 tmp->next = completeWild->nsSet; 13627 completeWild->nsSet = tmp; 13628 } 13629 cur = cur->next; 13630 } 13631 13632 return(0); 13633 } 13634 /* 13635 * 4 If the two are negations of different values (namespace names 13636 * or `absent`), then a pair of not and `absent` must be the value. 13637 */ 13638 if ((completeWild->negNsSet != NULL) && 13639 (curWild->negNsSet != NULL) && 13640 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13641 completeWild->negNsSet->value = NULL; 13642 13643 return(0); 13644 } 13645 /* 13646 * 5. 13647 */ 13648 if (((completeWild->negNsSet != NULL) && 13649 (completeWild->negNsSet->value != NULL) && 13650 (curWild->nsSet != NULL)) || 13651 ((curWild->negNsSet != NULL) && 13652 (curWild->negNsSet->value != NULL) && 13653 (completeWild->nsSet != NULL))) { 13654 13655 int nsFound, absentFound = 0; 13656 13657 if (completeWild->nsSet != NULL) { 13658 cur = completeWild->nsSet; 13659 curB = curWild->negNsSet; 13660 } else { 13661 cur = curWild->nsSet; 13662 curB = completeWild->negNsSet; 13663 } 13664 nsFound = 0; 13665 while (cur != NULL) { 13666 if (cur->value == NULL) 13667 absentFound = 1; 13668 else if (cur->value == curB->value) 13669 nsFound = 1; 13670 if (nsFound && absentFound) 13671 break; 13672 cur = cur->next; 13673 } 13674 13675 if (nsFound && absentFound) { 13676 /* 13677 * 5.1 If the set S includes both the negated namespace 13678 * name and `absent`, then any must be the value. 13679 */ 13680 completeWild->any = 1; 13681 if (completeWild->nsSet != NULL) { 13682 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13683 completeWild->nsSet = NULL; 13684 } 13685 if (completeWild->negNsSet != NULL) { 13686 xmlFree(completeWild->negNsSet); 13687 completeWild->negNsSet = NULL; 13688 } 13689 } else if (nsFound && (!absentFound)) { 13690 /* 13691 * 5.2 If the set S includes the negated namespace name 13692 * but not `absent`, then a pair of not and `absent` must 13693 * be the value. 13694 */ 13695 if (completeWild->nsSet != NULL) { 13696 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13697 completeWild->nsSet = NULL; 13698 } 13699 if (completeWild->negNsSet == NULL) { 13700 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13701 if (completeWild->negNsSet == NULL) 13702 return (-1); 13703 } 13704 completeWild->negNsSet->value = NULL; 13705 } else if ((!nsFound) && absentFound) { 13706 /* 13707 * 5.3 If the set S includes `absent` but not the negated 13708 * namespace name, then the union is not expressible. 13709 */ 13710 xmlSchemaPErr(ctxt, completeWild->node, 13711 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13712 "The union of the wilcard is not expressible.\n", 13713 NULL, NULL); 13714 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13715 } else if ((!nsFound) && (!absentFound)) { 13716 /* 13717 * 5.4 If the set S does not include either the negated namespace 13718 * name or `absent`, then whichever of O1 or O2 is a pair of not 13719 * and a namespace name must be the value. 13720 */ 13721 if (completeWild->negNsSet == NULL) { 13722 if (completeWild->nsSet != NULL) { 13723 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13724 completeWild->nsSet = NULL; 13725 } 13726 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13727 if (completeWild->negNsSet == NULL) 13728 return (-1); 13729 completeWild->negNsSet->value = curWild->negNsSet->value; 13730 } 13731 } 13732 return (0); 13733 } 13734 /* 13735 * 6. 13736 */ 13737 if (((completeWild->negNsSet != NULL) && 13738 (completeWild->negNsSet->value == NULL) && 13739 (curWild->nsSet != NULL)) || 13740 ((curWild->negNsSet != NULL) && 13741 (curWild->negNsSet->value == NULL) && 13742 (completeWild->nsSet != NULL))) { 13743 13744 if (completeWild->nsSet != NULL) { 13745 cur = completeWild->nsSet; 13746 } else { 13747 cur = curWild->nsSet; 13748 } 13749 while (cur != NULL) { 13750 if (cur->value == NULL) { 13751 /* 13752 * 6.1 If the set S includes `absent`, then any must be the 13753 * value. 13754 */ 13755 completeWild->any = 1; 13756 if (completeWild->nsSet != NULL) { 13757 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13758 completeWild->nsSet = NULL; 13759 } 13760 if (completeWild->negNsSet != NULL) { 13761 xmlFree(completeWild->negNsSet); 13762 completeWild->negNsSet = NULL; 13763 } 13764 return (0); 13765 } 13766 cur = cur->next; 13767 } 13768 if (completeWild->negNsSet == NULL) { 13769 /* 13770 * 6.2 If the set S does not include `absent`, then a pair of not 13771 * and `absent` must be the value. 13772 */ 13773 if (completeWild->nsSet != NULL) { 13774 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13775 completeWild->nsSet = NULL; 13776 } 13777 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13778 if (completeWild->negNsSet == NULL) 13779 return (-1); 13780 completeWild->negNsSet->value = NULL; 13781 } 13782 return (0); 13783 } 13784 return (0); 13785 13786 } 13787 13788 /** 13789 * xmlSchemaIntersectWildcards: 13790 * @ctxt: the schema parser context 13791 * @completeWild: the first wildcard 13792 * @curWild: the second wildcard 13793 * 13794 * Intersects the namespace constraints of the given wildcards. 13795 * @completeWild will hold the resulting intersection. 13796 * Returns a positive error code on failure, -1 in case of an 13797 * internal error, 0 otherwise. 13798 */ 13799 static int 13800 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13801 xmlSchemaWildcardPtr completeWild, 13802 xmlSchemaWildcardPtr curWild) 13803 { 13804 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13805 13806 /* 13807 * 1 If O1 and O2 are the same value, then that value must be the 13808 * value. 13809 */ 13810 if ((completeWild->any == curWild->any) && 13811 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13812 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13813 13814 if ((completeWild->negNsSet == NULL) || 13815 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13816 13817 if (completeWild->nsSet != NULL) { 13818 int found = 0; 13819 13820 /* 13821 * Check equality of sets. 13822 */ 13823 cur = completeWild->nsSet; 13824 while (cur != NULL) { 13825 found = 0; 13826 curB = curWild->nsSet; 13827 while (curB != NULL) { 13828 if (cur->value == curB->value) { 13829 found = 1; 13830 break; 13831 } 13832 curB = curB->next; 13833 } 13834 if (!found) 13835 break; 13836 cur = cur->next; 13837 } 13838 if (found) 13839 return(0); 13840 } else 13841 return(0); 13842 } 13843 } 13844 /* 13845 * 2 If either O1 or O2 is any, then the other must be the value. 13846 */ 13847 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13848 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13849 return(-1); 13850 return(0); 13851 } 13852 /* 13853 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13854 * name or `absent`) and the other is a set of (namespace names or 13855 * `absent`), then that set, minus the negated value if it was in 13856 * the set, minus `absent` if it was in the set, must be the value. 13857 */ 13858 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13859 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13860 const xmlChar *neg; 13861 13862 if (completeWild->nsSet == NULL) { 13863 neg = completeWild->negNsSet->value; 13864 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13865 return(-1); 13866 } else 13867 neg = curWild->negNsSet->value; 13868 /* 13869 * Remove absent and negated. 13870 */ 13871 prev = NULL; 13872 cur = completeWild->nsSet; 13873 while (cur != NULL) { 13874 if (cur->value == NULL) { 13875 if (prev == NULL) 13876 completeWild->nsSet = cur->next; 13877 else 13878 prev->next = cur->next; 13879 xmlFree(cur); 13880 break; 13881 } 13882 prev = cur; 13883 cur = cur->next; 13884 } 13885 if (neg != NULL) { 13886 prev = NULL; 13887 cur = completeWild->nsSet; 13888 while (cur != NULL) { 13889 if (cur->value == neg) { 13890 if (prev == NULL) 13891 completeWild->nsSet = cur->next; 13892 else 13893 prev->next = cur->next; 13894 xmlFree(cur); 13895 break; 13896 } 13897 prev = cur; 13898 cur = cur->next; 13899 } 13900 } 13901 13902 return(0); 13903 } 13904 /* 13905 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13906 * then the intersection of those sets must be the value. 13907 */ 13908 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13909 int found; 13910 13911 cur = completeWild->nsSet; 13912 prev = NULL; 13913 while (cur != NULL) { 13914 found = 0; 13915 curB = curWild->nsSet; 13916 while (curB != NULL) { 13917 if (cur->value == curB->value) { 13918 found = 1; 13919 break; 13920 } 13921 curB = curB->next; 13922 } 13923 if (!found) { 13924 if (prev == NULL) 13925 completeWild->nsSet = cur->next; 13926 else 13927 prev->next = cur->next; 13928 tmp = cur->next; 13929 xmlFree(cur); 13930 cur = tmp; 13931 continue; 13932 } 13933 prev = cur; 13934 cur = cur->next; 13935 } 13936 13937 return(0); 13938 } 13939 /* 5 If the two are negations of different namespace names, 13940 * then the intersection is not expressible 13941 */ 13942 if ((completeWild->negNsSet != NULL) && 13943 (curWild->negNsSet != NULL) && 13944 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13945 (completeWild->negNsSet->value != NULL) && 13946 (curWild->negNsSet->value != NULL)) { 13947 13948 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13949 "The intersection of the wilcard is not expressible.\n", 13950 NULL, NULL); 13951 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13952 } 13953 /* 13954 * 6 If the one is a negation of a namespace name and the other 13955 * is a negation of `absent`, then the one which is the negation 13956 * of a namespace name must be the value. 13957 */ 13958 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13959 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13960 (completeWild->negNsSet->value == NULL)) { 13961 completeWild->negNsSet->value = curWild->negNsSet->value; 13962 } 13963 return(0); 13964 } 13965 13966 /** 13967 * xmlSchemaIsWildcardNsConstraintSubset: 13968 * @ctxt: the schema parser context 13969 * @sub: the first wildcard 13970 * @super: the second wildcard 13971 * 13972 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13973 * 13974 * Returns 0 if the namespace constraint of @sub is an intensional 13975 * subset of @super, 1 otherwise. 13976 */ 13977 static int 13978 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13979 xmlSchemaWildcardPtr super) 13980 { 13981 /* 13982 * 1 super must be any. 13983 */ 13984 if (super->any) 13985 return (0); 13986 /* 13987 * 2.1 sub must be a pair of not and a namespace name or `absent`. 13988 * 2.2 super must be a pair of not and the same value. 13989 */ 13990 if ((sub->negNsSet != NULL) && 13991 (super->negNsSet != NULL) && 13992 (sub->negNsSet->value == super->negNsSet->value)) 13993 return (0); 13994 /* 13995 * 3.1 sub must be a set whose members are either namespace names or `absent`. 13996 */ 13997 if (sub->nsSet != NULL) { 13998 /* 13999 * 3.2.1 super must be the same set or a superset thereof. 14000 */ 14001 if (super->nsSet != NULL) { 14002 xmlSchemaWildcardNsPtr cur, curB; 14003 int found = 0; 14004 14005 cur = sub->nsSet; 14006 while (cur != NULL) { 14007 found = 0; 14008 curB = super->nsSet; 14009 while (curB != NULL) { 14010 if (cur->value == curB->value) { 14011 found = 1; 14012 break; 14013 } 14014 curB = curB->next; 14015 } 14016 if (!found) 14017 return (1); 14018 cur = cur->next; 14019 } 14020 if (found) 14021 return (0); 14022 } else if (super->negNsSet != NULL) { 14023 xmlSchemaWildcardNsPtr cur; 14024 /* 14025 * 3.2.2 super must be a pair of not and a namespace name or 14026 * `absent` and that value must not be in sub's set. 14027 */ 14028 cur = sub->nsSet; 14029 while (cur != NULL) { 14030 if (cur->value == super->negNsSet->value) 14031 return (1); 14032 cur = cur->next; 14033 } 14034 return (0); 14035 } 14036 } 14037 return (1); 14038 } 14039 14040 static int 14041 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14042 int *fixed, 14043 const xmlChar **value, 14044 xmlSchemaValPtr *val) 14045 { 14046 *fixed = 0; 14047 *value = NULL; 14048 if (val != 0) 14049 *val = NULL; 14050 14051 if (attruse->defValue != NULL) { 14052 *value = attruse->defValue; 14053 if (val != NULL) 14054 *val = attruse->defVal; 14055 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14056 *fixed = 1; 14057 return(1); 14058 } else if ((attruse->attrDecl != NULL) && 14059 (attruse->attrDecl->defValue != NULL)) { 14060 *value = attruse->attrDecl->defValue; 14061 if (val != NULL) 14062 *val = attruse->attrDecl->defVal; 14063 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14064 *fixed = 1; 14065 return(1); 14066 } 14067 return(0); 14068 } 14069 /** 14070 * xmlSchemaCheckCVCWildcardNamespace: 14071 * @wild: the wildcard 14072 * @ns: the namespace 14073 * 14074 * Validation Rule: Wildcard allows Namespace Name 14075 * (cvc-wildcard-namespace) 14076 * 14077 * Returns 0 if the given namespace matches the wildcard, 14078 * 1 otherwise and -1 on API errors. 14079 */ 14080 static int 14081 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14082 const xmlChar* ns) 14083 { 14084 if (wild == NULL) 14085 return(-1); 14086 14087 if (wild->any) 14088 return(0); 14089 else if (wild->nsSet != NULL) { 14090 xmlSchemaWildcardNsPtr cur; 14091 14092 cur = wild->nsSet; 14093 while (cur != NULL) { 14094 if (xmlStrEqual(cur->value, ns)) 14095 return(0); 14096 cur = cur->next; 14097 } 14098 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14099 (!xmlStrEqual(wild->negNsSet->value, ns))) 14100 return(0); 14101 14102 return(1); 14103 } 14104 14105 #define XML_SCHEMA_ACTION_DERIVE 0 14106 #define XML_SCHEMA_ACTION_REDEFINE 1 14107 14108 #define WXS_ACTION_STR(a) \ 14109 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14110 14111 /* 14112 * Schema Component Constraint: 14113 * Derivation Valid (Restriction, Complex) 14114 * derivation-ok-restriction (2) - (4) 14115 * 14116 * ATTENTION: 14117 * In XML Schema 1.1 this will be: 14118 * Validation Rule: 14119 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14120 * 14121 */ 14122 static int 14123 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14124 int action, 14125 xmlSchemaBasicItemPtr item, 14126 xmlSchemaBasicItemPtr baseItem, 14127 xmlSchemaItemListPtr uses, 14128 xmlSchemaItemListPtr baseUses, 14129 xmlSchemaWildcardPtr wild, 14130 xmlSchemaWildcardPtr baseWild) 14131 { 14132 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14133 int i, j, found; /* err = 0; */ 14134 const xmlChar *bEffValue; 14135 int effFixed; 14136 14137 if (uses != NULL) { 14138 for (i = 0; i < uses->nbItems; i++) { 14139 cur = uses->items[i]; 14140 found = 0; 14141 if (baseUses == NULL) 14142 goto not_found; 14143 for (j = 0; j < baseUses->nbItems; j++) { 14144 bcur = baseUses->items[j]; 14145 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14146 WXS_ATTRUSE_DECL_NAME(bcur)) && 14147 (WXS_ATTRUSE_DECL_TNS(cur) == 14148 WXS_ATTRUSE_DECL_TNS(bcur))) 14149 { 14150 /* 14151 * (2.1) "If there is an attribute use in the {attribute 14152 * uses} of the {base type definition} (call this B) whose 14153 * {attribute declaration} has the same {name} and {target 14154 * namespace}, then all of the following must be true:" 14155 */ 14156 found = 1; 14157 14158 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14159 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14160 { 14161 xmlChar *str = NULL; 14162 /* 14163 * (2.1.1) "one of the following must be true:" 14164 * (2.1.1.1) "B's {required} is false." 14165 * (2.1.1.2) "R's {required} is true." 14166 */ 14167 xmlSchemaPAttrUseErr4(pctxt, 14168 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14169 WXS_ITEM_NODE(item), item, cur, 14170 "The 'optional' attribute use is inconsistent " 14171 "with the corresponding 'required' attribute use of " 14172 "the %s %s", 14173 WXS_ACTION_STR(action), 14174 xmlSchemaGetComponentDesignation(&str, baseItem), 14175 NULL, NULL); 14176 FREE_AND_NULL(str); 14177 /* err = pctxt->err; */ 14178 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14179 WXS_ATTRUSE_TYPEDEF(cur), 14180 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14181 { 14182 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14183 14184 /* 14185 * SPEC (2.1.2) "R's {attribute declaration}'s 14186 * {type definition} must be validly derived from 14187 * B's {type definition} given the empty set as 14188 * defined in Type Derivation OK (Simple) ($3.14.6)." 14189 */ 14190 xmlSchemaPAttrUseErr4(pctxt, 14191 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14192 WXS_ITEM_NODE(item), item, cur, 14193 "The attribute declaration's %s " 14194 "is not validly derived from " 14195 "the corresponding %s of the " 14196 "attribute declaration in the %s %s", 14197 xmlSchemaGetComponentDesignation(&strA, 14198 WXS_ATTRUSE_TYPEDEF(cur)), 14199 xmlSchemaGetComponentDesignation(&strB, 14200 WXS_ATTRUSE_TYPEDEF(bcur)), 14201 WXS_ACTION_STR(action), 14202 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14203 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14204 FREE_AND_NULL(strA); 14205 FREE_AND_NULL(strB); 14206 FREE_AND_NULL(strC); 14207 /* err = pctxt->err; */ 14208 } else { 14209 /* 14210 * 2.1.3 [Definition:] Let the effective value 14211 * constraint of an attribute use be its {value 14212 * constraint}, if present, otherwise its {attribute 14213 * declaration}'s {value constraint} . 14214 */ 14215 xmlSchemaGetEffectiveValueConstraint(bcur, 14216 &effFixed, &bEffValue, NULL); 14217 /* 14218 * 2.1.3 ... one of the following must be true 14219 * 14220 * 2.1.3.1 B's `effective value constraint` is 14221 * `absent` or default. 14222 */ 14223 if ((bEffValue != NULL) && 14224 (effFixed == 1)) { 14225 const xmlChar *rEffValue = NULL; 14226 14227 xmlSchemaGetEffectiveValueConstraint(bcur, 14228 &effFixed, &rEffValue, NULL); 14229 /* 14230 * 2.1.3.2 R's `effective value constraint` is 14231 * fixed with the same string as B's. 14232 * MAYBE TODO: Compare the computed values. 14233 * Hmm, it says "same string" so 14234 * string-equality might really be sufficient. 14235 */ 14236 if ((effFixed == 0) || 14237 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14238 { 14239 xmlChar *str = NULL; 14240 14241 xmlSchemaPAttrUseErr4(pctxt, 14242 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14243 WXS_ITEM_NODE(item), item, cur, 14244 "The effective value constraint of the " 14245 "attribute use is inconsistent with " 14246 "its correspondent in the %s %s", 14247 WXS_ACTION_STR(action), 14248 xmlSchemaGetComponentDesignation(&str, 14249 baseItem), 14250 NULL, NULL); 14251 FREE_AND_NULL(str); 14252 /* err = pctxt->err; */ 14253 } 14254 } 14255 } 14256 break; 14257 } 14258 } 14259 not_found: 14260 if (!found) { 14261 /* 14262 * (2.2) "otherwise the {base type definition} must have an 14263 * {attribute wildcard} and the {target namespace} of the 14264 * R's {attribute declaration} must be `valid` with respect 14265 * to that wildcard, as defined in Wildcard allows Namespace 14266 * Name ($3.10.4)." 14267 */ 14268 if ((baseWild == NULL) || 14269 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14270 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14271 { 14272 xmlChar *str = NULL; 14273 14274 xmlSchemaPAttrUseErr4(pctxt, 14275 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14276 WXS_ITEM_NODE(item), item, cur, 14277 "Neither a matching attribute use, " 14278 "nor a matching wildcard exists in the %s %s", 14279 WXS_ACTION_STR(action), 14280 xmlSchemaGetComponentDesignation(&str, baseItem), 14281 NULL, NULL); 14282 FREE_AND_NULL(str); 14283 /* err = pctxt->err; */ 14284 } 14285 } 14286 } 14287 } 14288 /* 14289 * SPEC derivation-ok-restriction (3): 14290 * (3) "For each attribute use in the {attribute uses} of the {base type 14291 * definition} whose {required} is true, there must be an attribute 14292 * use with an {attribute declaration} with the same {name} and 14293 * {target namespace} as its {attribute declaration} in the {attribute 14294 * uses} of the complex type definition itself whose {required} is true. 14295 */ 14296 if (baseUses != NULL) { 14297 for (j = 0; j < baseUses->nbItems; j++) { 14298 bcur = baseUses->items[j]; 14299 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14300 continue; 14301 found = 0; 14302 if (uses != NULL) { 14303 for (i = 0; i < uses->nbItems; i++) { 14304 cur = uses->items[i]; 14305 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14306 WXS_ATTRUSE_DECL_NAME(bcur)) && 14307 (WXS_ATTRUSE_DECL_TNS(cur) == 14308 WXS_ATTRUSE_DECL_TNS(bcur))) { 14309 found = 1; 14310 break; 14311 } 14312 } 14313 } 14314 if (!found) { 14315 xmlChar *strA = NULL, *strB = NULL; 14316 14317 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14318 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14319 NULL, item, 14320 "A matching attribute use for the " 14321 "'required' %s of the %s %s is missing", 14322 xmlSchemaGetComponentDesignation(&strA, bcur), 14323 WXS_ACTION_STR(action), 14324 xmlSchemaGetComponentDesignation(&strB, baseItem), 14325 NULL); 14326 FREE_AND_NULL(strA); 14327 FREE_AND_NULL(strB); 14328 } 14329 } 14330 } 14331 /* 14332 * derivation-ok-restriction (4) 14333 */ 14334 if (wild != NULL) { 14335 /* 14336 * (4) "If there is an {attribute wildcard}, all of the 14337 * following must be true:" 14338 */ 14339 if (baseWild == NULL) { 14340 xmlChar *str = NULL; 14341 14342 /* 14343 * (4.1) "The {base type definition} must also have one." 14344 */ 14345 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14346 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14347 NULL, item, 14348 "The %s has an attribute wildcard, " 14349 "but the %s %s '%s' does not have one", 14350 WXS_ITEM_TYPE_NAME(item), 14351 WXS_ACTION_STR(action), 14352 WXS_ITEM_TYPE_NAME(baseItem), 14353 xmlSchemaGetComponentQName(&str, baseItem)); 14354 FREE_AND_NULL(str); 14355 return(pctxt->err); 14356 } else if ((baseWild->any == 0) && 14357 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14358 { 14359 xmlChar *str = NULL; 14360 /* 14361 * (4.2) "The complex type definition's {attribute wildcard}'s 14362 * {namespace constraint} must be a subset of the {base type 14363 * definition}'s {attribute wildcard}'s {namespace constraint}, 14364 * as defined by Wildcard Subset ($3.10.6)." 14365 */ 14366 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14367 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14368 NULL, item, 14369 "The attribute wildcard is not a valid " 14370 "subset of the wildcard in the %s %s '%s'", 14371 WXS_ACTION_STR(action), 14372 WXS_ITEM_TYPE_NAME(baseItem), 14373 xmlSchemaGetComponentQName(&str, baseItem), 14374 NULL); 14375 FREE_AND_NULL(str); 14376 return(pctxt->err); 14377 } 14378 /* 4.3 Unless the {base type definition} is the `ur-type 14379 * definition`, the complex type definition's {attribute 14380 * wildcard}'s {process contents} must be identical to or 14381 * stronger than the {base type definition}'s {attribute 14382 * wildcard}'s {process contents}, where strict is stronger 14383 * than lax is stronger than skip. 14384 */ 14385 if ((! WXS_IS_ANYTYPE(baseItem)) && 14386 (wild->processContents < baseWild->processContents)) { 14387 xmlChar *str = NULL; 14388 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14389 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14390 NULL, baseItem, 14391 "The {process contents} of the attribute wildcard is " 14392 "weaker than the one in the %s %s '%s'", 14393 WXS_ACTION_STR(action), 14394 WXS_ITEM_TYPE_NAME(baseItem), 14395 xmlSchemaGetComponentQName(&str, baseItem), 14396 NULL); 14397 FREE_AND_NULL(str) 14398 return(pctxt->err); 14399 } 14400 } 14401 return(0); 14402 } 14403 14404 14405 static int 14406 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14407 xmlSchemaBasicItemPtr item, 14408 xmlSchemaWildcardPtr *completeWild, 14409 xmlSchemaItemListPtr list, 14410 xmlSchemaItemListPtr prohibs); 14411 /** 14412 * xmlSchemaFixupTypeAttributeUses: 14413 * @ctxt: the schema parser context 14414 * @type: the complex type definition 14415 * 14416 * 14417 * Builds the wildcard and the attribute uses on the given complex type. 14418 * Returns -1 if an internal error occurs, 0 otherwise. 14419 * 14420 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14421 * strings, so recheck this if we start to hardcode some schemata, since 14422 * they might not be in the same dict. 14423 * NOTE: It is allowed to "extend" the xs:anyType type. 14424 */ 14425 static int 14426 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14427 xmlSchemaTypePtr type) 14428 { 14429 xmlSchemaTypePtr baseType = NULL; 14430 xmlSchemaAttributeUsePtr use; 14431 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14432 14433 if (type->baseType == NULL) { 14434 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14435 "no base type"); 14436 return (-1); 14437 } 14438 baseType = type->baseType; 14439 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14440 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14441 return(-1); 14442 14443 uses = type->attrUses; 14444 baseUses = baseType->attrUses; 14445 /* 14446 * Expand attribute group references. And build the 'complete' 14447 * wildcard, i.e. intersect multiple wildcards. 14448 * Move attribute prohibitions into a separate list. 14449 */ 14450 if (uses != NULL) { 14451 if (WXS_IS_RESTRICTION(type)) { 14452 /* 14453 * This one will transfer all attr. prohibitions 14454 * into pctxt->attrProhibs. 14455 */ 14456 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14457 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14458 pctxt->attrProhibs) == -1) 14459 { 14460 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14461 "failed to expand attributes"); 14462 } 14463 if (pctxt->attrProhibs->nbItems != 0) 14464 prohibs = pctxt->attrProhibs; 14465 } else { 14466 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14467 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14468 NULL) == -1) 14469 { 14470 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14471 "failed to expand attributes"); 14472 } 14473 } 14474 } 14475 /* 14476 * Inherit the attribute uses of the base type. 14477 */ 14478 if (baseUses != NULL) { 14479 int i, j; 14480 xmlSchemaAttributeUseProhibPtr pro; 14481 14482 if (WXS_IS_RESTRICTION(type)) { 14483 int usesCount; 14484 xmlSchemaAttributeUsePtr tmp; 14485 14486 if (uses != NULL) 14487 usesCount = uses->nbItems; 14488 else 14489 usesCount = 0; 14490 14491 /* Restriction. */ 14492 for (i = 0; i < baseUses->nbItems; i++) { 14493 use = baseUses->items[i]; 14494 if (prohibs) { 14495 /* 14496 * Filter out prohibited uses. 14497 */ 14498 for (j = 0; j < prohibs->nbItems; j++) { 14499 pro = prohibs->items[j]; 14500 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14501 (WXS_ATTRUSE_DECL_TNS(use) == 14502 pro->targetNamespace)) 14503 { 14504 goto inherit_next; 14505 } 14506 } 14507 } 14508 if (usesCount) { 14509 /* 14510 * Filter out existing uses. 14511 */ 14512 for (j = 0; j < usesCount; j++) { 14513 tmp = uses->items[j]; 14514 if ((WXS_ATTRUSE_DECL_NAME(use) == 14515 WXS_ATTRUSE_DECL_NAME(tmp)) && 14516 (WXS_ATTRUSE_DECL_TNS(use) == 14517 WXS_ATTRUSE_DECL_TNS(tmp))) 14518 { 14519 goto inherit_next; 14520 } 14521 } 14522 } 14523 if (uses == NULL) { 14524 type->attrUses = xmlSchemaItemListCreate(); 14525 if (type->attrUses == NULL) 14526 goto exit_failure; 14527 uses = type->attrUses; 14528 } 14529 xmlSchemaItemListAddSize(uses, 2, use); 14530 inherit_next: {} 14531 } 14532 } else { 14533 /* Extension. */ 14534 for (i = 0; i < baseUses->nbItems; i++) { 14535 use = baseUses->items[i]; 14536 if (uses == NULL) { 14537 type->attrUses = xmlSchemaItemListCreate(); 14538 if (type->attrUses == NULL) 14539 goto exit_failure; 14540 uses = type->attrUses; 14541 } 14542 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14543 } 14544 } 14545 } 14546 /* 14547 * Shrink attr. uses. 14548 */ 14549 if (uses) { 14550 if (uses->nbItems == 0) { 14551 xmlSchemaItemListFree(uses); 14552 type->attrUses = NULL; 14553 } 14554 /* 14555 * TODO: We could shrink the size of the array 14556 * to fit the actual number of items. 14557 */ 14558 } 14559 /* 14560 * Compute the complete wildcard. 14561 */ 14562 if (WXS_IS_EXTENSION(type)) { 14563 if (baseType->attributeWildcard != NULL) { 14564 /* 14565 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14566 * the appropriate case among the following:" 14567 */ 14568 if (type->attributeWildcard != NULL) { 14569 /* 14570 * Union the complete wildcard with the base wildcard. 14571 * SPEC {attribute wildcard} 14572 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14573 * and {annotation} are those of the `complete wildcard`, 14574 * and whose {namespace constraint} is the intensional union 14575 * of the {namespace constraint} of the `complete wildcard` 14576 * and of the `base wildcard`, as defined in Attribute 14577 * Wildcard Union ($3.10.6)." 14578 */ 14579 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14580 baseType->attributeWildcard) == -1) 14581 goto exit_failure; 14582 } else { 14583 /* 14584 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14585 * then the `base wildcard`." 14586 */ 14587 type->attributeWildcard = baseType->attributeWildcard; 14588 } 14589 } else { 14590 /* 14591 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14592 * `complete wildcard`" 14593 * NOOP 14594 */ 14595 } 14596 } else { 14597 /* 14598 * SPEC {attribute wildcard} 14599 * (3.1) "If the <restriction> alternative is chosen, then the 14600 * `complete wildcard`;" 14601 * NOOP 14602 */ 14603 } 14604 14605 return (0); 14606 14607 exit_failure: 14608 return(-1); 14609 } 14610 14611 /** 14612 * xmlSchemaTypeFinalContains: 14613 * @schema: the schema 14614 * @type: the type definition 14615 * @final: the final 14616 * 14617 * Evaluates if a type definition contains the given "final". 14618 * This does take "finalDefault" into account as well. 14619 * 14620 * Returns 1 if the type does containt the given "final", 14621 * 0 otherwise. 14622 */ 14623 static int 14624 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14625 { 14626 if (type == NULL) 14627 return (0); 14628 if (type->flags & final) 14629 return (1); 14630 else 14631 return (0); 14632 } 14633 14634 /** 14635 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14636 * @type: the Union Simple Type 14637 * 14638 * Returns a list of member types of @type if existing, 14639 * returns NULL otherwise. 14640 */ 14641 static xmlSchemaTypeLinkPtr 14642 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14643 { 14644 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14645 if (type->memberTypes != NULL) 14646 return (type->memberTypes); 14647 else 14648 type = type->baseType; 14649 } 14650 return (NULL); 14651 } 14652 14653 /** 14654 * xmlSchemaGetParticleTotalRangeMin: 14655 * @particle: the particle 14656 * 14657 * Schema Component Constraint: Effective Total Range 14658 * (all and sequence) + (choice) 14659 * 14660 * Returns the minimun Effective Total Range. 14661 */ 14662 static int 14663 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14664 { 14665 if ((particle->children == NULL) || 14666 (particle->minOccurs == 0)) 14667 return (0); 14668 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14669 int min = -1, cur; 14670 xmlSchemaParticlePtr part = 14671 (xmlSchemaParticlePtr) particle->children->children; 14672 14673 if (part == NULL) 14674 return (0); 14675 while (part != NULL) { 14676 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14677 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14678 cur = part->minOccurs; 14679 else 14680 cur = xmlSchemaGetParticleTotalRangeMin(part); 14681 if (cur == 0) 14682 return (0); 14683 if ((min > cur) || (min == -1)) 14684 min = cur; 14685 part = (xmlSchemaParticlePtr) part->next; 14686 } 14687 return (particle->minOccurs * min); 14688 } else { 14689 /* <all> and <sequence> */ 14690 int sum = 0; 14691 xmlSchemaParticlePtr part = 14692 (xmlSchemaParticlePtr) particle->children->children; 14693 14694 if (part == NULL) 14695 return (0); 14696 do { 14697 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14698 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14699 sum += part->minOccurs; 14700 else 14701 sum += xmlSchemaGetParticleTotalRangeMin(part); 14702 part = (xmlSchemaParticlePtr) part->next; 14703 } while (part != NULL); 14704 return (particle->minOccurs * sum); 14705 } 14706 } 14707 14708 #if 0 14709 /** 14710 * xmlSchemaGetParticleTotalRangeMax: 14711 * @particle: the particle 14712 * 14713 * Schema Component Constraint: Effective Total Range 14714 * (all and sequence) + (choice) 14715 * 14716 * Returns the maximum Effective Total Range. 14717 */ 14718 static int 14719 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14720 { 14721 if ((particle->children == NULL) || 14722 (particle->children->children == NULL)) 14723 return (0); 14724 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14725 int max = -1, cur; 14726 xmlSchemaParticlePtr part = 14727 (xmlSchemaParticlePtr) particle->children->children; 14728 14729 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14730 if (part->children == NULL) 14731 continue; 14732 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14733 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14734 cur = part->maxOccurs; 14735 else 14736 cur = xmlSchemaGetParticleTotalRangeMax(part); 14737 if (cur == UNBOUNDED) 14738 return (UNBOUNDED); 14739 if ((max < cur) || (max == -1)) 14740 max = cur; 14741 } 14742 /* TODO: Handle overflows? */ 14743 return (particle->maxOccurs * max); 14744 } else { 14745 /* <all> and <sequence> */ 14746 int sum = 0, cur; 14747 xmlSchemaParticlePtr part = 14748 (xmlSchemaParticlePtr) particle->children->children; 14749 14750 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14751 if (part->children == NULL) 14752 continue; 14753 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14754 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14755 cur = part->maxOccurs; 14756 else 14757 cur = xmlSchemaGetParticleTotalRangeMax(part); 14758 if (cur == UNBOUNDED) 14759 return (UNBOUNDED); 14760 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14761 return (UNBOUNDED); 14762 sum += cur; 14763 } 14764 /* TODO: Handle overflows? */ 14765 return (particle->maxOccurs * sum); 14766 } 14767 } 14768 #endif 14769 14770 /** 14771 * xmlSchemaIsParticleEmptiable: 14772 * @particle: the particle 14773 * 14774 * Schema Component Constraint: Particle Emptiable 14775 * Checks whether the given particle is emptiable. 14776 * 14777 * Returns 1 if emptiable, 0 otherwise. 14778 */ 14779 static int 14780 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14781 { 14782 /* 14783 * SPEC (1) "Its {min occurs} is 0." 14784 */ 14785 if ((particle == NULL) || (particle->minOccurs == 0) || 14786 (particle->children == NULL)) 14787 return (1); 14788 /* 14789 * SPEC (2) "Its {term} is a group and the minimum part of the 14790 * effective total range of that group, [...] is 0." 14791 */ 14792 if (WXS_IS_MODEL_GROUP(particle->children)) { 14793 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14794 return (1); 14795 } 14796 return (0); 14797 } 14798 14799 /** 14800 * xmlSchemaCheckCOSSTDerivedOK: 14801 * @actxt: a context 14802 * @type: the derived simple type definition 14803 * @baseType: the base type definition 14804 * @subset: the subset of ('restriction', ect.) 14805 * 14806 * Schema Component Constraint: 14807 * Type Derivation OK (Simple) (cos-st-derived-OK) 14808 * 14809 * Checks wheter @type can be validly 14810 * derived from @baseType. 14811 * 14812 * Returns 0 on success, an positive error code otherwise. 14813 */ 14814 static int 14815 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14816 xmlSchemaTypePtr type, 14817 xmlSchemaTypePtr baseType, 14818 int subset) 14819 { 14820 /* 14821 * 1 They are the same type definition. 14822 * TODO: The identy check might have to be more complex than this. 14823 */ 14824 if (type == baseType) 14825 return (0); 14826 /* 14827 * 2.1 restriction is not in the subset, or in the {final} 14828 * of its own {base type definition}; 14829 * 14830 * NOTE that this will be used also via "xsi:type". 14831 * 14832 * TODO: Revise this, it looks strange. How can the "type" 14833 * not be fixed or *in* fixing? 14834 */ 14835 if (WXS_IS_TYPE_NOT_FIXED(type)) 14836 if (xmlSchemaTypeFixup(type, actxt) == -1) 14837 return(-1); 14838 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14839 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14840 return(-1); 14841 if ((subset & SUBSET_RESTRICTION) || 14842 (xmlSchemaTypeFinalContains(type->baseType, 14843 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14844 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14845 } 14846 /* 2.2 */ 14847 if (type->baseType == baseType) { 14848 /* 14849 * 2.2.1 D's `base type definition` is B. 14850 */ 14851 return (0); 14852 } 14853 /* 14854 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14855 * and is validly derived from B given the subset, as defined by this 14856 * constraint. 14857 */ 14858 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14859 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14860 baseType, subset) == 0)) { 14861 return (0); 14862 } 14863 /* 14864 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14865 * definition`. 14866 */ 14867 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14868 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14869 return (0); 14870 } 14871 /* 14872 * 2.2.4 B's {variety} is union and D is validly derived from a type 14873 * definition in B's {member type definitions} given the subset, as 14874 * defined by this constraint. 14875 * 14876 * NOTE: This seems not to involve built-in types, since there is no 14877 * built-in Union Simple Type. 14878 */ 14879 if (WXS_IS_UNION(baseType)) { 14880 xmlSchemaTypeLinkPtr cur; 14881 14882 cur = baseType->memberTypes; 14883 while (cur != NULL) { 14884 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14885 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14886 return(-1); 14887 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14888 type, cur->type, subset) == 0) 14889 { 14890 /* 14891 * It just has to be validly derived from at least one 14892 * member-type. 14893 */ 14894 return (0); 14895 } 14896 cur = cur->next; 14897 } 14898 } 14899 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14900 } 14901 14902 /** 14903 * xmlSchemaCheckTypeDefCircularInternal: 14904 * @pctxt: the schema parser context 14905 * @ctxtType: the type definition 14906 * @ancestor: an ancestor of @ctxtType 14907 * 14908 * Checks st-props-correct (2) + ct-props-correct (3). 14909 * Circular type definitions are not allowed. 14910 * 14911 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14912 * circular, 0 otherwise. 14913 */ 14914 static int 14915 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14916 xmlSchemaTypePtr ctxtType, 14917 xmlSchemaTypePtr ancestor) 14918 { 14919 int ret; 14920 14921 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14922 return (0); 14923 14924 if (ctxtType == ancestor) { 14925 xmlSchemaPCustomErr(pctxt, 14926 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14927 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14928 "The definition is circular", NULL); 14929 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14930 } 14931 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14932 /* 14933 * Avoid inifinite recursion on circular types not yet checked. 14934 */ 14935 return (0); 14936 } 14937 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14938 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14939 ancestor->baseType); 14940 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14941 return (ret); 14942 } 14943 14944 /** 14945 * xmlSchemaCheckTypeDefCircular: 14946 * @item: the complex/simple type definition 14947 * @ctxt: the parser context 14948 * @name: the name 14949 * 14950 * Checks for circular type definitions. 14951 */ 14952 static void 14953 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14954 xmlSchemaParserCtxtPtr ctxt) 14955 { 14956 if ((item == NULL) || 14957 (item->type == XML_SCHEMA_TYPE_BASIC) || 14958 (item->baseType == NULL)) 14959 return; 14960 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14961 item->baseType); 14962 } 14963 14964 /* 14965 * Simple Type Definition Representation OK (src-simple-type) 4 14966 * 14967 * "4 Circular union type definition is disallowed. That is, if the 14968 * <union> alternative is chosen, there must not be any entries in the 14969 * memberTypes [attribute] at any depth which resolve to the component 14970 * corresponding to the <simpleType>." 14971 * 14972 * Note that this should work on the *representation* of a component, 14973 * thus assumes any union types in the member types not being yet 14974 * substituted. At this stage we need the variety of the types 14975 * to be already computed. 14976 */ 14977 static int 14978 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14979 xmlSchemaTypePtr ctxType, 14980 xmlSchemaTypeLinkPtr members) 14981 { 14982 xmlSchemaTypeLinkPtr member; 14983 xmlSchemaTypePtr memberType; 14984 14985 member = members; 14986 while (member != NULL) { 14987 memberType = member->type; 14988 while ((memberType != NULL) && 14989 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14990 if (memberType == ctxType) { 14991 xmlSchemaPCustomErr(pctxt, 14992 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14993 WXS_BASIC_CAST ctxType, NULL, 14994 "The union type definition is circular", NULL); 14995 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14996 } 14997 if ((WXS_IS_UNION(memberType)) && 14998 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14999 { 15000 int res; 15001 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 15002 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 15003 ctxType, 15004 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 15005 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 15006 if (res != 0) 15007 return(res); 15008 } 15009 memberType = memberType->baseType; 15010 } 15011 member = member->next; 15012 } 15013 return(0); 15014 } 15015 15016 static int 15017 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15018 xmlSchemaTypePtr type) 15019 { 15020 if (! WXS_IS_UNION(type)) 15021 return(0); 15022 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15023 type->memberTypes)); 15024 } 15025 15026 /** 15027 * xmlSchemaResolveTypeReferences: 15028 * @item: the complex/simple type definition 15029 * @ctxt: the parser context 15030 * @name: the name 15031 * 15032 * Resolvese type definition references 15033 */ 15034 static void 15035 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15036 xmlSchemaParserCtxtPtr ctxt) 15037 { 15038 if (typeDef == NULL) 15039 return; 15040 15041 /* 15042 * Resolve the base type. 15043 */ 15044 if (typeDef->baseType == NULL) { 15045 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15046 typeDef->base, typeDef->baseNs); 15047 if (typeDef->baseType == NULL) { 15048 xmlSchemaPResCompAttrErr(ctxt, 15049 XML_SCHEMAP_SRC_RESOLVE, 15050 WXS_BASIC_CAST typeDef, typeDef->node, 15051 "base", typeDef->base, typeDef->baseNs, 15052 XML_SCHEMA_TYPE_SIMPLE, NULL); 15053 return; 15054 } 15055 } 15056 if (WXS_IS_SIMPLE(typeDef)) { 15057 if (WXS_IS_UNION(typeDef)) { 15058 /* 15059 * Resolve the memberTypes. 15060 */ 15061 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15062 return; 15063 } else if (WXS_IS_LIST(typeDef)) { 15064 /* 15065 * Resolve the itemType. 15066 */ 15067 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15068 15069 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15070 typeDef->base, typeDef->baseNs); 15071 15072 if ((typeDef->subtypes == NULL) || 15073 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15074 { 15075 typeDef->subtypes = NULL; 15076 xmlSchemaPResCompAttrErr(ctxt, 15077 XML_SCHEMAP_SRC_RESOLVE, 15078 WXS_BASIC_CAST typeDef, typeDef->node, 15079 "itemType", typeDef->base, typeDef->baseNs, 15080 XML_SCHEMA_TYPE_SIMPLE, NULL); 15081 } 15082 } 15083 return; 15084 } 15085 } 15086 /* 15087 * The ball of letters below means, that if we have a particle 15088 * which has a QName-helper component as its {term}, we want 15089 * to resolve it... 15090 */ 15091 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15092 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15093 XML_SCHEMA_TYPE_PARTICLE) && 15094 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15095 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15096 XML_SCHEMA_EXTRA_QNAMEREF)) 15097 { 15098 xmlSchemaQNameRefPtr ref = 15099 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15100 xmlSchemaModelGroupDefPtr groupDef; 15101 15102 /* 15103 * URGENT TODO: Test this. 15104 */ 15105 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15106 /* 15107 * Resolve the MG definition reference. 15108 */ 15109 groupDef = 15110 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15111 ref->itemType, ref->name, ref->targetNamespace); 15112 if (groupDef == NULL) { 15113 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15114 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15115 "ref", ref->name, ref->targetNamespace, ref->itemType, 15116 NULL); 15117 /* Remove the particle. */ 15118 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15119 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15120 /* Remove the particle. */ 15121 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15122 else { 15123 /* 15124 * Assign the MG definition's {model group} to the 15125 * particle's {term}. 15126 */ 15127 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15128 15129 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15130 /* 15131 * SPEC cos-all-limited (1.2) 15132 * "1.2 the {term} property of a particle with 15133 * {max occurs}=1 which is part of a pair which constitutes 15134 * the {content type} of a complex type definition." 15135 */ 15136 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15137 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15138 /* TODO: error code */ 15139 XML_SCHEMAP_COS_ALL_LIMITED, 15140 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15141 "The particle's {max occurs} must be 1, since the " 15142 "reference resolves to an 'all' model group", 15143 NULL, NULL); 15144 } 15145 } 15146 } 15147 } 15148 } 15149 15150 15151 15152 /** 15153 * xmlSchemaCheckSTPropsCorrect: 15154 * @ctxt: the schema parser context 15155 * @type: the simple type definition 15156 * 15157 * Checks st-props-correct. 15158 * 15159 * Returns 0 if the properties are correct, 15160 * if not, a positive error code and -1 on internal 15161 * errors. 15162 */ 15163 static int 15164 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15165 xmlSchemaTypePtr type) 15166 { 15167 xmlSchemaTypePtr baseType = type->baseType; 15168 xmlChar *str = NULL; 15169 15170 /* STATE: error funcs converted. */ 15171 /* 15172 * Schema Component Constraint: Simple Type Definition Properties Correct 15173 * 15174 * NOTE: This is somehow redundant, since we actually built a simple type 15175 * to have all the needed information; this acts as an self test. 15176 */ 15177 /* Base type: If the datatype has been `derived` by `restriction` 15178 * then the Simple Type Definition component from which it is `derived`, 15179 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15180 */ 15181 if (baseType == NULL) { 15182 /* 15183 * TODO: Think about: "modulo the impact of Missing 15184 * Sub-components ($5.3)." 15185 */ 15186 xmlSchemaPCustomErr(ctxt, 15187 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15188 WXS_BASIC_CAST type, NULL, 15189 "No base type existent", NULL); 15190 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15191 15192 } 15193 if (! WXS_IS_SIMPLE(baseType)) { 15194 xmlSchemaPCustomErr(ctxt, 15195 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15196 WXS_BASIC_CAST type, NULL, 15197 "The base type '%s' is not a simple type", 15198 xmlSchemaGetComponentQName(&str, baseType)); 15199 FREE_AND_NULL(str) 15200 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15201 } 15202 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15203 (WXS_IS_RESTRICTION(type) == 0) && 15204 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15205 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15206 xmlSchemaPCustomErr(ctxt, 15207 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15208 WXS_BASIC_CAST type, NULL, 15209 "A type, derived by list or union, must have " 15210 "the simple ur-type definition as base type, not '%s'", 15211 xmlSchemaGetComponentQName(&str, baseType)); 15212 FREE_AND_NULL(str) 15213 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15214 } 15215 /* 15216 * Variety: One of {atomic, list, union}. 15217 */ 15218 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15219 (! WXS_IS_LIST(type))) { 15220 xmlSchemaPCustomErr(ctxt, 15221 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15222 WXS_BASIC_CAST type, NULL, 15223 "The variety is absent", NULL); 15224 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15225 } 15226 /* TODO: Finish this. Hmm, is this finished? */ 15227 15228 /* 15229 * 3 The {final} of the {base type definition} must not contain restriction. 15230 */ 15231 if (xmlSchemaTypeFinalContains(baseType, 15232 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15233 xmlSchemaPCustomErr(ctxt, 15234 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15235 WXS_BASIC_CAST type, NULL, 15236 "The 'final' of its base type '%s' must not contain " 15237 "'restriction'", 15238 xmlSchemaGetComponentQName(&str, baseType)); 15239 FREE_AND_NULL(str) 15240 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15241 } 15242 15243 /* 15244 * 2 All simple type definitions must be derived ultimately from the `simple 15245 * ur-type definition` (so circular definitions are disallowed). That is, it 15246 * must be possible to reach a built-in primitive datatype or the `simple 15247 * ur-type definition` by repeatedly following the {base type definition}. 15248 * 15249 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15250 */ 15251 return (0); 15252 } 15253 15254 /** 15255 * xmlSchemaCheckCOSSTRestricts: 15256 * @ctxt: the schema parser context 15257 * @type: the simple type definition 15258 * 15259 * Schema Component Constraint: 15260 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15261 15262 * Checks if the given @type (simpleType) is derived validly by restriction. 15263 * STATUS: 15264 * 15265 * Returns -1 on internal errors, 0 if the type is validly derived, 15266 * a positive error code otherwise. 15267 */ 15268 static int 15269 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15270 xmlSchemaTypePtr type) 15271 { 15272 xmlChar *str = NULL; 15273 15274 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15275 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15276 "given type is not a user-derived simpleType"); 15277 return (-1); 15278 } 15279 15280 if (WXS_IS_ATOMIC(type)) { 15281 xmlSchemaTypePtr primitive; 15282 /* 15283 * 1.1 The {base type definition} must be an atomic simple 15284 * type definition or a built-in primitive datatype. 15285 */ 15286 if (! WXS_IS_ATOMIC(type->baseType)) { 15287 xmlSchemaPCustomErr(pctxt, 15288 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15289 WXS_BASIC_CAST type, NULL, 15290 "The base type '%s' is not an atomic simple type", 15291 xmlSchemaGetComponentQName(&str, type->baseType)); 15292 FREE_AND_NULL(str) 15293 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15294 } 15295 /* 1.2 The {final} of the {base type definition} must not contain 15296 * restriction. 15297 */ 15298 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15299 if (xmlSchemaTypeFinalContains(type->baseType, 15300 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15301 xmlSchemaPCustomErr(pctxt, 15302 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15303 WXS_BASIC_CAST type, NULL, 15304 "The final of its base type '%s' must not contain 'restriction'", 15305 xmlSchemaGetComponentQName(&str, type->baseType)); 15306 FREE_AND_NULL(str) 15307 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15308 } 15309 15310 /* 15311 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15312 * type definition}, as specified in the appropriate subsection of 3.2 15313 * Primitive datatypes. 15314 */ 15315 if (type->facets != NULL) { 15316 xmlSchemaFacetPtr facet; 15317 int ok = 1; 15318 15319 primitive = xmlSchemaGetPrimitiveType(type); 15320 if (primitive == NULL) { 15321 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15322 "failed to get primitive type"); 15323 return (-1); 15324 } 15325 facet = type->facets; 15326 do { 15327 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15328 ok = 0; 15329 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15330 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15331 type, primitive, facet); 15332 } 15333 facet = facet->next; 15334 } while (facet != NULL); 15335 if (ok == 0) 15336 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15337 } 15338 /* 15339 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15340 * of the {base type definition} (call this BF),then the DF's {value} 15341 * must be a valid restriction of BF's {value} as defined in 15342 * [XML Schemas: Datatypes]." 15343 * 15344 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15345 * xmlSchemaDeriveAndValidateFacets() 15346 */ 15347 } else if (WXS_IS_LIST(type)) { 15348 xmlSchemaTypePtr itemType = NULL; 15349 15350 itemType = type->subtypes; 15351 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15352 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15353 "failed to evaluate the item type"); 15354 return (-1); 15355 } 15356 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15357 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15358 /* 15359 * 2.1 The {item type definition} must have a {variety} of atomic or 15360 * union (in which case all the {member type definitions} 15361 * must be atomic). 15362 */ 15363 if ((! WXS_IS_ATOMIC(itemType)) && 15364 (! WXS_IS_UNION(itemType))) { 15365 xmlSchemaPCustomErr(pctxt, 15366 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15367 WXS_BASIC_CAST type, NULL, 15368 "The item type '%s' does not have a variety of atomic or union", 15369 xmlSchemaGetComponentQName(&str, itemType)); 15370 FREE_AND_NULL(str) 15371 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15372 } else if (WXS_IS_UNION(itemType)) { 15373 xmlSchemaTypeLinkPtr member; 15374 15375 member = itemType->memberTypes; 15376 while (member != NULL) { 15377 if (! WXS_IS_ATOMIC(member->type)) { 15378 xmlSchemaPCustomErr(pctxt, 15379 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15380 WXS_BASIC_CAST type, NULL, 15381 "The item type is a union type, but the " 15382 "member type '%s' of this item type is not atomic", 15383 xmlSchemaGetComponentQName(&str, member->type)); 15384 FREE_AND_NULL(str) 15385 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15386 } 15387 member = member->next; 15388 } 15389 } 15390 15391 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15392 xmlSchemaFacetPtr facet; 15393 /* 15394 * This is the case if we have: <simpleType><list .. 15395 */ 15396 /* 15397 * 2.3.1 15398 * 2.3.1.1 The {final} of the {item type definition} must not 15399 * contain list. 15400 */ 15401 if (xmlSchemaTypeFinalContains(itemType, 15402 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15403 xmlSchemaPCustomErr(pctxt, 15404 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15405 WXS_BASIC_CAST type, NULL, 15406 "The final of its item type '%s' must not contain 'list'", 15407 xmlSchemaGetComponentQName(&str, itemType)); 15408 FREE_AND_NULL(str) 15409 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15410 } 15411 /* 15412 * 2.3.1.2 The {facets} must only contain the whiteSpace 15413 * facet component. 15414 * OPTIMIZE TODO: the S4S already disallows any facet 15415 * to be specified. 15416 */ 15417 if (type->facets != NULL) { 15418 facet = type->facets; 15419 do { 15420 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15421 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15422 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15423 type, facet); 15424 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15425 } 15426 facet = facet->next; 15427 } while (facet != NULL); 15428 } 15429 /* 15430 * MAYBE TODO: (Hmm, not really) Datatypes states: 15431 * A `list` datatype can be `derived` from an `atomic` datatype 15432 * whose `lexical space` allows space (such as string or anyURI)or 15433 * a `union` datatype any of whose {member type definitions}'s 15434 * `lexical space` allows space. 15435 */ 15436 } else { 15437 /* 15438 * This is the case if we have: <simpleType><restriction ... 15439 * I.e. the variety of "list" is inherited. 15440 */ 15441 /* 15442 * 2.3.2 15443 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15444 */ 15445 if (! WXS_IS_LIST(type->baseType)) { 15446 xmlSchemaPCustomErr(pctxt, 15447 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15448 WXS_BASIC_CAST type, NULL, 15449 "The base type '%s' must be a list type", 15450 xmlSchemaGetComponentQName(&str, type->baseType)); 15451 FREE_AND_NULL(str) 15452 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15453 } 15454 /* 15455 * 2.3.2.2 The {final} of the {base type definition} must not 15456 * contain restriction. 15457 */ 15458 if (xmlSchemaTypeFinalContains(type->baseType, 15459 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15460 xmlSchemaPCustomErr(pctxt, 15461 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15462 WXS_BASIC_CAST type, NULL, 15463 "The 'final' of the base type '%s' must not contain 'restriction'", 15464 xmlSchemaGetComponentQName(&str, type->baseType)); 15465 FREE_AND_NULL(str) 15466 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15467 } 15468 /* 15469 * 2.3.2.3 The {item type definition} must be validly derived 15470 * from the {base type definition}'s {item type definition} given 15471 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15472 */ 15473 { 15474 xmlSchemaTypePtr baseItemType; 15475 15476 baseItemType = type->baseType->subtypes; 15477 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15478 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15479 "failed to eval the item type of a base type"); 15480 return (-1); 15481 } 15482 if ((itemType != baseItemType) && 15483 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15484 baseItemType, 0) != 0)) { 15485 xmlChar *strBIT = NULL, *strBT = NULL; 15486 xmlSchemaPCustomErrExt(pctxt, 15487 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15488 WXS_BASIC_CAST type, NULL, 15489 "The item type '%s' is not validly derived from " 15490 "the item type '%s' of the base type '%s'", 15491 xmlSchemaGetComponentQName(&str, itemType), 15492 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15493 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15494 15495 FREE_AND_NULL(str) 15496 FREE_AND_NULL(strBIT) 15497 FREE_AND_NULL(strBT) 15498 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15499 } 15500 } 15501 15502 if (type->facets != NULL) { 15503 xmlSchemaFacetPtr facet; 15504 int ok = 1; 15505 /* 15506 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15507 * and enumeration facet components are allowed among the {facets}. 15508 */ 15509 facet = type->facets; 15510 do { 15511 switch (facet->type) { 15512 case XML_SCHEMA_FACET_LENGTH: 15513 case XML_SCHEMA_FACET_MINLENGTH: 15514 case XML_SCHEMA_FACET_MAXLENGTH: 15515 case XML_SCHEMA_FACET_WHITESPACE: 15516 /* 15517 * TODO: 2.5.1.2 List datatypes 15518 * The value of `whiteSpace` is fixed to the value collapse. 15519 */ 15520 case XML_SCHEMA_FACET_PATTERN: 15521 case XML_SCHEMA_FACET_ENUMERATION: 15522 break; 15523 default: { 15524 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15525 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15526 type, facet); 15527 /* 15528 * We could return, but it's nicer to report all 15529 * invalid facets. 15530 */ 15531 ok = 0; 15532 } 15533 } 15534 facet = facet->next; 15535 } while (facet != NULL); 15536 if (ok == 0) 15537 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15538 /* 15539 * SPEC (2.3.2.5) (same as 1.3.2) 15540 * 15541 * NOTE (2.3.2.5) This is currently done in 15542 * xmlSchemaDeriveAndValidateFacets() 15543 */ 15544 } 15545 } 15546 } else if (WXS_IS_UNION(type)) { 15547 /* 15548 * 3.1 The {member type definitions} must all have {variety} of 15549 * atomic or list. 15550 */ 15551 xmlSchemaTypeLinkPtr member; 15552 15553 member = type->memberTypes; 15554 while (member != NULL) { 15555 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15556 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15557 15558 if ((! WXS_IS_ATOMIC(member->type)) && 15559 (! WXS_IS_LIST(member->type))) { 15560 xmlSchemaPCustomErr(pctxt, 15561 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15562 WXS_BASIC_CAST type, NULL, 15563 "The member type '%s' is neither an atomic, nor a list type", 15564 xmlSchemaGetComponentQName(&str, member->type)); 15565 FREE_AND_NULL(str) 15566 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15567 } 15568 member = member->next; 15569 } 15570 /* 15571 * 3.3.1 If the {base type definition} is the `simple ur-type 15572 * definition` 15573 */ 15574 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15575 /* 15576 * 3.3.1.1 All of the {member type definitions} must have a 15577 * {final} which does not contain union. 15578 */ 15579 member = type->memberTypes; 15580 while (member != NULL) { 15581 if (xmlSchemaTypeFinalContains(member->type, 15582 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15583 xmlSchemaPCustomErr(pctxt, 15584 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15585 WXS_BASIC_CAST type, NULL, 15586 "The 'final' of member type '%s' contains 'union'", 15587 xmlSchemaGetComponentQName(&str, member->type)); 15588 FREE_AND_NULL(str) 15589 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15590 } 15591 member = member->next; 15592 } 15593 /* 15594 * 3.3.1.2 The {facets} must be empty. 15595 */ 15596 if (type->facetSet != NULL) { 15597 xmlSchemaPCustomErr(pctxt, 15598 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15599 WXS_BASIC_CAST type, NULL, 15600 "No facets allowed", NULL); 15601 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15602 } 15603 } else { 15604 /* 15605 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15606 * I.e. the variety of "list" is inherited. 15607 */ 15608 if (! WXS_IS_UNION(type->baseType)) { 15609 xmlSchemaPCustomErr(pctxt, 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15611 WXS_BASIC_CAST type, NULL, 15612 "The base type '%s' is not a union type", 15613 xmlSchemaGetComponentQName(&str, type->baseType)); 15614 FREE_AND_NULL(str) 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15616 } 15617 /* 15618 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15619 */ 15620 if (xmlSchemaTypeFinalContains(type->baseType, 15621 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15622 xmlSchemaPCustomErr(pctxt, 15623 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15624 WXS_BASIC_CAST type, NULL, 15625 "The 'final' of its base type '%s' must not contain 'restriction'", 15626 xmlSchemaGetComponentQName(&str, type->baseType)); 15627 FREE_AND_NULL(str) 15628 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15629 } 15630 /* 15631 * 3.3.2.3 The {member type definitions}, in order, must be validly 15632 * derived from the corresponding type definitions in the {base 15633 * type definition}'s {member type definitions} given the empty set, 15634 * as defined in Type Derivation OK (Simple) ($3.14.6). 15635 */ 15636 { 15637 xmlSchemaTypeLinkPtr baseMember; 15638 15639 /* 15640 * OPTIMIZE: if the type is restricting, it has no local defined 15641 * member types and inherits the member types of the base type; 15642 * thus a check for equality can be skipped. 15643 */ 15644 /* 15645 * Even worse: I cannot see a scenario where a restricting 15646 * union simple type can have other member types as the member 15647 * types of it's base type. This check seems not necessary with 15648 * respect to the derivation process in libxml2. 15649 * But necessary if constructing types with an API. 15650 */ 15651 if (type->memberTypes != NULL) { 15652 member = type->memberTypes; 15653 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15654 if ((member == NULL) && (baseMember != NULL)) { 15655 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15656 "different number of member types in base"); 15657 } 15658 while (member != NULL) { 15659 if (baseMember == NULL) { 15660 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15661 "different number of member types in base"); 15662 } else if ((member->type != baseMember->type) && 15663 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15664 member->type, baseMember->type, 0) != 0)) { 15665 xmlChar *strBMT = NULL, *strBT = NULL; 15666 15667 xmlSchemaPCustomErrExt(pctxt, 15668 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15669 WXS_BASIC_CAST type, NULL, 15670 "The member type %s is not validly " 15671 "derived from its corresponding member " 15672 "type %s of the base type %s", 15673 xmlSchemaGetComponentQName(&str, member->type), 15674 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15675 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15676 FREE_AND_NULL(str) 15677 FREE_AND_NULL(strBMT) 15678 FREE_AND_NULL(strBT) 15679 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15680 } 15681 member = member->next; 15682 if (baseMember != NULL) 15683 baseMember = baseMember->next; 15684 } 15685 } 15686 } 15687 /* 15688 * 3.3.2.4 Only pattern and enumeration facet components are 15689 * allowed among the {facets}. 15690 */ 15691 if (type->facets != NULL) { 15692 xmlSchemaFacetPtr facet; 15693 int ok = 1; 15694 15695 facet = type->facets; 15696 do { 15697 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15698 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15699 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15700 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15701 type, facet); 15702 ok = 0; 15703 } 15704 facet = facet->next; 15705 } while (facet != NULL); 15706 if (ok == 0) 15707 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15708 15709 } 15710 /* 15711 * SPEC (3.3.2.5) (same as 1.3.2) 15712 * 15713 * NOTE (3.3.2.5) This is currently done in 15714 * xmlSchemaDeriveAndValidateFacets() 15715 */ 15716 } 15717 } 15718 15719 return (0); 15720 } 15721 15722 /** 15723 * xmlSchemaCheckSRCSimpleType: 15724 * @ctxt: the schema parser context 15725 * @type: the simple type definition 15726 * 15727 * Checks crc-simple-type constraints. 15728 * 15729 * Returns 0 if the constraints are satisfied, 15730 * if not a positive error code and -1 on internal 15731 * errors. 15732 */ 15733 #if 0 15734 static int 15735 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15736 xmlSchemaTypePtr type) 15737 { 15738 /* 15739 * src-simple-type.1 The corresponding simple type definition, if any, 15740 * must satisfy the conditions set out in Constraints on Simple Type 15741 * Definition Schema Components ($3.14.6). 15742 */ 15743 if (WXS_IS_RESTRICTION(type)) { 15744 /* 15745 * src-simple-type.2 "If the <restriction> alternative is chosen, 15746 * either it must have a base [attribute] or a <simpleType> among its 15747 * [children], but not both." 15748 * NOTE: This is checked in the parse function of <restriction>. 15749 */ 15750 /* 15751 * 15752 */ 15753 } else if (WXS_IS_LIST(type)) { 15754 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15755 * an itemType [attribute] or a <simpleType> among its [children], 15756 * but not both." 15757 * 15758 * NOTE: This is checked in the parse function of <list>. 15759 */ 15760 } else if (WXS_IS_UNION(type)) { 15761 /* 15762 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15763 */ 15764 } 15765 return (0); 15766 } 15767 #endif 15768 15769 static int 15770 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15771 { 15772 if (ctxt->vctxt == NULL) { 15773 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15774 if (ctxt->vctxt == NULL) { 15775 xmlSchemaPErr(ctxt, NULL, 15776 XML_SCHEMAP_INTERNAL, 15777 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15778 "failed to create a temp. validation context.\n", 15779 NULL, NULL); 15780 return (-1); 15781 } 15782 /* TODO: Pass user data. */ 15783 xmlSchemaSetValidErrors(ctxt->vctxt, 15784 ctxt->error, ctxt->warning, ctxt->errCtxt); 15785 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15786 ctxt->serror, ctxt->errCtxt); 15787 } 15788 return (0); 15789 } 15790 15791 static int 15792 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15793 xmlNodePtr node, 15794 xmlSchemaTypePtr type, 15795 const xmlChar *value, 15796 xmlSchemaValPtr *retVal, 15797 int fireErrors, 15798 int normalize, 15799 int isNormalized); 15800 15801 /** 15802 * xmlSchemaParseCheckCOSValidDefault: 15803 * @pctxt: the schema parser context 15804 * @type: the simple type definition 15805 * @value: the default value 15806 * @node: an optional node (the holder of the value) 15807 * 15808 * Schema Component Constraint: Element Default Valid (Immediate) 15809 * (cos-valid-default) 15810 * This will be used by the parser only. For the validator there's 15811 * an other version. 15812 * 15813 * Returns 0 if the constraints are satisfied, 15814 * if not, a positive error code and -1 on internal 15815 * errors. 15816 */ 15817 static int 15818 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15819 xmlNodePtr node, 15820 xmlSchemaTypePtr type, 15821 const xmlChar *value, 15822 xmlSchemaValPtr *val) 15823 { 15824 int ret = 0; 15825 15826 /* 15827 * cos-valid-default: 15828 * Schema Component Constraint: Element Default Valid (Immediate) 15829 * For a string to be a valid default with respect to a type 15830 * definition the appropriate case among the following must be true: 15831 */ 15832 if WXS_IS_COMPLEX(type) { 15833 /* 15834 * Complex type. 15835 * 15836 * SPEC (2.1) "its {content type} must be a simple type definition 15837 * or mixed." 15838 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15839 * type}'s particle must be `emptiable` as defined by 15840 * Particle Emptiable ($3.9.6)." 15841 */ 15842 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15843 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15844 /* NOTE that this covers (2.2.2) as well. */ 15845 xmlSchemaPCustomErr(pctxt, 15846 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15847 WXS_BASIC_CAST type, type->node, 15848 "For a string to be a valid default, the type definition " 15849 "must be a simple type or a complex type with mixed content " 15850 "and a particle emptiable", NULL); 15851 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15852 } 15853 } 15854 /* 15855 * 1 If the type definition is a simple type definition, then the string 15856 * must be `valid` with respect to that definition as defined by String 15857 * Valid ($3.14.4). 15858 * 15859 * AND 15860 * 15861 * 2.2.1 If the {content type} is a simple type definition, then the 15862 * string must be `valid` with respect to that simple type definition 15863 * as defined by String Valid ($3.14.4). 15864 */ 15865 if (WXS_IS_SIMPLE(type)) 15866 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15867 type, value, val, 1, 1, 0); 15868 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15869 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15870 type->contentTypeDef, value, val, 1, 1, 0); 15871 else 15872 return (ret); 15873 15874 if (ret < 0) { 15875 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15876 "calling xmlSchemaVCheckCVCSimpleType()"); 15877 } 15878 15879 return (ret); 15880 } 15881 15882 /** 15883 * xmlSchemaCheckCTPropsCorrect: 15884 * @ctxt: the schema parser context 15885 * @type: the complex type definition 15886 * 15887 *.(4.6) Constraints on Complex Type Definition Schema Components 15888 * Schema Component Constraint: 15889 * Complex Type Definition Properties Correct (ct-props-correct) 15890 * STATUS: (seems) complete 15891 * 15892 * Returns 0 if the constraints are satisfied, a positive 15893 * error code if not and -1 if an internal error occured. 15894 */ 15895 static int 15896 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15897 xmlSchemaTypePtr type) 15898 { 15899 /* 15900 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15901 * 15902 * SPEC (1) "The values of the properties of a complex type definition must 15903 * be as described in the property tableau in The Complex Type Definition 15904 * Schema Component ($3.4.1), modulo the impact of Missing 15905 * Sub-components ($5.3)." 15906 */ 15907 if ((type->baseType != NULL) && 15908 (WXS_IS_SIMPLE(type->baseType)) && 15909 (WXS_IS_EXTENSION(type) == 0)) { 15910 /* 15911 * SPEC (2) "If the {base type definition} is a simple type definition, 15912 * the {derivation method} must be extension." 15913 */ 15914 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15915 XML_SCHEMAP_SRC_CT_1, 15916 NULL, WXS_BASIC_CAST type, 15917 "If the base type is a simple type, the derivation method must be " 15918 "'extension'", NULL, NULL); 15919 return (XML_SCHEMAP_SRC_CT_1); 15920 } 15921 /* 15922 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15923 * definition`. That is, it must be possible to reach the `ur-type 15924 * definition` by repeatedly following the {base type definition}." 15925 * 15926 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15927 */ 15928 /* 15929 * NOTE that (4) and (5) need the following: 15930 * - attribute uses need to be already inherited (apply attr. prohibitions) 15931 * - attribute group references need to be expanded already 15932 * - simple types need to be typefixed already 15933 */ 15934 if (type->attrUses && 15935 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15936 { 15937 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15938 xmlSchemaAttributeUsePtr use, tmp; 15939 int i, j, hasId = 0; 15940 15941 for (i = uses->nbItems -1; i >= 0; i--) { 15942 use = uses->items[i]; 15943 15944 /* 15945 * SPEC ct-props-correct 15946 * (4) "Two distinct attribute declarations in the 15947 * {attribute uses} must not have identical {name}s and 15948 * {target namespace}s." 15949 */ 15950 if (i > 0) { 15951 for (j = i -1; j >= 0; j--) { 15952 tmp = uses->items[j]; 15953 if ((WXS_ATTRUSE_DECL_NAME(use) == 15954 WXS_ATTRUSE_DECL_NAME(tmp)) && 15955 (WXS_ATTRUSE_DECL_TNS(use) == 15956 WXS_ATTRUSE_DECL_TNS(tmp))) 15957 { 15958 xmlChar *str = NULL; 15959 15960 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15961 XML_SCHEMAP_AG_PROPS_CORRECT, 15962 NULL, WXS_BASIC_CAST type, 15963 "Duplicate %s", 15964 xmlSchemaGetComponentDesignation(&str, use), 15965 NULL); 15966 FREE_AND_NULL(str); 15967 /* 15968 * Remove the duplicate. 15969 */ 15970 if (xmlSchemaItemListRemove(uses, i) == -1) 15971 goto exit_failure; 15972 goto next_use; 15973 } 15974 } 15975 } 15976 /* 15977 * SPEC ct-props-correct 15978 * (5) "Two distinct attribute declarations in the 15979 * {attribute uses} must not have {type definition}s which 15980 * are or are derived from ID." 15981 */ 15982 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15983 if (xmlSchemaIsDerivedFromBuiltInType( 15984 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15985 { 15986 if (hasId) { 15987 xmlChar *str = NULL; 15988 15989 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15990 XML_SCHEMAP_AG_PROPS_CORRECT, 15991 NULL, WXS_BASIC_CAST type, 15992 "There must not exist more than one attribute " 15993 "declaration of type 'xs:ID' " 15994 "(or derived from 'xs:ID'). The %s violates this " 15995 "constraint", 15996 xmlSchemaGetComponentDesignation(&str, use), 15997 NULL); 15998 FREE_AND_NULL(str); 15999 if (xmlSchemaItemListRemove(uses, i) == -1) 16000 goto exit_failure; 16001 } 16002 16003 hasId = 1; 16004 } 16005 } 16006 next_use: {} 16007 } 16008 } 16009 return (0); 16010 exit_failure: 16011 return(-1); 16012 } 16013 16014 static int 16015 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16016 xmlSchemaTypePtr typeB) 16017 { 16018 /* 16019 * TODO: This should implement component-identity 16020 * in the future. 16021 */ 16022 if ((typeA == NULL) || (typeB == NULL)) 16023 return (0); 16024 return (typeA == typeB); 16025 } 16026 16027 /** 16028 * xmlSchemaCheckCOSCTDerivedOK: 16029 * @ctxt: the schema parser context 16030 * @type: the to-be derived complex type definition 16031 * @baseType: the base complex type definition 16032 * @set: the given set 16033 * 16034 * Schema Component Constraint: 16035 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16036 * 16037 * STATUS: completed 16038 * 16039 * Returns 0 if the constraints are satisfied, or 1 16040 * if not. 16041 */ 16042 static int 16043 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16044 xmlSchemaTypePtr type, 16045 xmlSchemaTypePtr baseType, 16046 int set) 16047 { 16048 int equal = xmlSchemaAreEqualTypes(type, baseType); 16049 /* TODO: Error codes. */ 16050 /* 16051 * SPEC "For a complex type definition (call it D, for derived) 16052 * to be validly derived from a type definition (call this 16053 * B, for base) given a subset of {extension, restriction} 16054 * all of the following must be true:" 16055 */ 16056 if (! equal) { 16057 /* 16058 * SPEC (1) "If B and D are not the same type definition, then the 16059 * {derivation method} of D must not be in the subset." 16060 */ 16061 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16062 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16063 return (1); 16064 } else { 16065 /* 16066 * SPEC (2.1) "B and D must be the same type definition." 16067 */ 16068 return (0); 16069 } 16070 /* 16071 * SPEC (2.2) "B must be D's {base type definition}." 16072 */ 16073 if (type->baseType == baseType) 16074 return (0); 16075 /* 16076 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16077 * definition`." 16078 */ 16079 if (WXS_IS_ANYTYPE(type->baseType)) 16080 return (1); 16081 16082 if (WXS_IS_COMPLEX(type->baseType)) { 16083 /* 16084 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16085 * must be validly derived from B given the subset as defined by this 16086 * constraint." 16087 */ 16088 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16089 baseType, set)); 16090 } else { 16091 /* 16092 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16093 * must be validly derived from B given the subset as defined in Type 16094 * Derivation OK (Simple) ($3.14.6). 16095 */ 16096 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16097 baseType, set)); 16098 } 16099 } 16100 16101 /** 16102 * xmlSchemaCheckCOSDerivedOK: 16103 * @type: the derived simple type definition 16104 * @baseType: the base type definition 16105 * 16106 * Calls: 16107 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16108 * 16109 * Checks wheter @type can be validly derived from @baseType. 16110 * 16111 * Returns 0 on success, an positive error code otherwise. 16112 */ 16113 static int 16114 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16115 xmlSchemaTypePtr type, 16116 xmlSchemaTypePtr baseType, 16117 int set) 16118 { 16119 if (WXS_IS_SIMPLE(type)) 16120 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16121 else 16122 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16123 } 16124 16125 /** 16126 * xmlSchemaCheckCOSCTExtends: 16127 * @ctxt: the schema parser context 16128 * @type: the complex type definition 16129 * 16130 * (3.4.6) Constraints on Complex Type Definition Schema Components 16131 * Schema Component Constraint: 16132 * Derivation Valid (Extension) (cos-ct-extends) 16133 * 16134 * STATUS: 16135 * missing: 16136 * (1.5) 16137 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16138 * 16139 * Returns 0 if the constraints are satisfied, a positive 16140 * error code if not and -1 if an internal error occured. 16141 */ 16142 static int 16143 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16144 xmlSchemaTypePtr type) 16145 { 16146 xmlSchemaTypePtr base = type->baseType; 16147 /* 16148 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16149 * temporarily only. 16150 */ 16151 /* 16152 * SPEC (1) "If the {base type definition} is a complex type definition, 16153 * then all of the following must be true:" 16154 */ 16155 if (WXS_IS_COMPLEX(base)) { 16156 /* 16157 * SPEC (1.1) "The {final} of the {base type definition} must not 16158 * contain extension." 16159 */ 16160 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16161 xmlSchemaPCustomErr(ctxt, 16162 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16163 WXS_BASIC_CAST type, NULL, 16164 "The 'final' of the base type definition " 16165 "contains 'extension'", NULL); 16166 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16167 } 16168 16169 /* 16170 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16171 * since they are automatically satisfied through the 16172 * inheriting mechanism. 16173 * Note that even if redefining components, the inheriting mechanism 16174 * is used. 16175 */ 16176 #if 0 16177 /* 16178 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16179 * uses} 16180 * of the complex type definition itself, that is, for every attribute 16181 * use in the {attribute uses} of the {base type definition}, there 16182 * must be an attribute use in the {attribute uses} of the complex 16183 * type definition itself whose {attribute declaration} has the same 16184 * {name}, {target namespace} and {type definition} as its attribute 16185 * declaration" 16186 */ 16187 if (base->attrUses != NULL) { 16188 int i, j, found; 16189 xmlSchemaAttributeUsePtr use, buse; 16190 16191 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16192 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16193 found = 0; 16194 if (type->attrUses != NULL) { 16195 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16196 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16197 { 16198 if ((WXS_ATTRUSE_DECL_NAME(use) == 16199 WXS_ATTRUSE_DECL_NAME(buse)) && 16200 (WXS_ATTRUSE_DECL_TNS(use) == 16201 WXS_ATTRUSE_DECL_TNS(buse)) && 16202 (WXS_ATTRUSE_TYPEDEF(use) == 16203 WXS_ATTRUSE_TYPEDEF(buse)) 16204 { 16205 found = 1; 16206 break; 16207 } 16208 } 16209 } 16210 if (! found) { 16211 xmlChar *str = NULL; 16212 16213 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16214 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16215 NULL, WXS_BASIC_CAST type, 16216 /* 16217 * TODO: The report does not indicate that also the 16218 * type needs to be the same. 16219 */ 16220 "This type is missing a matching correspondent " 16221 "for its {base type}'s %s in its {attribute uses}", 16222 xmlSchemaGetComponentDesignation(&str, 16223 buse->children), 16224 NULL); 16225 FREE_AND_NULL(str) 16226 } 16227 } 16228 } 16229 /* 16230 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16231 * definition must also have one, and the base type definition's 16232 * {attribute wildcard}'s {namespace constraint} must be a subset 16233 * of the complex type definition's {attribute wildcard}'s {namespace 16234 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16235 */ 16236 16237 /* 16238 * MAYBE TODO: Enable if ever needed. But this will be needed only 16239 * if created the type via a schema construction API. 16240 */ 16241 if (base->attributeWildcard != NULL) { 16242 if (type->attributeWilcard == NULL) { 16243 xmlChar *str = NULL; 16244 16245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16246 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16247 NULL, type, 16248 "The base %s has an attribute wildcard, " 16249 "but this type is missing an attribute wildcard", 16250 xmlSchemaGetComponentDesignation(&str, base)); 16251 FREE_AND_NULL(str) 16252 16253 } else if (xmlSchemaCheckCOSNSSubset( 16254 base->attributeWildcard, type->attributeWildcard)) 16255 { 16256 xmlChar *str = NULL; 16257 16258 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16259 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16260 NULL, type, 16261 "The attribute wildcard is not a valid " 16262 "superset of the one in the base %s", 16263 xmlSchemaGetComponentDesignation(&str, base)); 16264 FREE_AND_NULL(str) 16265 } 16266 } 16267 #endif 16268 /* 16269 * SPEC (1.4) "One of the following must be true:" 16270 */ 16271 if ((type->contentTypeDef != NULL) && 16272 (type->contentTypeDef == base->contentTypeDef)) { 16273 /* 16274 * SPEC (1.4.1) "The {content type} of the {base type definition} 16275 * and the {content type} of the complex type definition itself 16276 * must be the same simple type definition" 16277 * PASS 16278 */ 16279 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16280 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16281 /* 16282 * SPEC (1.4.2) "The {content type} of both the {base type 16283 * definition} and the complex type definition itself must 16284 * be empty." 16285 * PASS 16286 */ 16287 } else { 16288 /* 16289 * SPEC (1.4.3) "All of the following must be true:" 16290 */ 16291 if (type->subtypes == NULL) { 16292 /* 16293 * SPEC 1.4.3.1 The {content type} of the complex type 16294 * definition itself must specify a particle. 16295 */ 16296 xmlSchemaPCustomErr(ctxt, 16297 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16298 WXS_BASIC_CAST type, NULL, 16299 "The content type must specify a particle", NULL); 16300 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16301 } 16302 /* 16303 * SPEC (1.4.3.2) "One of the following must be true:" 16304 */ 16305 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16306 /* 16307 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16308 * definition} must be empty. 16309 * PASS 16310 */ 16311 } else { 16312 /* 16313 * SPEC (1.4.3.2.2) "All of the following must be true:" 16314 */ 16315 if ((type->contentType != base->contentType) || 16316 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16317 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16318 /* 16319 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16320 * or both must be element-only." 16321 */ 16322 xmlSchemaPCustomErr(ctxt, 16323 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16324 WXS_BASIC_CAST type, NULL, 16325 "The content type of both, the type and its base " 16326 "type, must either 'mixed' or 'element-only'", NULL); 16327 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16328 } 16329 /* 16330 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16331 * complex type definition must be a `valid extension` 16332 * of the {base type definition}'s particle, as defined 16333 * in Particle Valid (Extension) ($3.9.6)." 16334 * 16335 * NOTE that we won't check "Particle Valid (Extension)", 16336 * since it is ensured by the derivation process in 16337 * xmlSchemaTypeFixup(). We need to implement this when heading 16338 * for a construction API 16339 * TODO: !! This is needed to be checked if redefining a type !! 16340 */ 16341 } 16342 /* 16343 * URGENT TODO (1.5) 16344 */ 16345 } 16346 } else { 16347 /* 16348 * SPEC (2) "If the {base type definition} is a simple type definition, 16349 * then all of the following must be true:" 16350 */ 16351 if (type->contentTypeDef != base) { 16352 /* 16353 * SPEC (2.1) "The {content type} must be the same simple type 16354 * definition." 16355 */ 16356 xmlSchemaPCustomErr(ctxt, 16357 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16358 WXS_BASIC_CAST type, NULL, 16359 "The content type must be the simple base type", NULL); 16360 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16361 } 16362 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16363 /* 16364 * SPEC (2.2) "The {final} of the {base type definition} must not 16365 * contain extension" 16366 * NOTE that this is the same as (1.1). 16367 */ 16368 xmlSchemaPCustomErr(ctxt, 16369 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16370 WXS_BASIC_CAST type, NULL, 16371 "The 'final' of the base type definition " 16372 "contains 'extension'", NULL); 16373 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16374 } 16375 } 16376 return (0); 16377 } 16378 16379 /** 16380 * xmlSchemaCheckDerivationOKRestriction: 16381 * @ctxt: the schema parser context 16382 * @type: the complex type definition 16383 * 16384 * (3.4.6) Constraints on Complex Type Definition Schema Components 16385 * Schema Component Constraint: 16386 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16387 * 16388 * STATUS: 16389 * missing: 16390 * (5.4.2) ??? 16391 * 16392 * ATTENTION: 16393 * In XML Schema 1.1 this will be: 16394 * Validation Rule: Checking complex type subsumption 16395 * 16396 * Returns 0 if the constraints are satisfied, a positive 16397 * error code if not and -1 if an internal error occured. 16398 */ 16399 static int 16400 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16401 xmlSchemaTypePtr type) 16402 { 16403 xmlSchemaTypePtr base; 16404 16405 /* 16406 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16407 * temporarily only. 16408 */ 16409 base = type->baseType; 16410 if (! WXS_IS_COMPLEX(base)) { 16411 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16412 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16413 type->node, WXS_BASIC_CAST type, 16414 "The base type must be a complex type", NULL, NULL); 16415 return(ctxt->err); 16416 } 16417 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16418 /* 16419 * SPEC (1) "The {base type definition} must be a complex type 16420 * definition whose {final} does not contain restriction." 16421 */ 16422 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16423 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16424 type->node, WXS_BASIC_CAST type, 16425 "The 'final' of the base type definition " 16426 "contains 'restriction'", NULL, NULL); 16427 return (ctxt->err); 16428 } 16429 /* 16430 * SPEC (2), (3) and (4) 16431 * Those are handled in a separate function, since the 16432 * same constraints are needed for redefinition of 16433 * attribute groups as well. 16434 */ 16435 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16436 XML_SCHEMA_ACTION_DERIVE, 16437 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16438 type->attrUses, base->attrUses, 16439 type->attributeWildcard, 16440 base->attributeWildcard) == -1) 16441 { 16442 return(-1); 16443 } 16444 /* 16445 * SPEC (5) "One of the following must be true:" 16446 */ 16447 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16448 /* 16449 * SPEC (5.1) "The {base type definition} must be the 16450 * `ur-type definition`." 16451 * PASS 16452 */ 16453 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16454 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16455 /* 16456 * SPEC (5.2.1) "The {content type} of the complex type definition 16457 * must be a simple type definition" 16458 * 16459 * SPEC (5.2.2) "One of the following must be true:" 16460 */ 16461 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16462 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16463 { 16464 int err; 16465 /* 16466 * SPEC (5.2.2.1) "The {content type} of the {base type 16467 * definition} must be a simple type definition from which 16468 * the {content type} is validly derived given the empty 16469 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16470 * 16471 * ATTENTION TODO: This seems not needed if the type implicitely 16472 * derived from the base type. 16473 * 16474 */ 16475 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16476 type->contentTypeDef, base->contentTypeDef, 0); 16477 if (err != 0) { 16478 xmlChar *strA = NULL, *strB = NULL; 16479 16480 if (err == -1) 16481 return(-1); 16482 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16483 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16484 NULL, WXS_BASIC_CAST type, 16485 "The {content type} %s is not validly derived from the " 16486 "base type's {content type} %s", 16487 xmlSchemaGetComponentDesignation(&strA, 16488 type->contentTypeDef), 16489 xmlSchemaGetComponentDesignation(&strB, 16490 base->contentTypeDef)); 16491 FREE_AND_NULL(strA); 16492 FREE_AND_NULL(strB); 16493 return(ctxt->err); 16494 } 16495 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16496 (xmlSchemaIsParticleEmptiable( 16497 (xmlSchemaParticlePtr) base->subtypes))) { 16498 /* 16499 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16500 * and have a particle which is `emptiable` as defined in 16501 * Particle Emptiable ($3.9.6)." 16502 * PASS 16503 */ 16504 } else { 16505 xmlSchemaPCustomErr(ctxt, 16506 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16507 WXS_BASIC_CAST type, NULL, 16508 "The content type of the base type must be either " 16509 "a simple type or 'mixed' and an emptiable particle", NULL); 16510 return (ctxt->err); 16511 } 16512 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16513 /* 16514 * SPEC (5.3.1) "The {content type} of the complex type itself must 16515 * be empty" 16516 */ 16517 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16518 /* 16519 * SPEC (5.3.2.1) "The {content type} of the {base type 16520 * definition} must also be empty." 16521 * PASS 16522 */ 16523 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16524 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16525 xmlSchemaIsParticleEmptiable( 16526 (xmlSchemaParticlePtr) base->subtypes)) { 16527 /* 16528 * SPEC (5.3.2.2) "The {content type} of the {base type 16529 * definition} must be elementOnly or mixed and have a particle 16530 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16531 * PASS 16532 */ 16533 } else { 16534 xmlSchemaPCustomErr(ctxt, 16535 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16536 WXS_BASIC_CAST type, NULL, 16537 "The content type of the base type must be either " 16538 "empty or 'mixed' (or 'elements-only') and an emptiable " 16539 "particle", NULL); 16540 return (ctxt->err); 16541 } 16542 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16543 WXS_HAS_MIXED_CONTENT(type)) { 16544 /* 16545 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16546 * itself must be element-only" 16547 */ 16548 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16549 /* 16550 * SPEC (5.4.1.2) "The {content type} of the complex type 16551 * definition itself and of the {base type definition} must be 16552 * mixed" 16553 */ 16554 xmlSchemaPCustomErr(ctxt, 16555 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16556 WXS_BASIC_CAST type, NULL, 16557 "If the content type is 'mixed', then the content type of the " 16558 "base type must also be 'mixed'", NULL); 16559 return (ctxt->err); 16560 } 16561 /* 16562 * SPEC (5.4.2) "The particle of the complex type definition itself 16563 * must be a `valid restriction` of the particle of the {content 16564 * type} of the {base type definition} as defined in Particle Valid 16565 * (Restriction) ($3.9.6). 16566 * 16567 * URGENT TODO: (5.4.2) 16568 */ 16569 } else { 16570 xmlSchemaPCustomErr(ctxt, 16571 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16572 WXS_BASIC_CAST type, NULL, 16573 "The type is not a valid restriction of its base type", NULL); 16574 return (ctxt->err); 16575 } 16576 return (0); 16577 } 16578 16579 /** 16580 * xmlSchemaCheckCTComponent: 16581 * @ctxt: the schema parser context 16582 * @type: the complex type definition 16583 * 16584 * (3.4.6) Constraints on Complex Type Definition Schema Components 16585 * 16586 * Returns 0 if the constraints are satisfied, a positive 16587 * error code if not and -1 if an internal error occured. 16588 */ 16589 static int 16590 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16591 xmlSchemaTypePtr type) 16592 { 16593 int ret; 16594 /* 16595 * Complex Type Definition Properties Correct 16596 */ 16597 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16598 if (ret != 0) 16599 return (ret); 16600 if (WXS_IS_EXTENSION(type)) 16601 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16602 else 16603 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16604 return (ret); 16605 } 16606 16607 /** 16608 * xmlSchemaCheckSRCCT: 16609 * @ctxt: the schema parser context 16610 * @type: the complex type definition 16611 * 16612 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16613 * Schema Representation Constraint: 16614 * Complex Type Definition Representation OK (src-ct) 16615 * 16616 * Returns 0 if the constraints are satisfied, a positive 16617 * error code if not and -1 if an internal error occured. 16618 */ 16619 static int 16620 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16621 xmlSchemaTypePtr type) 16622 { 16623 xmlSchemaTypePtr base; 16624 int ret = 0; 16625 16626 /* 16627 * TODO: Adjust the error codes here, as I used 16628 * XML_SCHEMAP_SRC_CT_1 only yet. 16629 */ 16630 base = type->baseType; 16631 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16632 /* 16633 * 1 If the <complexContent> alternative is chosen, the type definition 16634 * `resolved` to by the `actual value` of the base [attribute] 16635 * must be a complex type definition; 16636 */ 16637 if (! WXS_IS_COMPLEX(base)) { 16638 xmlChar *str = NULL; 16639 xmlSchemaPCustomErr(ctxt, 16640 XML_SCHEMAP_SRC_CT_1, 16641 WXS_BASIC_CAST type, type->node, 16642 "If using <complexContent>, the base type is expected to be " 16643 "a complex type. The base type '%s' is a simple type", 16644 xmlSchemaFormatQName(&str, base->targetNamespace, 16645 base->name)); 16646 FREE_AND_NULL(str) 16647 return (XML_SCHEMAP_SRC_CT_1); 16648 } 16649 } else { 16650 /* 16651 * SPEC 16652 * 2 If the <simpleContent> alternative is chosen, all of the 16653 * following must be true: 16654 * 2.1 The type definition `resolved` to by the `actual value` of the 16655 * base [attribute] must be one of the following: 16656 */ 16657 if (WXS_IS_SIMPLE(base)) { 16658 if (WXS_IS_EXTENSION(type) == 0) { 16659 xmlChar *str = NULL; 16660 /* 16661 * 2.1.3 only if the <extension> alternative is also 16662 * chosen, a simple type definition. 16663 */ 16664 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16665 xmlSchemaPCustomErr(ctxt, 16666 XML_SCHEMAP_SRC_CT_1, 16667 WXS_BASIC_CAST type, NULL, 16668 "If using <simpleContent> and <restriction>, the base " 16669 "type must be a complex type. The base type '%s' is " 16670 "a simple type", 16671 xmlSchemaFormatQName(&str, base->targetNamespace, 16672 base->name)); 16673 FREE_AND_NULL(str) 16674 return (XML_SCHEMAP_SRC_CT_1); 16675 } 16676 } else { 16677 /* Base type is a complex type. */ 16678 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16679 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16680 /* 16681 * 2.1.1 a complex type definition whose {content type} is a 16682 * simple type definition; 16683 * PASS 16684 */ 16685 if (base->contentTypeDef == NULL) { 16686 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16687 WXS_BASIC_CAST type, NULL, 16688 "Internal error: xmlSchemaCheckSRCCT, " 16689 "'%s', base type has no content type", 16690 type->name); 16691 return (-1); 16692 } 16693 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16694 (WXS_IS_RESTRICTION(type))) { 16695 16696 /* 16697 * 2.1.2 only if the <restriction> alternative is also 16698 * chosen, a complex type definition whose {content type} 16699 * is mixed and a particle emptiable. 16700 */ 16701 if (! xmlSchemaIsParticleEmptiable( 16702 (xmlSchemaParticlePtr) base->subtypes)) { 16703 ret = XML_SCHEMAP_SRC_CT_1; 16704 } else 16705 /* 16706 * Attention: at this point the <simpleType> child is in 16707 * ->contentTypeDef (put there during parsing). 16708 */ 16709 if (type->contentTypeDef == NULL) { 16710 xmlChar *str = NULL; 16711 /* 16712 * 2.2 If clause 2.1.2 above is satisfied, then there 16713 * must be a <simpleType> among the [children] of 16714 * <restriction>. 16715 */ 16716 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16717 xmlSchemaPCustomErr(ctxt, 16718 XML_SCHEMAP_SRC_CT_1, 16719 WXS_BASIC_CAST type, NULL, 16720 "A <simpleType> is expected among the children " 16721 "of <restriction>, if <simpleContent> is used and " 16722 "the base type '%s' is a complex type", 16723 xmlSchemaFormatQName(&str, base->targetNamespace, 16724 base->name)); 16725 FREE_AND_NULL(str) 16726 return (XML_SCHEMAP_SRC_CT_1); 16727 } 16728 } else { 16729 ret = XML_SCHEMAP_SRC_CT_1; 16730 } 16731 } 16732 if (ret > 0) { 16733 xmlChar *str = NULL; 16734 if (WXS_IS_RESTRICTION(type)) { 16735 xmlSchemaPCustomErr(ctxt, 16736 XML_SCHEMAP_SRC_CT_1, 16737 WXS_BASIC_CAST type, NULL, 16738 "If <simpleContent> and <restriction> is used, the " 16739 "base type must be a simple type or a complex type with " 16740 "mixed content and particle emptiable. The base type " 16741 "'%s' is none of those", 16742 xmlSchemaFormatQName(&str, base->targetNamespace, 16743 base->name)); 16744 } else { 16745 xmlSchemaPCustomErr(ctxt, 16746 XML_SCHEMAP_SRC_CT_1, 16747 WXS_BASIC_CAST type, NULL, 16748 "If <simpleContent> and <extension> is used, the " 16749 "base type must be a simple type. The base type '%s' " 16750 "is a complex type", 16751 xmlSchemaFormatQName(&str, base->targetNamespace, 16752 base->name)); 16753 } 16754 FREE_AND_NULL(str) 16755 } 16756 } 16757 /* 16758 * SPEC (3) "The corresponding complex type definition component must 16759 * satisfy the conditions set out in Constraints on Complex Type 16760 * Definition Schema Components ($3.4.6);" 16761 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16762 */ 16763 /* 16764 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16765 * above for {attribute wildcard} is satisfied, the intensional 16766 * intersection must be expressible, as defined in Attribute Wildcard 16767 * Intersection ($3.10.6). 16768 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16769 */ 16770 return (ret); 16771 } 16772 16773 #ifdef ENABLE_PARTICLE_RESTRICTION 16774 /** 16775 * xmlSchemaCheckParticleRangeOK: 16776 * @ctxt: the schema parser context 16777 * @type: the complex type definition 16778 * 16779 * (3.9.6) Constraints on Particle Schema Components 16780 * Schema Component Constraint: 16781 * Occurrence Range OK (range-ok) 16782 * 16783 * STATUS: complete 16784 * 16785 * Returns 0 if the constraints are satisfied, a positive 16786 * error code if not and -1 if an internal error occured. 16787 */ 16788 static int 16789 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16790 int bmin, int bmax) 16791 { 16792 if (rmin < bmin) 16793 return (1); 16794 if ((bmax != UNBOUNDED) && 16795 (rmax > bmax)) 16796 return (1); 16797 return (0); 16798 } 16799 16800 /** 16801 * xmlSchemaCheckRCaseNameAndTypeOK: 16802 * @ctxt: the schema parser context 16803 * @r: the restricting element declaration particle 16804 * @b: the base element declaration particle 16805 * 16806 * (3.9.6) Constraints on Particle Schema Components 16807 * Schema Component Constraint: 16808 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16809 * (rcase-NameAndTypeOK) 16810 * 16811 * STATUS: 16812 * MISSING (3.2.3) 16813 * CLARIFY: (3.2.2) 16814 * 16815 * Returns 0 if the constraints are satisfied, a positive 16816 * error code if not and -1 if an internal error occured. 16817 */ 16818 static int 16819 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16820 xmlSchemaParticlePtr r, 16821 xmlSchemaParticlePtr b) 16822 { 16823 xmlSchemaElementPtr elemR, elemB; 16824 16825 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16826 elemR = (xmlSchemaElementPtr) r->children; 16827 elemB = (xmlSchemaElementPtr) b->children; 16828 /* 16829 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16830 * the same." 16831 */ 16832 if ((elemR != elemB) && 16833 ((! xmlStrEqual(elemR->name, elemB->name)) || 16834 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16835 return (1); 16836 /* 16837 * SPEC (2) "R's occurrence range is a valid restriction of B's 16838 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16839 */ 16840 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16841 b->minOccurs, b->maxOccurs) != 0) 16842 return (1); 16843 /* 16844 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16845 * {scope} are global." 16846 */ 16847 if (elemR == elemB) 16848 return (0); 16849 /* 16850 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16851 */ 16852 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16853 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16854 return (1); 16855 /* 16856 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16857 * or is not fixed, or R's declaration's {value constraint} is fixed 16858 * with the same value." 16859 */ 16860 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16861 ((elemR->value == NULL) || 16862 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16863 /* TODO: Equality of the initial value or normalized or canonical? */ 16864 (! xmlStrEqual(elemR->value, elemB->value)))) 16865 return (1); 16866 /* 16867 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16868 * definitions} is a subset of B's declaration's {identity-constraint 16869 * definitions}, if any." 16870 */ 16871 if (elemB->idcs != NULL) { 16872 /* TODO */ 16873 } 16874 /* 16875 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16876 * superset of B's declaration's {disallowed substitutions}." 16877 */ 16878 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16879 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16880 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16881 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16882 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16883 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16884 return (1); 16885 /* 16886 * SPEC (3.2.5) "R's {type definition} is validly derived given 16887 * {extension, list, union} from B's {type definition}" 16888 * 16889 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16890 * set, if the corresponding constraints handle "restriction" and 16891 * "extension" only? 16892 * 16893 */ 16894 { 16895 int set = 0; 16896 16897 set |= SUBSET_EXTENSION; 16898 set |= SUBSET_LIST; 16899 set |= SUBSET_UNION; 16900 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16901 elemB->subtypes, set) != 0) 16902 return (1); 16903 } 16904 return (0); 16905 } 16906 16907 /** 16908 * xmlSchemaCheckRCaseNSCompat: 16909 * @ctxt: the schema parser context 16910 * @r: the restricting element declaration particle 16911 * @b: the base wildcard particle 16912 * 16913 * (3.9.6) Constraints on Particle Schema Components 16914 * Schema Component Constraint: 16915 * Particle Derivation OK (Elt:Any -- NSCompat) 16916 * (rcase-NSCompat) 16917 * 16918 * STATUS: complete 16919 * 16920 * Returns 0 if the constraints are satisfied, a positive 16921 * error code if not and -1 if an internal error occured. 16922 */ 16923 static int 16924 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16925 xmlSchemaParticlePtr r, 16926 xmlSchemaParticlePtr b) 16927 { 16928 /* TODO:Error codes (rcase-NSCompat). */ 16929 /* 16930 * SPEC "For an element declaration particle to be a `valid restriction` 16931 * of a wildcard particle all of the following must be true:" 16932 * 16933 * SPEC (1) "The element declaration's {target namespace} is `valid` 16934 * with respect to the wildcard's {namespace constraint} as defined by 16935 * Wildcard allows Namespace Name ($3.10.4)." 16936 */ 16937 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16938 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16939 return (1); 16940 /* 16941 * SPEC (2) "R's occurrence range is a valid restriction of B's 16942 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16943 */ 16944 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16945 b->minOccurs, b->maxOccurs) != 0) 16946 return (1); 16947 16948 return (0); 16949 } 16950 16951 /** 16952 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16953 * @ctxt: the schema parser context 16954 * @r: the restricting element declaration particle 16955 * @b: the base model group particle 16956 * 16957 * (3.9.6) Constraints on Particle Schema Components 16958 * Schema Component Constraint: 16959 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16960 * (rcase-RecurseAsIfGroup) 16961 * 16962 * STATUS: TODO 16963 * 16964 * Returns 0 if the constraints are satisfied, a positive 16965 * error code if not and -1 if an internal error occured. 16966 */ 16967 static int 16968 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16969 xmlSchemaParticlePtr r, 16970 xmlSchemaParticlePtr b) 16971 { 16972 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16973 TODO 16974 return (0); 16975 } 16976 16977 /** 16978 * xmlSchemaCheckRCaseNSSubset: 16979 * @ctxt: the schema parser context 16980 * @r: the restricting wildcard particle 16981 * @b: the base wildcard particle 16982 * 16983 * (3.9.6) Constraints on Particle Schema Components 16984 * Schema Component Constraint: 16985 * Particle Derivation OK (Any:Any -- NSSubset) 16986 * (rcase-NSSubset) 16987 * 16988 * STATUS: complete 16989 * 16990 * Returns 0 if the constraints are satisfied, a positive 16991 * error code if not and -1 if an internal error occured. 16992 */ 16993 static int 16994 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16995 xmlSchemaParticlePtr r, 16996 xmlSchemaParticlePtr b, 16997 int isAnyTypeBase) 16998 { 16999 /* TODO: Error codes (rcase-NSSubset). */ 17000 /* 17001 * SPEC (1) "R's occurrence range is a valid restriction of B's 17002 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17003 */ 17004 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17005 b->minOccurs, b->maxOccurs)) 17006 return (1); 17007 /* 17008 * SPEC (2) "R's {namespace constraint} must be an intensional subset 17009 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 17010 */ 17011 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 17012 (xmlSchemaWildcardPtr) b->children)) 17013 return (1); 17014 /* 17015 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17016 * definition`, R's {process contents} must be identical to or stronger 17017 * than B's {process contents}, where strict is stronger than lax is 17018 * stronger than skip." 17019 */ 17020 if (! isAnyTypeBase) { 17021 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17022 ((xmlSchemaWildcardPtr) b->children)->processContents) 17023 return (1); 17024 } 17025 17026 return (0); 17027 } 17028 17029 /** 17030 * xmlSchemaCheckCOSParticleRestrict: 17031 * @ctxt: the schema parser context 17032 * @type: the complex type definition 17033 * 17034 * (3.9.6) Constraints on Particle Schema Components 17035 * Schema Component Constraint: 17036 * Particle Valid (Restriction) (cos-particle-restrict) 17037 * 17038 * STATUS: TODO 17039 * 17040 * Returns 0 if the constraints are satisfied, a positive 17041 * error code if not and -1 if an internal error occured. 17042 */ 17043 static int 17044 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17045 xmlSchemaParticlePtr r, 17046 xmlSchemaParticlePtr b) 17047 { 17048 int ret = 0; 17049 17050 /*part = WXS_TYPE_PARTICLE(type); 17051 basePart = WXS_TYPE_PARTICLE(base); 17052 */ 17053 17054 TODO 17055 17056 /* 17057 * SPEC (1) "They are the same particle." 17058 */ 17059 if (r == b) 17060 return (0); 17061 17062 17063 return (0); 17064 } 17065 17066 #if 0 17067 /** 17068 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17069 * @ctxt: the schema parser context 17070 * @r: the model group particle 17071 * @b: the base wildcard particle 17072 * 17073 * (3.9.6) Constraints on Particle Schema Components 17074 * Schema Component Constraint: 17075 * Particle Derivation OK (All/Choice/Sequence:Any -- 17076 * NSRecurseCheckCardinality) 17077 * (rcase-NSRecurseCheckCardinality) 17078 * 17079 * STATUS: TODO: subst-groups 17080 * 17081 * Returns 0 if the constraints are satisfied, a positive 17082 * error code if not and -1 if an internal error occured. 17083 */ 17084 static int 17085 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17086 xmlSchemaParticlePtr r, 17087 xmlSchemaParticlePtr b) 17088 { 17089 xmlSchemaParticlePtr part; 17090 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17091 if ((r->children == NULL) || (r->children->children == NULL)) 17092 return (-1); 17093 /* 17094 * SPEC "For a group particle to be a `valid restriction` of a 17095 * wildcard particle..." 17096 * 17097 * SPEC (1) "Every member of the {particles} of the group is a `valid 17098 * restriction` of the wildcard as defined by 17099 * Particle Valid (Restriction) ($3.9.6)." 17100 */ 17101 part = (xmlSchemaParticlePtr) r->children->children; 17102 do { 17103 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17104 return (1); 17105 part = (xmlSchemaParticlePtr) part->next; 17106 } while (part != NULL); 17107 /* 17108 * SPEC (2) "The effective total range of the group [...] is a 17109 * valid restriction of B's occurrence range as defined by 17110 * Occurrence Range OK ($3.9.6)." 17111 */ 17112 if (xmlSchemaCheckParticleRangeOK( 17113 xmlSchemaGetParticleTotalRangeMin(r), 17114 xmlSchemaGetParticleTotalRangeMax(r), 17115 b->minOccurs, b->maxOccurs) != 0) 17116 return (1); 17117 return (0); 17118 } 17119 #endif 17120 17121 /** 17122 * xmlSchemaCheckRCaseRecurse: 17123 * @ctxt: the schema parser context 17124 * @r: the <all> or <sequence> model group particle 17125 * @b: the base <all> or <sequence> model group particle 17126 * 17127 * (3.9.6) Constraints on Particle Schema Components 17128 * Schema Component Constraint: 17129 * Particle Derivation OK (All:All,Sequence:Sequence -- 17130 Recurse) 17131 * (rcase-Recurse) 17132 * 17133 * STATUS: ? 17134 * TODO: subst-groups 17135 * 17136 * Returns 0 if the constraints are satisfied, a positive 17137 * error code if not and -1 if an internal error occured. 17138 */ 17139 static int 17140 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17141 xmlSchemaParticlePtr r, 17142 xmlSchemaParticlePtr b) 17143 { 17144 /* xmlSchemaParticlePtr part; */ 17145 /* TODO: Error codes (rcase-Recurse). */ 17146 if ((r->children == NULL) || (b->children == NULL) || 17147 (r->children->type != b->children->type)) 17148 return (-1); 17149 /* 17150 * SPEC "For an all or sequence group particle to be a `valid 17151 * restriction` of another group particle with the same {compositor}..." 17152 * 17153 * SPEC (1) "R's occurrence range is a valid restriction of B's 17154 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17155 */ 17156 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17157 b->minOccurs, b->maxOccurs)) 17158 return (1); 17159 17160 17161 return (0); 17162 } 17163 17164 #endif 17165 17166 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17167 xmlSchemaPCustomErrExt(pctxt, \ 17168 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17169 WXS_BASIC_CAST fac1, fac1->node, \ 17170 "It is an error for both '%s' and '%s' to be specified on the "\ 17171 "same type definition", \ 17172 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17173 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17174 17175 #define FACET_RESTR_ERR(fac1, msg) \ 17176 xmlSchemaPCustomErr(pctxt, \ 17177 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17178 WXS_BASIC_CAST fac1, fac1->node, \ 17179 msg, NULL); 17180 17181 #define FACET_RESTR_FIXED_ERR(fac) \ 17182 xmlSchemaPCustomErr(pctxt, \ 17183 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17184 WXS_BASIC_CAST fac, fac->node, \ 17185 "The base type's facet is 'fixed', thus the value must not " \ 17186 "differ", NULL); 17187 17188 static void 17189 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17190 xmlSchemaFacetPtr facet1, 17191 xmlSchemaFacetPtr facet2, 17192 int lessGreater, 17193 int orEqual, 17194 int ofBase) 17195 { 17196 xmlChar *msg = NULL; 17197 17198 msg = xmlStrdup(BAD_CAST "'"); 17199 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17200 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17201 if (lessGreater == 0) 17202 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17203 if (lessGreater == 1) 17204 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17205 else 17206 msg = xmlStrcat(msg, BAD_CAST " less than"); 17207 17208 if (orEqual) 17209 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17210 msg = xmlStrcat(msg, BAD_CAST " '"); 17211 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17212 if (ofBase) 17213 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17214 else 17215 msg = xmlStrcat(msg, BAD_CAST "'"); 17216 17217 xmlSchemaPCustomErr(pctxt, 17218 XML_SCHEMAP_INVALID_FACET_VALUE, 17219 WXS_BASIC_CAST facet1, NULL, 17220 (const char *) msg, NULL); 17221 17222 if (msg != NULL) 17223 xmlFree(msg); 17224 } 17225 17226 /* 17227 * xmlSchemaDeriveAndValidateFacets: 17228 * 17229 * Schema Component Constraint: Simple Type Restriction (Facets) 17230 * (st-restrict-facets) 17231 */ 17232 static int 17233 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17234 xmlSchemaTypePtr type) 17235 { 17236 xmlSchemaTypePtr base = type->baseType; 17237 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17238 xmlSchemaFacetPtr facet, bfacet, 17239 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17240 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17241 fmininc = NULL, fmaxinc = NULL, 17242 fminexc = NULL, fmaxexc = NULL, 17243 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17244 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17245 bfmininc = NULL, bfmaxinc = NULL, 17246 bfminexc = NULL, bfmaxexc = NULL; 17247 int res; /* err = 0, fixedErr; */ 17248 17249 /* 17250 * SPEC st-restrict-facets 1: 17251 * "The {variety} of R is the same as that of B." 17252 */ 17253 /* 17254 * SPEC st-restrict-facets 2: 17255 * "If {variety} is atomic, the {primitive type definition} 17256 * of R is the same as that of B." 17257 * 17258 * NOTE: we leave 1 & 2 out for now, since this will be 17259 * satisfied by the derivation process. 17260 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17261 */ 17262 /* 17263 * SPEC st-restrict-facets 3: 17264 * "The {facets} of R are the union of S and the {facets} 17265 * of B, eliminating duplicates. To eliminate duplicates, 17266 * when a facet of the same kind occurs in both S and the 17267 * {facets} of B, the one in the {facets} of B is not 17268 * included, with the exception of enumeration and pattern 17269 * facets, for which multiple occurrences with distinct values 17270 * are allowed." 17271 */ 17272 17273 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17274 return (0); 17275 17276 last = type->facetSet; 17277 if (last != NULL) 17278 while (last->next != NULL) 17279 last = last->next; 17280 17281 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17282 facet = cur->facet; 17283 switch (facet->type) { 17284 case XML_SCHEMA_FACET_LENGTH: 17285 flength = facet; break; 17286 case XML_SCHEMA_FACET_MINLENGTH: 17287 fminlen = facet; break; 17288 case XML_SCHEMA_FACET_MININCLUSIVE: 17289 fmininc = facet; break; 17290 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17291 fminexc = facet; break; 17292 case XML_SCHEMA_FACET_MAXLENGTH: 17293 fmaxlen = facet; break; 17294 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17295 fmaxinc = facet; break; 17296 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17297 fmaxexc = facet; break; 17298 case XML_SCHEMA_FACET_TOTALDIGITS: 17299 ftotdig = facet; break; 17300 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17301 ffracdig = facet; break; 17302 default: 17303 break; 17304 } 17305 } 17306 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17307 facet = cur->facet; 17308 switch (facet->type) { 17309 case XML_SCHEMA_FACET_LENGTH: 17310 bflength = facet; break; 17311 case XML_SCHEMA_FACET_MINLENGTH: 17312 bfminlen = facet; break; 17313 case XML_SCHEMA_FACET_MININCLUSIVE: 17314 bfmininc = facet; break; 17315 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17316 bfminexc = facet; break; 17317 case XML_SCHEMA_FACET_MAXLENGTH: 17318 bfmaxlen = facet; break; 17319 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17320 bfmaxinc = facet; break; 17321 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17322 bfmaxexc = facet; break; 17323 case XML_SCHEMA_FACET_TOTALDIGITS: 17324 bftotdig = facet; break; 17325 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17326 bffracdig = facet; break; 17327 default: 17328 break; 17329 } 17330 } 17331 /* 17332 * length and minLength or maxLength (2.2) + (3.2) 17333 */ 17334 if (flength && (fminlen || fmaxlen)) { 17335 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17336 "either of 'minLength' or 'maxLength' to be specified on " 17337 "the same type definition") 17338 } 17339 /* 17340 * Mutual exclusions in the same derivation step. 17341 */ 17342 if ((fmaxinc) && (fmaxexc)) { 17343 /* 17344 * SCC "maxInclusive and maxExclusive" 17345 */ 17346 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17347 } 17348 if ((fmininc) && (fminexc)) { 17349 /* 17350 * SCC "minInclusive and minExclusive" 17351 */ 17352 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17353 } 17354 17355 if (flength && bflength) { 17356 /* 17357 * SCC "length valid restriction" 17358 * The values have to be equal. 17359 */ 17360 res = xmlSchemaCompareValues(flength->val, bflength->val); 17361 if (res == -2) 17362 goto internal_error; 17363 if (res != 0) 17364 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17365 if ((res != 0) && (bflength->fixed)) { 17366 FACET_RESTR_FIXED_ERR(flength) 17367 } 17368 17369 } 17370 if (fminlen && bfminlen) { 17371 /* 17372 * SCC "minLength valid restriction" 17373 * minLength >= BASE minLength 17374 */ 17375 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17376 if (res == -2) 17377 goto internal_error; 17378 if (res == -1) 17379 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17380 if ((res != 0) && (bfminlen->fixed)) { 17381 FACET_RESTR_FIXED_ERR(fminlen) 17382 } 17383 } 17384 if (fmaxlen && bfmaxlen) { 17385 /* 17386 * SCC "maxLength valid restriction" 17387 * maxLength <= BASE minLength 17388 */ 17389 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17390 if (res == -2) 17391 goto internal_error; 17392 if (res == 1) 17393 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17394 if ((res != 0) && (bfmaxlen->fixed)) { 17395 FACET_RESTR_FIXED_ERR(fmaxlen) 17396 } 17397 } 17398 /* 17399 * SCC "length and minLength or maxLength" 17400 */ 17401 if (! flength) 17402 flength = bflength; 17403 if (flength) { 17404 if (! fminlen) 17405 fminlen = bfminlen; 17406 if (fminlen) { 17407 /* (1.1) length >= minLength */ 17408 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17409 if (res == -2) 17410 goto internal_error; 17411 if (res == -1) 17412 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17413 } 17414 if (! fmaxlen) 17415 fmaxlen = bfmaxlen; 17416 if (fmaxlen) { 17417 /* (2.1) length <= maxLength */ 17418 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17419 if (res == -2) 17420 goto internal_error; 17421 if (res == 1) 17422 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17423 } 17424 } 17425 if (fmaxinc) { 17426 /* 17427 * "maxInclusive" 17428 */ 17429 if (fmininc) { 17430 /* SCC "maxInclusive >= minInclusive" */ 17431 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17432 if (res == -2) 17433 goto internal_error; 17434 if (res == -1) { 17435 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17436 } 17437 } 17438 /* 17439 * SCC "maxInclusive valid restriction" 17440 */ 17441 if (bfmaxinc) { 17442 /* maxInclusive <= BASE maxInclusive */ 17443 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17444 if (res == -2) 17445 goto internal_error; 17446 if (res == 1) 17447 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17448 if ((res != 0) && (bfmaxinc->fixed)) { 17449 FACET_RESTR_FIXED_ERR(fmaxinc) 17450 } 17451 } 17452 if (bfmaxexc) { 17453 /* maxInclusive < BASE maxExclusive */ 17454 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17455 if (res == -2) 17456 goto internal_error; 17457 if (res != -1) { 17458 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17459 } 17460 } 17461 if (bfmininc) { 17462 /* maxInclusive >= BASE minInclusive */ 17463 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17464 if (res == -2) 17465 goto internal_error; 17466 if (res == -1) { 17467 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17468 } 17469 } 17470 if (bfminexc) { 17471 /* maxInclusive > BASE minExclusive */ 17472 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17473 if (res == -2) 17474 goto internal_error; 17475 if (res != 1) { 17476 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17477 } 17478 } 17479 } 17480 if (fmaxexc) { 17481 /* 17482 * "maxExclusive >= minExclusive" 17483 */ 17484 if (fminexc) { 17485 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17486 if (res == -2) 17487 goto internal_error; 17488 if (res == -1) { 17489 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17490 } 17491 } 17492 /* 17493 * "maxExclusive valid restriction" 17494 */ 17495 if (bfmaxexc) { 17496 /* maxExclusive <= BASE maxExclusive */ 17497 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17498 if (res == -2) 17499 goto internal_error; 17500 if (res == 1) { 17501 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17502 } 17503 if ((res != 0) && (bfmaxexc->fixed)) { 17504 FACET_RESTR_FIXED_ERR(fmaxexc) 17505 } 17506 } 17507 if (bfmaxinc) { 17508 /* maxExclusive <= BASE maxInclusive */ 17509 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17510 if (res == -2) 17511 goto internal_error; 17512 if (res == 1) { 17513 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17514 } 17515 } 17516 if (bfmininc) { 17517 /* maxExclusive > BASE minInclusive */ 17518 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17519 if (res == -2) 17520 goto internal_error; 17521 if (res != 1) { 17522 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17523 } 17524 } 17525 if (bfminexc) { 17526 /* maxExclusive > BASE minExclusive */ 17527 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17528 if (res == -2) 17529 goto internal_error; 17530 if (res != 1) { 17531 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17532 } 17533 } 17534 } 17535 if (fminexc) { 17536 /* 17537 * "minExclusive < maxInclusive" 17538 */ 17539 if (fmaxinc) { 17540 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17541 if (res == -2) 17542 goto internal_error; 17543 if (res != -1) { 17544 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17545 } 17546 } 17547 /* 17548 * "minExclusive valid restriction" 17549 */ 17550 if (bfminexc) { 17551 /* minExclusive >= BASE minExclusive */ 17552 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17553 if (res == -2) 17554 goto internal_error; 17555 if (res == -1) { 17556 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17557 } 17558 if ((res != 0) && (bfminexc->fixed)) { 17559 FACET_RESTR_FIXED_ERR(fminexc) 17560 } 17561 } 17562 if (bfmaxinc) { 17563 /* minExclusive <= BASE maxInclusive */ 17564 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17565 if (res == -2) 17566 goto internal_error; 17567 if (res == 1) { 17568 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17569 } 17570 } 17571 if (bfmininc) { 17572 /* minExclusive >= BASE minInclusive */ 17573 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17574 if (res == -2) 17575 goto internal_error; 17576 if (res == -1) { 17577 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17578 } 17579 } 17580 if (bfmaxexc) { 17581 /* minExclusive < BASE maxExclusive */ 17582 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17583 if (res == -2) 17584 goto internal_error; 17585 if (res != -1) { 17586 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17587 } 17588 } 17589 } 17590 if (fmininc) { 17591 /* 17592 * "minInclusive < maxExclusive" 17593 */ 17594 if (fmaxexc) { 17595 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17596 if (res == -2) 17597 goto internal_error; 17598 if (res != -1) { 17599 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17600 } 17601 } 17602 /* 17603 * "minExclusive valid restriction" 17604 */ 17605 if (bfmininc) { 17606 /* minInclusive >= BASE minInclusive */ 17607 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17608 if (res == -2) 17609 goto internal_error; 17610 if (res == -1) { 17611 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17612 } 17613 if ((res != 0) && (bfmininc->fixed)) { 17614 FACET_RESTR_FIXED_ERR(fmininc) 17615 } 17616 } 17617 if (bfmaxinc) { 17618 /* minInclusive <= BASE maxInclusive */ 17619 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17620 if (res == -2) 17621 goto internal_error; 17622 if (res == 1) { 17623 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17624 } 17625 } 17626 if (bfminexc) { 17627 /* minInclusive > BASE minExclusive */ 17628 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17629 if (res == -2) 17630 goto internal_error; 17631 if (res != 1) 17632 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17633 } 17634 if (bfmaxexc) { 17635 /* minInclusive < BASE maxExclusive */ 17636 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17637 if (res == -2) 17638 goto internal_error; 17639 if (res != -1) 17640 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17641 } 17642 } 17643 if (ftotdig && bftotdig) { 17644 /* 17645 * SCC " totalDigits valid restriction" 17646 * totalDigits <= BASE totalDigits 17647 */ 17648 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17649 if (res == -2) 17650 goto internal_error; 17651 if (res == 1) 17652 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17653 -1, 1, 1); 17654 if ((res != 0) && (bftotdig->fixed)) { 17655 FACET_RESTR_FIXED_ERR(ftotdig) 17656 } 17657 } 17658 if (ffracdig && bffracdig) { 17659 /* 17660 * SCC "fractionDigits valid restriction" 17661 * fractionDigits <= BASE fractionDigits 17662 */ 17663 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17664 if (res == -2) 17665 goto internal_error; 17666 if (res == 1) 17667 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17668 -1, 1, 1); 17669 if ((res != 0) && (bffracdig->fixed)) { 17670 FACET_RESTR_FIXED_ERR(ffracdig) 17671 } 17672 } 17673 /* 17674 * SCC "fractionDigits less than or equal to totalDigits" 17675 */ 17676 if (! ftotdig) 17677 ftotdig = bftotdig; 17678 if (! ffracdig) 17679 ffracdig = bffracdig; 17680 if (ftotdig && ffracdig) { 17681 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17682 if (res == -2) 17683 goto internal_error; 17684 if (res == 1) 17685 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17686 -1, 1, 0); 17687 } 17688 /* 17689 * *Enumerations* won' be added here, since only the first set 17690 * of enumerations in the ancestor-or-self axis is used 17691 * for validation, plus we need to use the base type of those 17692 * enumerations for whitespace. 17693 * 17694 * *Patterns*: won't be add here, since they are ORed at 17695 * type level and ANDed at ancestor level. This will 17696 * happed during validation by walking the base axis 17697 * of the type. 17698 */ 17699 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17700 bfacet = cur->facet; 17701 /* 17702 * Special handling of enumerations and patterns. 17703 * TODO: hmm, they should not appear in the set, so remove this. 17704 */ 17705 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17706 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17707 continue; 17708 /* 17709 * Search for a duplicate facet in the current type. 17710 */ 17711 link = type->facetSet; 17712 /* err = 0; */ 17713 /* fixedErr = 0; */ 17714 while (link != NULL) { 17715 facet = link->facet; 17716 if (facet->type == bfacet->type) { 17717 switch (facet->type) { 17718 case XML_SCHEMA_FACET_WHITESPACE: 17719 /* 17720 * The whitespace must be stronger. 17721 */ 17722 if (facet->whitespace < bfacet->whitespace) { 17723 FACET_RESTR_ERR(facet, 17724 "The 'whitespace' value has to be equal to " 17725 "or stronger than the 'whitespace' value of " 17726 "the base type") 17727 } 17728 if ((bfacet->fixed) && 17729 (facet->whitespace != bfacet->whitespace)) { 17730 FACET_RESTR_FIXED_ERR(facet) 17731 } 17732 break; 17733 default: 17734 break; 17735 } 17736 /* Duplicate found. */ 17737 break; 17738 } 17739 link = link->next; 17740 } 17741 /* 17742 * If no duplicate was found: add the base types's facet 17743 * to the set. 17744 */ 17745 if (link == NULL) { 17746 link = (xmlSchemaFacetLinkPtr) 17747 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17748 if (link == NULL) { 17749 xmlSchemaPErrMemory(pctxt, 17750 "deriving facets, creating a facet link", NULL); 17751 return (-1); 17752 } 17753 link->facet = cur->facet; 17754 link->next = NULL; 17755 if (last == NULL) 17756 type->facetSet = link; 17757 else 17758 last->next = link; 17759 last = link; 17760 } 17761 17762 } 17763 17764 return (0); 17765 internal_error: 17766 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17767 "an error occured"); 17768 return (-1); 17769 } 17770 17771 static int 17772 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17773 xmlSchemaTypePtr type) 17774 { 17775 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17776 /* 17777 * The actual value is then formed by replacing any union type 17778 * definition in the `explicit members` with the members of their 17779 * {member type definitions}, in order. 17780 * 17781 * TODO: There's a bug entry at 17782 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17783 * which indicates that we'll keep the union types the future. 17784 */ 17785 link = type->memberTypes; 17786 while (link != NULL) { 17787 17788 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17789 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17790 17791 if (WXS_IS_UNION(link->type)) { 17792 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17793 if (subLink != NULL) { 17794 link->type = subLink->type; 17795 if (subLink->next != NULL) { 17796 lastLink = link->next; 17797 subLink = subLink->next; 17798 prevLink = link; 17799 while (subLink != NULL) { 17800 newLink = (xmlSchemaTypeLinkPtr) 17801 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17802 if (newLink == NULL) { 17803 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17804 NULL); 17805 return (-1); 17806 } 17807 newLink->type = subLink->type; 17808 prevLink->next = newLink; 17809 prevLink = newLink; 17810 newLink->next = lastLink; 17811 17812 subLink = subLink->next; 17813 } 17814 } 17815 } 17816 } 17817 link = link->next; 17818 } 17819 return (0); 17820 } 17821 17822 static void 17823 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17824 { 17825 int has = 0, needVal = 0, normVal = 0; 17826 17827 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17828 if (has) { 17829 needVal = (type->baseType->flags & 17830 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17831 normVal = (type->baseType->flags & 17832 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17833 } 17834 if (type->facets != NULL) { 17835 xmlSchemaFacetPtr fac; 17836 17837 for (fac = type->facets; fac != NULL; fac = fac->next) { 17838 switch (fac->type) { 17839 case XML_SCHEMA_FACET_WHITESPACE: 17840 break; 17841 case XML_SCHEMA_FACET_PATTERN: 17842 normVal = 1; 17843 has = 1; 17844 break; 17845 case XML_SCHEMA_FACET_ENUMERATION: 17846 needVal = 1; 17847 normVal = 1; 17848 has = 1; 17849 break; 17850 default: 17851 has = 1; 17852 break; 17853 } 17854 } 17855 } 17856 if (normVal) 17857 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17858 if (needVal) 17859 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17860 if (has) 17861 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17862 17863 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17864 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17865 /* 17866 * OPTIMIZE VAL TODO: Some facets need a computed value. 17867 */ 17868 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17869 (prim->builtInType != XML_SCHEMAS_STRING)) { 17870 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17871 } 17872 } 17873 } 17874 17875 static int 17876 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17877 { 17878 17879 17880 /* 17881 * Evaluate the whitespace-facet value. 17882 */ 17883 if (WXS_IS_LIST(type)) { 17884 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17885 return (0); 17886 } else if (WXS_IS_UNION(type)) 17887 return (0); 17888 17889 if (type->facetSet != NULL) { 17890 xmlSchemaFacetLinkPtr lin; 17891 17892 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17893 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17894 switch (lin->facet->whitespace) { 17895 case XML_SCHEMAS_FACET_PRESERVE: 17896 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17897 break; 17898 case XML_SCHEMAS_FACET_REPLACE: 17899 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17900 break; 17901 case XML_SCHEMAS_FACET_COLLAPSE: 17902 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17903 break; 17904 default: 17905 return (-1); 17906 } 17907 return (0); 17908 } 17909 } 17910 } 17911 /* 17912 * For all `atomic` datatypes other than string (and types `derived` 17913 * by `restriction` from it) the value of whiteSpace is fixed to 17914 * collapse 17915 */ 17916 { 17917 xmlSchemaTypePtr anc; 17918 17919 for (anc = type->baseType; anc != NULL && 17920 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17921 anc = anc->baseType) { 17922 17923 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17924 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17925 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17926 17927 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17928 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17929 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17930 17931 } else 17932 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17933 break; 17934 } 17935 } 17936 } 17937 return (0); 17938 } 17939 17940 static int 17941 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17942 xmlSchemaTypePtr type) 17943 { 17944 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17945 return(0); 17946 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17947 return(0); 17948 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17949 17950 if (WXS_IS_LIST(type)) { 17951 /* 17952 * Corresponds to <simpleType><list>... 17953 */ 17954 if (type->subtypes == NULL) { 17955 /* 17956 * This one is really needed, so get out. 17957 */ 17958 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17959 "list type has no item-type assigned"); 17960 return(-1); 17961 } 17962 } else if (WXS_IS_UNION(type)) { 17963 /* 17964 * Corresponds to <simpleType><union>... 17965 */ 17966 if (type->memberTypes == NULL) { 17967 /* 17968 * This one is really needed, so get out. 17969 */ 17970 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17971 "union type has no member-types assigned"); 17972 return(-1); 17973 } 17974 } else { 17975 /* 17976 * Corresponds to <simpleType><restriction>... 17977 */ 17978 if (type->baseType == NULL) { 17979 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17980 "type has no base-type assigned"); 17981 return(-1); 17982 } 17983 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17984 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17985 return(-1); 17986 /* 17987 * Variety 17988 * If the <restriction> alternative is chosen, then the 17989 * {variety} of the {base type definition}. 17990 */ 17991 if (WXS_IS_ATOMIC(type->baseType)) 17992 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17993 else if (WXS_IS_LIST(type->baseType)) { 17994 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17995 /* 17996 * Inherit the itemType. 17997 */ 17998 type->subtypes = type->baseType->subtypes; 17999 } else if (WXS_IS_UNION(type->baseType)) { 18000 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 18001 /* 18002 * NOTE that we won't assign the memberTypes of the base, 18003 * since this will make trouble when freeing them; we will 18004 * use a lookup function to access them instead. 18005 */ 18006 } 18007 } 18008 return(0); 18009 } 18010 18011 #ifdef DEBUG_TYPE 18012 static void 18013 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18014 xmlSchemaTypePtr type) 18015 { 18016 if (type->node != NULL) { 18017 xmlGenericError(xmlGenericErrorContext, 18018 "Type of %s : %s:%d :", name, 18019 type->node->doc->URL, 18020 xmlGetLineNo(type->node)); 18021 } else { 18022 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18023 } 18024 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18025 switch (type->contentType) { 18026 case XML_SCHEMA_CONTENT_SIMPLE: 18027 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18028 break; 18029 case XML_SCHEMA_CONTENT_ELEMENTS: 18030 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18031 break; 18032 case XML_SCHEMA_CONTENT_UNKNOWN: 18033 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18034 break; 18035 case XML_SCHEMA_CONTENT_EMPTY: 18036 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18037 break; 18038 case XML_SCHEMA_CONTENT_MIXED: 18039 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18040 type->subtypes)) 18041 xmlGenericError(xmlGenericErrorContext, 18042 "mixed as emptiable particle\n"); 18043 else 18044 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18045 break; 18046 /* Removed, since not used. */ 18047 /* 18048 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18049 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18050 break; 18051 */ 18052 case XML_SCHEMA_CONTENT_BASIC: 18053 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18054 break; 18055 default: 18056 xmlGenericError(xmlGenericErrorContext, 18057 "not registered !!!\n"); 18058 break; 18059 } 18060 } 18061 } 18062 #endif 18063 18064 /* 18065 * 3.14.6 Constraints on Simple Type Definition Schema Components 18066 */ 18067 static int 18068 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18069 xmlSchemaTypePtr type) 18070 { 18071 int res, olderrs = pctxt->nberrors; 18072 18073 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18074 return(-1); 18075 18076 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18077 return(0); 18078 18079 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18080 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18081 18082 if (type->baseType == NULL) { 18083 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18084 "missing baseType"); 18085 goto exit_failure; 18086 } 18087 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18088 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18089 /* 18090 * If a member type of a union is a union itself, we need to substitute 18091 * that member type for its member types. 18092 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18093 * types in WXS 1.1. 18094 */ 18095 if ((type->memberTypes != NULL) && 18096 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18097 return(-1); 18098 /* 18099 * SPEC src-simple-type 1 18100 * "The corresponding simple type definition, if any, must satisfy 18101 * the conditions set out in Constraints on Simple Type Definition 18102 * Schema Components ($3.14.6)." 18103 */ 18104 /* 18105 * Schema Component Constraint: Simple Type Definition Properties Correct 18106 * (st-props-correct) 18107 */ 18108 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18109 HFAILURE HERROR 18110 /* 18111 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18112 * (cos-st-restricts) 18113 */ 18114 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18115 HFAILURE HERROR 18116 /* 18117 * TODO: Removed the error report, since it got annoying to get an 18118 * extra error report, if anything failed until now. 18119 * Enable this if needed. 18120 * 18121 * xmlSchemaPErr(ctxt, type->node, 18122 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18123 * "Simple type '%s' does not satisfy the constraints " 18124 * "on simple type definitions.\n", 18125 * type->name, NULL); 18126 */ 18127 /* 18128 * Schema Component Constraint: Simple Type Restriction (Facets) 18129 * (st-restrict-facets) 18130 */ 18131 res = xmlSchemaCheckFacetValues(type, pctxt); 18132 HFAILURE HERROR 18133 if ((type->facetSet != NULL) || 18134 (type->baseType->facetSet != NULL)) { 18135 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18136 HFAILURE HERROR 18137 } 18138 /* 18139 * Whitespace value. 18140 */ 18141 res = xmlSchemaTypeFixupWhitespace(type); 18142 HFAILURE HERROR 18143 xmlSchemaTypeFixupOptimFacets(type); 18144 18145 exit_error: 18146 #ifdef DEBUG_TYPE 18147 xmlSchemaDebugFixedType(pctxt, type); 18148 #endif 18149 if (olderrs != pctxt->nberrors) 18150 return(pctxt->err); 18151 return(0); 18152 18153 exit_failure: 18154 #ifdef DEBUG_TYPE 18155 xmlSchemaDebugFixedType(pctxt, type); 18156 #endif 18157 return(-1); 18158 } 18159 18160 static int 18161 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18162 xmlSchemaTypePtr type) 18163 { 18164 int res = 0, olderrs = pctxt->nberrors; 18165 xmlSchemaTypePtr baseType = type->baseType; 18166 18167 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18168 return(0); 18169 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18170 if (baseType == NULL) { 18171 PERROR_INT("xmlSchemaFixupComplexType", 18172 "missing baseType"); 18173 goto exit_failure; 18174 } 18175 /* 18176 * Fixup the base type. 18177 */ 18178 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18179 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18180 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18181 /* 18182 * Skip fixup if the base type is invalid. 18183 * TODO: Generate a warning! 18184 */ 18185 return(0); 18186 } 18187 /* 18188 * This basically checks if the base type can be derived. 18189 */ 18190 res = xmlSchemaCheckSRCCT(pctxt, type); 18191 HFAILURE HERROR 18192 /* 18193 * Fixup the content type. 18194 */ 18195 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18196 /* 18197 * Corresponds to <complexType><simpleContent>... 18198 */ 18199 if ((WXS_IS_COMPLEX(baseType)) && 18200 (baseType->contentTypeDef != NULL) && 18201 (WXS_IS_RESTRICTION(type))) { 18202 xmlSchemaTypePtr contentBase, content; 18203 #ifdef ENABLE_NAMED_LOCALS 18204 char buf[30]; 18205 const xmlChar *tmpname; 18206 #endif 18207 /* 18208 * SPEC (1) If <restriction> + base type is <complexType>, 18209 * "whose own {content type} is a simple type..." 18210 */ 18211 if (type->contentTypeDef != NULL) { 18212 /* 18213 * SPEC (1.1) "the simple type definition corresponding to the 18214 * <simpleType> among the [children] of <restriction> if there 18215 * is one;" 18216 * Note that this "<simpleType> among the [children]" was put 18217 * into ->contentTypeDef during parsing. 18218 */ 18219 contentBase = type->contentTypeDef; 18220 type->contentTypeDef = NULL; 18221 } else { 18222 /* 18223 * (1.2) "...otherwise (<restriction> has no <simpleType> 18224 * among its [children]), the simple type definition which 18225 * is the {content type} of the ... base type." 18226 */ 18227 contentBase = baseType->contentTypeDef; 18228 } 18229 /* 18230 * SPEC 18231 * "... a simple type definition which restricts the simple 18232 * type definition identified in clause 1.1 or clause 1.2 18233 * with a set of facet components" 18234 * 18235 * Create the anonymous simple type, which will be the content 18236 * type of the complex type. 18237 */ 18238 #ifdef ENABLE_NAMED_LOCALS 18239 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18240 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18241 content = xmlSchemaAddType(pctxt, pctxt->schema, 18242 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18243 type->node, 0); 18244 #else 18245 content = xmlSchemaAddType(pctxt, pctxt->schema, 18246 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18247 type->node, 0); 18248 #endif 18249 if (content == NULL) 18250 goto exit_failure; 18251 /* 18252 * We will use the same node as for the <complexType> 18253 * to have it somehow anchored in the schema doc. 18254 */ 18255 content->type = XML_SCHEMA_TYPE_SIMPLE; 18256 content->baseType = contentBase; 18257 /* 18258 * Move the facets, previously anchored on the 18259 * complexType during parsing. 18260 */ 18261 content->facets = type->facets; 18262 type->facets = NULL; 18263 content->facetSet = type->facetSet; 18264 type->facetSet = NULL; 18265 18266 type->contentTypeDef = content; 18267 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18268 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18269 /* 18270 * Fixup the newly created type. We don't need to check 18271 * for circularity here. 18272 */ 18273 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18274 HFAILURE HERROR 18275 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18276 HFAILURE HERROR 18277 18278 } else if ((WXS_IS_COMPLEX(baseType)) && 18279 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18280 (WXS_IS_RESTRICTION(type))) { 18281 /* 18282 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18283 * an emptiable particle, then a simple type definition which 18284 * restricts the <restriction>'s <simpleType> child. 18285 */ 18286 if ((type->contentTypeDef == NULL) || 18287 (type->contentTypeDef->baseType == NULL)) { 18288 /* 18289 * TODO: Check if this ever happens. 18290 */ 18291 xmlSchemaPCustomErr(pctxt, 18292 XML_SCHEMAP_INTERNAL, 18293 WXS_BASIC_CAST type, NULL, 18294 "Internal error: xmlSchemaTypeFixup, " 18295 "complex type '%s': the <simpleContent><restriction> " 18296 "is missing a <simpleType> child, but was not catched " 18297 "by xmlSchemaCheckSRCCT()", type->name); 18298 goto exit_failure; 18299 } 18300 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18301 /* 18302 * SPEC (3) If <extension> + base is <complexType> with 18303 * <simpleType> content, "...then the {content type} of that 18304 * complex type definition" 18305 */ 18306 if (baseType->contentTypeDef == NULL) { 18307 /* 18308 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18309 * should have catched this already. 18310 */ 18311 xmlSchemaPCustomErr(pctxt, 18312 XML_SCHEMAP_INTERNAL, 18313 WXS_BASIC_CAST type, NULL, 18314 "Internal error: xmlSchemaTypeFixup, " 18315 "complex type '%s': the <extension>ed base type is " 18316 "a complex type with no simple content type", 18317 type->name); 18318 goto exit_failure; 18319 } 18320 type->contentTypeDef = baseType->contentTypeDef; 18321 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18322 /* 18323 * SPEC (4) <extension> + base is <simpleType> 18324 * "... then that simple type definition" 18325 */ 18326 type->contentTypeDef = baseType; 18327 } else { 18328 /* 18329 * TODO: Check if this ever happens. 18330 */ 18331 xmlSchemaPCustomErr(pctxt, 18332 XML_SCHEMAP_INTERNAL, 18333 WXS_BASIC_CAST type, NULL, 18334 "Internal error: xmlSchemaTypeFixup, " 18335 "complex type '%s' with <simpleContent>: unhandled " 18336 "derivation case", type->name); 18337 goto exit_failure; 18338 } 18339 } else { 18340 int dummySequence = 0; 18341 xmlSchemaParticlePtr particle = 18342 (xmlSchemaParticlePtr) type->subtypes; 18343 /* 18344 * Corresponds to <complexType><complexContent>... 18345 * 18346 * NOTE that the effective mixed was already set during parsing of 18347 * <complexType> and <complexContent>; its flag value is 18348 * XML_SCHEMAS_TYPE_MIXED. 18349 * 18350 * Compute the "effective content": 18351 * (2.1.1) + (2.1.2) + (2.1.3) 18352 */ 18353 if ((particle == NULL) || 18354 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18355 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18356 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18357 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18358 (particle->minOccurs == 0))) && 18359 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18360 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18361 /* 18362 * SPEC (2.1.4) "If the `effective mixed` is true, then 18363 * a particle whose properties are as follows:..." 18364 * 18365 * Empty sequence model group with 18366 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18367 * NOTE that we sill assign it the <complexType> node to 18368 * somehow anchor it in the doc. 18369 */ 18370 if ((particle == NULL) || 18371 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18372 /* 18373 * Create the particle. 18374 */ 18375 particle = xmlSchemaAddParticle(pctxt, 18376 type->node, 1, 1); 18377 if (particle == NULL) 18378 goto exit_failure; 18379 /* 18380 * Create the model group. 18381 */ /* URGENT TODO: avoid adding to pending items. */ 18382 particle->children = (xmlSchemaTreeItemPtr) 18383 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18384 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18385 if (particle->children == NULL) 18386 goto exit_failure; 18387 18388 type->subtypes = (xmlSchemaTypePtr) particle; 18389 } 18390 dummySequence = 1; 18391 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18392 } else { 18393 /* 18394 * SPEC (2.1.5) "otherwise empty" 18395 */ 18396 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18397 } 18398 } else { 18399 /* 18400 * SPEC (2.2) "otherwise the particle corresponding to the 18401 * <all>, <choice>, <group> or <sequence> among the 18402 * [children]." 18403 */ 18404 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18405 } 18406 /* 18407 * Compute the "content type". 18408 */ 18409 if (WXS_IS_RESTRICTION(type)) { 18410 /* 18411 * SPEC (3.1) "If <restriction>..." 18412 * (3.1.1) + (3.1.2) */ 18413 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18414 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18415 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18416 } 18417 } else { 18418 /* 18419 * SPEC (3.2) "If <extension>..." 18420 */ 18421 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18422 /* 18423 * SPEC (3.2.1) 18424 * "If the `effective content` is empty, then the 18425 * {content type} of the [...] base ..." 18426 */ 18427 type->contentType = baseType->contentType; 18428 type->subtypes = baseType->subtypes; 18429 /* 18430 * Fixes bug #347316: 18431 * This is the case when the base type has a simple 18432 * type definition as content. 18433 */ 18434 type->contentTypeDef = baseType->contentTypeDef; 18435 /* 18436 * NOTE that the effective mixed is ignored here. 18437 */ 18438 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18439 /* 18440 * SPEC (3.2.2) 18441 */ 18442 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18443 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18444 } else { 18445 /* 18446 * SPEC (3.2.3) 18447 */ 18448 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18449 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18450 /* 18451 * "A model group whose {compositor} is sequence and whose 18452 * {particles} are..." 18453 */ 18454 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18455 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18456 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18457 XML_SCHEMA_TYPE_ALL)) 18458 { 18459 /* 18460 * SPEC cos-all-limited (1) 18461 */ 18462 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18463 /* TODO: error code */ 18464 XML_SCHEMAP_COS_ALL_LIMITED, 18465 WXS_ITEM_NODE(type), NULL, 18466 "The type has an 'all' model group in its " 18467 "{content type} and thus cannot be derived from " 18468 "a non-empty type, since this would produce a " 18469 "'sequence' model group containing the 'all' " 18470 "model group; 'all' model groups are not " 18471 "allowed to appear inside other model groups", 18472 NULL, NULL); 18473 18474 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18475 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18476 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18477 XML_SCHEMA_TYPE_ALL)) 18478 { 18479 /* 18480 * SPEC cos-all-limited (1) 18481 */ 18482 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18483 /* TODO: error code */ 18484 XML_SCHEMAP_COS_ALL_LIMITED, 18485 WXS_ITEM_NODE(type), NULL, 18486 "A type cannot be derived by extension from a type " 18487 "which has an 'all' model group in its " 18488 "{content type}, since this would produce a " 18489 "'sequence' model group containing the 'all' " 18490 "model group; 'all' model groups are not " 18491 "allowed to appear inside other model groups", 18492 NULL, NULL); 18493 18494 } else if (! dummySequence) { 18495 xmlSchemaTreeItemPtr effectiveContent = 18496 (xmlSchemaTreeItemPtr) type->subtypes; 18497 /* 18498 * Create the particle. 18499 */ 18500 particle = xmlSchemaAddParticle(pctxt, 18501 type->node, 1, 1); 18502 if (particle == NULL) 18503 goto exit_failure; 18504 /* 18505 * Create the "sequence" model group. 18506 */ 18507 particle->children = (xmlSchemaTreeItemPtr) 18508 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18509 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18510 if (particle->children == NULL) 18511 goto exit_failure; 18512 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18513 /* 18514 * SPEC "the particle of the {content type} of 18515 * the ... base ..." 18516 * Create a duplicate of the base type's particle 18517 * and assign its "term" to it. 18518 */ 18519 particle->children->children = 18520 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18521 type->node, 18522 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18523 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18524 if (particle->children->children == NULL) 18525 goto exit_failure; 18526 particle = (xmlSchemaParticlePtr) 18527 particle->children->children; 18528 particle->children = 18529 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18530 /* 18531 * SPEC "followed by the `effective content`." 18532 */ 18533 particle->next = effectiveContent; 18534 /* 18535 * This all will result in: 18536 * new-particle 18537 * --> new-sequence( 18538 * new-particle 18539 * --> base-model, 18540 * this-particle 18541 * --> this-model 18542 * ) 18543 */ 18544 } else { 18545 /* 18546 * This is the case when there is already an empty 18547 * <sequence> with minOccurs==maxOccurs==1. 18548 * Just add the base types's content type. 18549 * NOTE that, although we miss to add an intermediate 18550 * <sequence>, this should produce no difference to 18551 * neither the regex compilation of the content model, 18552 * nor to the complex type contraints. 18553 */ 18554 particle->children->children = 18555 (xmlSchemaTreeItemPtr) baseType->subtypes; 18556 } 18557 } 18558 } 18559 } 18560 /* 18561 * Now fixup attribute uses: 18562 * - expand attr. group references 18563 * - intersect attribute wildcards 18564 * - inherit attribute uses of the base type 18565 * - inherit or union attr. wildcards if extending 18566 * - apply attr. use prohibitions if restricting 18567 */ 18568 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18569 HFAILURE HERROR 18570 /* 18571 * Apply the complex type component constraints; this will not 18572 * check attributes, since this is done in 18573 * xmlSchemaFixupTypeAttributeUses(). 18574 */ 18575 res = xmlSchemaCheckCTComponent(pctxt, type); 18576 HFAILURE HERROR 18577 18578 #ifdef DEBUG_TYPE 18579 xmlSchemaDebugFixedType(pctxt, type); 18580 #endif 18581 if (olderrs != pctxt->nberrors) 18582 return(pctxt->err); 18583 else 18584 return(0); 18585 18586 exit_error: 18587 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18588 #ifdef DEBUG_TYPE 18589 xmlSchemaDebugFixedType(pctxt, type); 18590 #endif 18591 return(pctxt->err); 18592 18593 exit_failure: 18594 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18595 #ifdef DEBUG_TYPE 18596 xmlSchemaDebugFixedType(pctxt, type); 18597 #endif 18598 return(-1); 18599 } 18600 18601 18602 /** 18603 * xmlSchemaTypeFixup: 18604 * @typeDecl: the schema type definition 18605 * @ctxt: the schema parser context 18606 * 18607 * Fixes the content model of the type. 18608 * URGENT TODO: We need an int result! 18609 */ 18610 static int 18611 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18612 xmlSchemaAbstractCtxtPtr actxt) 18613 { 18614 if (type == NULL) 18615 return(0); 18616 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18617 AERROR_INT("xmlSchemaTypeFixup", 18618 "this function needs a parser context"); 18619 return(-1); 18620 } 18621 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18622 return(0); 18623 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18624 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18625 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18626 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18627 return(0); 18628 } 18629 18630 /** 18631 * xmlSchemaCheckFacet: 18632 * @facet: the facet 18633 * @typeDecl: the schema type definition 18634 * @pctxt: the schema parser context or NULL 18635 * @name: the optional name of the type 18636 * 18637 * Checks and computes the values of facets. 18638 * 18639 * Returns 0 if valid, a positive error code if not valid and 18640 * -1 in case of an internal or API error. 18641 */ 18642 int 18643 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18644 xmlSchemaTypePtr typeDecl, 18645 xmlSchemaParserCtxtPtr pctxt, 18646 const xmlChar * name ATTRIBUTE_UNUSED) 18647 { 18648 int ret = 0, ctxtGiven; 18649 18650 if ((facet == NULL) || (typeDecl == NULL)) 18651 return(-1); 18652 /* 18653 * TODO: will the parser context be given if used from 18654 * the relaxNG module? 18655 */ 18656 if (pctxt == NULL) 18657 ctxtGiven = 0; 18658 else 18659 ctxtGiven = 1; 18660 18661 switch (facet->type) { 18662 case XML_SCHEMA_FACET_MININCLUSIVE: 18663 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18664 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18665 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18666 case XML_SCHEMA_FACET_ENUMERATION: { 18667 /* 18668 * Okay we need to validate the value 18669 * at that point. 18670 */ 18671 xmlSchemaTypePtr base; 18672 18673 /* 4.3.5.5 Constraints on enumeration Schema Components 18674 * Schema Component Constraint: enumeration valid restriction 18675 * It is an `error` if any member of {value} is not in the 18676 * `value space` of {base type definition}. 18677 * 18678 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18679 * The value `must` be in the 18680 * `value space` of the `base type`. 18681 */ 18682 /* 18683 * This function is intended to deliver a compiled value 18684 * on the facet. In this implementation of XML Schemata the 18685 * type holding a facet, won't be a built-in type. 18686 * Thus to ensure that other API 18687 * calls (relaxng) do work, if the given type is a built-in 18688 * type, we will assume that the given built-in type *is 18689 * already* the base type. 18690 */ 18691 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18692 base = typeDecl->baseType; 18693 if (base == NULL) { 18694 PERROR_INT("xmlSchemaCheckFacet", 18695 "a type user derived type has no base type"); 18696 return (-1); 18697 } 18698 } else 18699 base = typeDecl; 18700 18701 if (! ctxtGiven) { 18702 /* 18703 * A context is needed if called from RelaxNG. 18704 */ 18705 pctxt = xmlSchemaNewParserCtxt("*"); 18706 if (pctxt == NULL) 18707 return (-1); 18708 } 18709 /* 18710 * NOTE: This call does not check the content nodes, 18711 * since they are not available: 18712 * facet->node is just the node holding the facet 18713 * definition, *not* the attribute holding the *value* 18714 * of the facet. 18715 */ 18716 ret = xmlSchemaVCheckCVCSimpleType( 18717 ACTXT_CAST pctxt, facet->node, base, 18718 facet->value, &(facet->val), 1, 1, 0); 18719 if (ret != 0) { 18720 if (ret < 0) { 18721 /* No error message for RelaxNG. */ 18722 if (ctxtGiven) { 18723 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18724 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18725 "Internal error: xmlSchemaCheckFacet, " 18726 "failed to validate the value '%s' of the " 18727 "facet '%s' against the base type", 18728 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18729 } 18730 goto internal_error; 18731 } 18732 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18733 /* No error message for RelaxNG. */ 18734 if (ctxtGiven) { 18735 xmlChar *str = NULL; 18736 18737 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18738 ret, facet->node, WXS_BASIC_CAST facet, 18739 "The value '%s' of the facet does not validate " 18740 "against the base type '%s'", 18741 facet->value, 18742 xmlSchemaFormatQName(&str, 18743 base->targetNamespace, base->name)); 18744 FREE_AND_NULL(str); 18745 } 18746 goto exit; 18747 } else if (facet->val == NULL) { 18748 if (ctxtGiven) { 18749 PERROR_INT("xmlSchemaCheckFacet", 18750 "value was not computed"); 18751 } 18752 TODO 18753 } 18754 break; 18755 } 18756 case XML_SCHEMA_FACET_PATTERN: 18757 facet->regexp = xmlRegexpCompile(facet->value); 18758 if (facet->regexp == NULL) { 18759 ret = XML_SCHEMAP_REGEXP_INVALID; 18760 /* No error message for RelaxNG. */ 18761 if (ctxtGiven) { 18762 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18763 ret, facet->node, WXS_BASIC_CAST typeDecl, 18764 "The value '%s' of the facet 'pattern' is not a " 18765 "valid regular expression", 18766 facet->value, NULL); 18767 } 18768 } 18769 break; 18770 case XML_SCHEMA_FACET_TOTALDIGITS: 18771 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18772 case XML_SCHEMA_FACET_LENGTH: 18773 case XML_SCHEMA_FACET_MAXLENGTH: 18774 case XML_SCHEMA_FACET_MINLENGTH: 18775 18776 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18777 ret = xmlSchemaValidatePredefinedType( 18778 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18779 facet->value, &(facet->val)); 18780 } else { 18781 ret = xmlSchemaValidatePredefinedType( 18782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18783 facet->value, &(facet->val)); 18784 } 18785 if (ret != 0) { 18786 if (ret < 0) { 18787 /* No error message for RelaxNG. */ 18788 if (ctxtGiven) { 18789 PERROR_INT("xmlSchemaCheckFacet", 18790 "validating facet value"); 18791 } 18792 goto internal_error; 18793 } 18794 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18795 /* No error message for RelaxNG. */ 18796 if (ctxtGiven) { 18797 /* error code */ 18798 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18799 ret, facet->node, WXS_BASIC_CAST typeDecl, 18800 "The value '%s' of the facet '%s' is not a valid '%s'", 18801 facet->value, 18802 xmlSchemaFacetTypeToString(facet->type), 18803 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18804 BAD_CAST "nonNegativeInteger" : 18805 BAD_CAST "positiveInteger", 18806 NULL); 18807 } 18808 } 18809 break; 18810 18811 case XML_SCHEMA_FACET_WHITESPACE:{ 18812 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18813 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18814 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18815 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18816 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18817 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18818 } else { 18819 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18820 /* No error message for RelaxNG. */ 18821 if (ctxtGiven) { 18822 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18823 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18824 ret, facet->node, WXS_BASIC_CAST typeDecl, 18825 "The value '%s' of the facet 'whitespace' is not " 18826 "valid", facet->value, NULL); 18827 } 18828 } 18829 } 18830 default: 18831 break; 18832 } 18833 exit: 18834 if ((! ctxtGiven) && (pctxt != NULL)) 18835 xmlSchemaFreeParserCtxt(pctxt); 18836 return (ret); 18837 internal_error: 18838 if ((! ctxtGiven) && (pctxt != NULL)) 18839 xmlSchemaFreeParserCtxt(pctxt); 18840 return (-1); 18841 } 18842 18843 /** 18844 * xmlSchemaCheckFacetValues: 18845 * @typeDecl: the schema type definition 18846 * @ctxt: the schema parser context 18847 * 18848 * Checks the default values types, especially for facets 18849 */ 18850 static int 18851 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18852 xmlSchemaParserCtxtPtr pctxt) 18853 { 18854 int res, olderrs = pctxt->nberrors; 18855 const xmlChar *name = typeDecl->name; 18856 /* 18857 * NOTE: It is intended to use the facets list, instead 18858 * of facetSet. 18859 */ 18860 if (typeDecl->facets != NULL) { 18861 xmlSchemaFacetPtr facet = typeDecl->facets; 18862 18863 /* 18864 * Temporarily assign the "schema" to the validation context 18865 * of the parser context. This is needed for NOTATION validation. 18866 */ 18867 if (pctxt->vctxt == NULL) { 18868 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18869 return(-1); 18870 } 18871 pctxt->vctxt->schema = pctxt->schema; 18872 while (facet != NULL) { 18873 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18874 HFAILURE 18875 facet = facet->next; 18876 } 18877 pctxt->vctxt->schema = NULL; 18878 } 18879 if (olderrs != pctxt->nberrors) 18880 return(pctxt->err); 18881 return(0); 18882 exit_failure: 18883 return(-1); 18884 } 18885 18886 /** 18887 * xmlSchemaGetCircModelGrDefRef: 18888 * @ctxtMGroup: the searched model group 18889 * @selfMGroup: the second searched model group 18890 * @particle: the first particle 18891 * 18892 * This one is intended to be used by 18893 * xmlSchemaCheckGroupDefCircular only. 18894 * 18895 * Returns the particle with the circular model group definition reference, 18896 * otherwise NULL. 18897 */ 18898 static xmlSchemaTreeItemPtr 18899 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18900 xmlSchemaTreeItemPtr particle) 18901 { 18902 xmlSchemaTreeItemPtr circ = NULL; 18903 xmlSchemaTreeItemPtr term; 18904 xmlSchemaModelGroupDefPtr gdef; 18905 18906 for (; particle != NULL; particle = particle->next) { 18907 term = particle->children; 18908 if (term == NULL) 18909 continue; 18910 switch (term->type) { 18911 case XML_SCHEMA_TYPE_GROUP: 18912 gdef = (xmlSchemaModelGroupDefPtr) term; 18913 if (gdef == groupDef) 18914 return (particle); 18915 /* 18916 * Mark this model group definition to avoid infinite 18917 * recursion on circular references not yet examined. 18918 */ 18919 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18920 continue; 18921 if (gdef->children != NULL) { 18922 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18923 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18924 gdef->children->children); 18925 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18926 if (circ != NULL) 18927 return (circ); 18928 } 18929 break; 18930 case XML_SCHEMA_TYPE_SEQUENCE: 18931 case XML_SCHEMA_TYPE_CHOICE: 18932 case XML_SCHEMA_TYPE_ALL: 18933 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18934 if (circ != NULL) 18935 return (circ); 18936 break; 18937 default: 18938 break; 18939 } 18940 } 18941 return (NULL); 18942 } 18943 18944 /** 18945 * xmlSchemaCheckGroupDefCircular: 18946 * @item: the model group definition 18947 * @ctxt: the parser context 18948 * @name: the name 18949 * 18950 * Checks for circular references to model group definitions. 18951 */ 18952 static void 18953 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18954 xmlSchemaParserCtxtPtr ctxt) 18955 { 18956 /* 18957 * Schema Component Constraint: Model Group Correct 18958 * 2 Circular groups are disallowed. That is, within the {particles} 18959 * of a group there must not be at any depth a particle whose {term} 18960 * is the group itself. 18961 */ 18962 if ((item == NULL) || 18963 (item->type != XML_SCHEMA_TYPE_GROUP) || 18964 (item->children == NULL)) 18965 return; 18966 { 18967 xmlSchemaTreeItemPtr circ; 18968 18969 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18970 if (circ != NULL) { 18971 xmlChar *str = NULL; 18972 /* 18973 * TODO: The error report is not adequate: this constraint 18974 * is defined for model groups but not definitions, but since 18975 * there cannot be any circular model groups without a model group 18976 * definition (if not using a construction API), we check those 18977 * defintions only. 18978 */ 18979 xmlSchemaPCustomErr(ctxt, 18980 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18981 NULL, WXS_ITEM_NODE(circ), 18982 "Circular reference to the model group definition '%s' " 18983 "defined", xmlSchemaFormatQName(&str, 18984 item->targetNamespace, item->name)); 18985 FREE_AND_NULL(str) 18986 /* 18987 * NOTE: We will cut the reference to avoid further 18988 * confusion of the processor. This is a fatal error. 18989 */ 18990 circ->children = NULL; 18991 } 18992 } 18993 } 18994 18995 /** 18996 * xmlSchemaModelGroupToModelGroupDefFixup: 18997 * @ctxt: the parser context 18998 * @mg: the model group 18999 * 19000 * Assigns the model group of model group definitions to the "term" 19001 * of the referencing particle. 19002 * In xmlSchemaResolveModelGroupParticleReferences the model group 19003 * definitions were assigned to the "term", since needed for the 19004 * circularity check. 19005 * 19006 * Schema Component Constraint: 19007 * All Group Limited (cos-all-limited) (1.2) 19008 */ 19009 static void 19010 xmlSchemaModelGroupToModelGroupDefFixup( 19011 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 19012 xmlSchemaModelGroupPtr mg) 19013 { 19014 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19015 19016 while (particle != NULL) { 19017 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19018 ((WXS_PARTICLE_TERM(particle))->type != 19019 XML_SCHEMA_TYPE_GROUP)) 19020 { 19021 particle = WXS_PTC_CAST particle->next; 19022 continue; 19023 } 19024 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19025 /* 19026 * TODO: Remove the particle. 19027 */ 19028 WXS_PARTICLE_TERM(particle) = NULL; 19029 particle = WXS_PTC_CAST particle->next; 19030 continue; 19031 } 19032 /* 19033 * Assign the model group to the {term} of the particle. 19034 */ 19035 WXS_PARTICLE_TERM(particle) = 19036 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19037 19038 particle = WXS_PTC_CAST particle->next; 19039 } 19040 } 19041 19042 /** 19043 * xmlSchemaCheckAttrGroupCircularRecur: 19044 * @ctxtGr: the searched attribute group 19045 * @attr: the current attribute list to be processed 19046 * 19047 * This one is intended to be used by 19048 * xmlSchemaCheckAttrGroupCircular only. 19049 * 19050 * Returns the circular attribute grou reference, otherwise NULL. 19051 */ 19052 static xmlSchemaQNameRefPtr 19053 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19054 xmlSchemaItemListPtr list) 19055 { 19056 xmlSchemaAttributeGroupPtr gr; 19057 xmlSchemaQNameRefPtr ref, circ; 19058 int i; 19059 /* 19060 * We will search for an attribute group reference which 19061 * references the context attribute group. 19062 */ 19063 for (i = 0; i < list->nbItems; i++) { 19064 ref = list->items[i]; 19065 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19066 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19067 (ref->item != NULL)) 19068 { 19069 gr = WXS_ATTR_GROUP_CAST ref->item; 19070 if (gr == ctxtGr) 19071 return(ref); 19072 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19073 continue; 19074 /* 19075 * Mark as visited to avoid infinite recursion on 19076 * circular references not yet examined. 19077 */ 19078 if ((gr->attrUses) && 19079 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19080 { 19081 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19082 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19083 (xmlSchemaItemListPtr) gr->attrUses); 19084 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19085 if (circ != NULL) 19086 return (circ); 19087 } 19088 19089 } 19090 } 19091 return (NULL); 19092 } 19093 19094 /** 19095 * xmlSchemaCheckAttrGroupCircular: 19096 * attrGr: the attribute group definition 19097 * @ctxt: the parser context 19098 * @name: the name 19099 * 19100 * Checks for circular references of attribute groups. 19101 */ 19102 static int 19103 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19104 xmlSchemaParserCtxtPtr ctxt) 19105 { 19106 /* 19107 * Schema Representation Constraint: 19108 * Attribute Group Definition Representation OK 19109 * 3 Circular group reference is disallowed outside <redefine>. 19110 * That is, unless this element information item's parent is 19111 * <redefine>, then among the [children], if any, there must 19112 * not be an <attributeGroup> with ref [attribute] which resolves 19113 * to the component corresponding to this <attributeGroup>. Indirect 19114 * circularity is also ruled out. That is, when QName resolution 19115 * (Schema Document) ($3.15.3) is applied to a `QName` arising from 19116 * any <attributeGroup>s with a ref [attribute] among the [children], 19117 * it must not be the case that a `QName` is encountered at any depth 19118 * which resolves to the component corresponding to this <attributeGroup>. 19119 */ 19120 if (attrGr->attrUses == NULL) 19121 return(0); 19122 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19123 return(0); 19124 else { 19125 xmlSchemaQNameRefPtr circ; 19126 19127 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19128 (xmlSchemaItemListPtr) attrGr->attrUses); 19129 if (circ != NULL) { 19130 xmlChar *str = NULL; 19131 /* 19132 * TODO: Report the referenced attr group as QName. 19133 */ 19134 xmlSchemaPCustomErr(ctxt, 19135 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19136 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19137 "Circular reference to the attribute group '%s' " 19138 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19139 FREE_AND_NULL(str); 19140 /* 19141 * NOTE: We will cut the reference to avoid further 19142 * confusion of the processor. 19143 * BADSPEC TODO: The spec should define how to process in this case. 19144 */ 19145 circ->item = NULL; 19146 return(ctxt->err); 19147 } 19148 } 19149 return(0); 19150 } 19151 19152 static int 19153 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19154 xmlSchemaAttributeGroupPtr attrGr); 19155 19156 /** 19157 * xmlSchemaExpandAttributeGroupRefs: 19158 * @pctxt: the parser context 19159 * @node: the node of the component holding the attribute uses 19160 * @completeWild: the intersected wildcard to be returned 19161 * @list: the attribute uses 19162 * 19163 * Substitutes contained attribute group references 19164 * for their attribute uses. Wilcards are intersected. 19165 * Attribute use prohibitions are removed from the list 19166 * and returned via the @prohibs list. 19167 * Pointlessness of attr. prohibs, if a matching attr. decl 19168 * is existent a well, are checked. 19169 */ 19170 static int 19171 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19172 xmlSchemaBasicItemPtr item, 19173 xmlSchemaWildcardPtr *completeWild, 19174 xmlSchemaItemListPtr list, 19175 xmlSchemaItemListPtr prohibs) 19176 { 19177 xmlSchemaAttributeGroupPtr gr; 19178 xmlSchemaAttributeUsePtr use; 19179 xmlSchemaItemListPtr sublist; 19180 int i, j; 19181 int created = (*completeWild == NULL) ? 0 : 1; 19182 19183 if (prohibs) 19184 prohibs->nbItems = 0; 19185 19186 for (i = 0; i < list->nbItems; i++) { 19187 use = list->items[i]; 19188 19189 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19190 if (prohibs == NULL) { 19191 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19192 "unexpected attr prohibition found"); 19193 return(-1); 19194 } 19195 /* 19196 * Remove from attribute uses. 19197 */ 19198 if (xmlSchemaItemListRemove(list, i) == -1) 19199 return(-1); 19200 i--; 19201 /* 19202 * Note that duplicate prohibitions were already 19203 * handled at parsing time. 19204 */ 19205 /* 19206 * Add to list of prohibitions. 19207 */ 19208 xmlSchemaItemListAddSize(prohibs, 2, use); 19209 continue; 19210 } 19211 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19212 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19213 { 19214 if ((WXS_QNAME_CAST use)->item == NULL) 19215 return(-1); 19216 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19217 /* 19218 * Expand the referenced attr. group. 19219 * TODO: remove this, this is done in a previous step, so 19220 * already done here. 19221 */ 19222 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19223 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19224 return(-1); 19225 } 19226 /* 19227 * Build the 'complete' wildcard; i.e. intersect multiple 19228 * wildcards. 19229 */ 19230 if (gr->attributeWildcard != NULL) { 19231 if (*completeWild == NULL) { 19232 *completeWild = gr->attributeWildcard; 19233 } else { 19234 if (! created) { 19235 xmlSchemaWildcardPtr tmpWild; 19236 19237 /* 19238 * Copy the first encountered wildcard as context, 19239 * except for the annotation. 19240 * 19241 * Although the complete wildcard might not correspond 19242 * to any node in the schema, we will anchor it on 19243 * the node of the owner component. 19244 */ 19245 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19246 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19247 WXS_ITEM_NODE(item)); 19248 if (tmpWild == NULL) 19249 return(-1); 19250 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19251 tmpWild, *completeWild) == -1) 19252 return (-1); 19253 tmpWild->processContents = (*completeWild)->processContents; 19254 *completeWild = tmpWild; 19255 created = 1; 19256 } 19257 19258 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19259 gr->attributeWildcard) == -1) 19260 return(-1); 19261 } 19262 } 19263 /* 19264 * Just remove the reference if the referenced group does not 19265 * contain any attribute uses. 19266 */ 19267 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19268 if ((sublist == NULL) || sublist->nbItems == 0) { 19269 if (xmlSchemaItemListRemove(list, i) == -1) 19270 return(-1); 19271 i--; 19272 continue; 19273 } 19274 /* 19275 * Add the attribute uses. 19276 */ 19277 list->items[i] = sublist->items[0]; 19278 if (sublist->nbItems != 1) { 19279 for (j = 1; j < sublist->nbItems; j++) { 19280 i++; 19281 if (xmlSchemaItemListInsert(list, 19282 sublist->items[j], i) == -1) 19283 return(-1); 19284 } 19285 } 19286 } 19287 19288 } 19289 /* 19290 * Handle pointless prohibitions of declared attributes. 19291 */ 19292 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19293 xmlSchemaAttributeUseProhibPtr prohib; 19294 19295 for (i = prohibs->nbItems -1; i >= 0; i--) { 19296 prohib = prohibs->items[i]; 19297 for (j = 0; j < list->nbItems; j++) { 19298 use = list->items[j]; 19299 19300 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19301 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19302 { 19303 xmlChar *str = NULL; 19304 19305 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19306 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19307 prohib->node, NULL, 19308 "Skipping pointless attribute use prohibition " 19309 "'%s', since a corresponding attribute use " 19310 "exists already in the type definition", 19311 xmlSchemaFormatQName(&str, 19312 prohib->targetNamespace, prohib->name), 19313 NULL, NULL); 19314 FREE_AND_NULL(str); 19315 /* 19316 * Remove the prohibition. 19317 */ 19318 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19319 return(-1); 19320 break; 19321 } 19322 } 19323 } 19324 } 19325 return(0); 19326 } 19327 19328 /** 19329 * xmlSchemaAttributeGroupExpandRefs: 19330 * @pctxt: the parser context 19331 * @attrGr: the attribute group definition 19332 * 19333 * Computation of: 19334 * {attribute uses} property 19335 * {attribute wildcard} property 19336 * 19337 * Substitutes contained attribute group references 19338 * for their attribute uses. Wilcards are intersected. 19339 */ 19340 static int 19341 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19342 xmlSchemaAttributeGroupPtr attrGr) 19343 { 19344 if ((attrGr->attrUses == NULL) || 19345 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19346 return(0); 19347 19348 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19349 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19350 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19351 return(-1); 19352 return(0); 19353 } 19354 19355 /** 19356 * xmlSchemaAttributeGroupExpandRefs: 19357 * @pctxt: the parser context 19358 * @attrGr: the attribute group definition 19359 * 19360 * Substitutes contained attribute group references 19361 * for their attribute uses. Wilcards are intersected. 19362 * 19363 * Schema Component Constraint: 19364 * Attribute Group Definition Properties Correct (ag-props-correct) 19365 */ 19366 static int 19367 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19368 xmlSchemaAttributeGroupPtr attrGr) 19369 { 19370 /* 19371 * SPEC ag-props-correct 19372 * (1) "The values of the properties of an attribute group definition 19373 * must be as described in the property tableau in The Attribute 19374 * Group Definition Schema Component ($3.6.1), modulo the impact of 19375 * Missing Sub-components ($5.3);" 19376 */ 19377 19378 if ((attrGr->attrUses != NULL) && 19379 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19380 { 19381 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19382 xmlSchemaAttributeUsePtr use, tmp; 19383 int i, j, hasId = 0; 19384 19385 for (i = uses->nbItems -1; i >= 0; i--) { 19386 use = uses->items[i]; 19387 /* 19388 * SPEC ag-props-correct 19389 * (2) "Two distinct members of the {attribute uses} must not have 19390 * {attribute declaration}s both of whose {name}s match and whose 19391 * {target namespace}s are identical." 19392 */ 19393 if (i > 0) { 19394 for (j = i -1; j >= 0; j--) { 19395 tmp = uses->items[j]; 19396 if ((WXS_ATTRUSE_DECL_NAME(use) == 19397 WXS_ATTRUSE_DECL_NAME(tmp)) && 19398 (WXS_ATTRUSE_DECL_TNS(use) == 19399 WXS_ATTRUSE_DECL_TNS(tmp))) 19400 { 19401 xmlChar *str = NULL; 19402 19403 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19404 XML_SCHEMAP_AG_PROPS_CORRECT, 19405 attrGr->node, WXS_BASIC_CAST attrGr, 19406 "Duplicate %s", 19407 xmlSchemaGetComponentDesignation(&str, use), 19408 NULL); 19409 FREE_AND_NULL(str); 19410 /* 19411 * Remove the duplicate. 19412 */ 19413 if (xmlSchemaItemListRemove(uses, i) == -1) 19414 return(-1); 19415 goto next_use; 19416 } 19417 } 19418 } 19419 /* 19420 * SPEC ag-props-correct 19421 * (3) "Two distinct members of the {attribute uses} must not have 19422 * {attribute declaration}s both of whose {type definition}s are or 19423 * are derived from ID." 19424 * TODO: Does 'derived' include member-types of unions? 19425 */ 19426 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19427 if (xmlSchemaIsDerivedFromBuiltInType( 19428 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19429 { 19430 if (hasId) { 19431 xmlChar *str = NULL; 19432 19433 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19434 XML_SCHEMAP_AG_PROPS_CORRECT, 19435 attrGr->node, WXS_BASIC_CAST attrGr, 19436 "There must not exist more than one attribute " 19437 "declaration of type 'xs:ID' " 19438 "(or derived from 'xs:ID'). The %s violates this " 19439 "constraint", 19440 xmlSchemaGetComponentDesignation(&str, use), 19441 NULL); 19442 FREE_AND_NULL(str); 19443 if (xmlSchemaItemListRemove(uses, i) == -1) 19444 return(-1); 19445 } 19446 hasId = 1; 19447 } 19448 } 19449 next_use: {} 19450 } 19451 } 19452 return(0); 19453 } 19454 19455 /** 19456 * xmlSchemaResolveAttrGroupReferences: 19457 * @attrgrpDecl: the schema attribute definition 19458 * @ctxt: the schema parser context 19459 * @name: the attribute name 19460 * 19461 * Resolves references to attribute group definitions. 19462 */ 19463 static int 19464 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19465 xmlSchemaParserCtxtPtr ctxt) 19466 { 19467 xmlSchemaAttributeGroupPtr group; 19468 19469 if (ref->item != NULL) 19470 return(0); 19471 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19472 ref->name, 19473 ref->targetNamespace); 19474 if (group == NULL) { 19475 xmlSchemaPResCompAttrErr(ctxt, 19476 XML_SCHEMAP_SRC_RESOLVE, 19477 NULL, ref->node, 19478 "ref", ref->name, ref->targetNamespace, 19479 ref->itemType, NULL); 19480 return(ctxt->err); 19481 } 19482 ref->item = WXS_BASIC_CAST group; 19483 return(0); 19484 } 19485 19486 /** 19487 * xmlSchemaCheckAttrPropsCorrect: 19488 * @item: an schema attribute declaration/use 19489 * @ctxt: a schema parser context 19490 * @name: the name of the attribute 19491 * 19492 * 19493 * Schema Component Constraint: 19494 * Attribute Declaration Properties Correct (a-props-correct) 19495 * 19496 * Validates the value constraints of an attribute declaration/use. 19497 * NOTE that this needs the simle type definitions to be already 19498 * builded and checked. 19499 */ 19500 static int 19501 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19502 xmlSchemaAttributePtr attr) 19503 { 19504 19505 /* 19506 * SPEC a-props-correct (1) 19507 * "The values of the properties of an attribute declaration must 19508 * be as described in the property tableau in The Attribute 19509 * Declaration Schema Component ($3.2.1), modulo the impact of 19510 * Missing Sub-components ($5.3)." 19511 */ 19512 19513 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19514 return(0); 19515 19516 if (attr->defValue != NULL) { 19517 int ret; 19518 19519 /* 19520 * SPEC a-props-correct (3) 19521 * "If the {type definition} is or is derived from ID then there 19522 * must not be a {value constraint}." 19523 */ 19524 if (xmlSchemaIsDerivedFromBuiltInType( 19525 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19526 { 19527 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19528 XML_SCHEMAP_A_PROPS_CORRECT_3, 19529 NULL, WXS_BASIC_CAST attr, 19530 "Value constraints are not allowed if the type definition " 19531 "is or is derived from xs:ID", 19532 NULL, NULL); 19533 return(pctxt->err); 19534 } 19535 /* 19536 * SPEC a-props-correct (2) 19537 * "if there is a {value constraint}, the canonical lexical 19538 * representation of its value must be `valid` with respect 19539 * to the {type definition} as defined in String Valid ($3.14.4)." 19540 * TODO: Don't care about the *canonical* stuff here, this requirement 19541 * will be removed in WXS 1.1 anyway. 19542 */ 19543 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19544 attr->node, WXS_ATTR_TYPEDEF(attr), 19545 attr->defValue, &(attr->defVal), 19546 1, 1, 0); 19547 if (ret != 0) { 19548 if (ret < 0) { 19549 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19550 "calling xmlSchemaVCheckCVCSimpleType()"); 19551 return(-1); 19552 } 19553 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19554 XML_SCHEMAP_A_PROPS_CORRECT_2, 19555 NULL, WXS_BASIC_CAST attr, 19556 "The value of the value constraint is not valid", 19557 NULL, NULL); 19558 return(pctxt->err); 19559 } 19560 } 19561 19562 return(0); 19563 } 19564 19565 static xmlSchemaElementPtr 19566 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19567 xmlSchemaElementPtr ancestor) 19568 { 19569 xmlSchemaElementPtr ret; 19570 19571 if (WXS_SUBST_HEAD(ancestor) == NULL) 19572 return (NULL); 19573 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19574 return (ancestor); 19575 19576 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19577 return (NULL); 19578 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19579 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19580 WXS_SUBST_HEAD(ancestor)); 19581 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19582 19583 return (ret); 19584 } 19585 19586 /** 19587 * xmlSchemaCheckElemPropsCorrect: 19588 * @ctxt: a schema parser context 19589 * @decl: the element declaration 19590 * @name: the name of the attribute 19591 * 19592 * Schema Component Constraint: 19593 * Element Declaration Properties Correct (e-props-correct) 19594 * 19595 * STATUS: 19596 * missing: (6) 19597 */ 19598 static int 19599 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19600 xmlSchemaElementPtr elemDecl) 19601 { 19602 int ret = 0; 19603 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19604 /* 19605 * SPEC (1) "The values of the properties of an element declaration 19606 * must be as described in the property tableau in The Element 19607 * Declaration Schema Component ($3.3.1), modulo the impact of Missing 19608 * Sub-components ($5.3)." 19609 */ 19610 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19611 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19612 19613 xmlSchemaCheckElementDeclComponent(head, pctxt); 19614 /* 19615 * SPEC (3) "If there is a non-`absent` {substitution group 19616 * affiliation}, then {scope} must be global." 19617 */ 19618 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19619 xmlSchemaPCustomErr(pctxt, 19620 XML_SCHEMAP_E_PROPS_CORRECT_3, 19621 WXS_BASIC_CAST elemDecl, NULL, 19622 "Only global element declarations can have a " 19623 "substitution group affiliation", NULL); 19624 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19625 } 19626 /* 19627 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19628 * That is, it must not be possible to return to an element declaration 19629 * by repeatedly following the {substitution group affiliation} 19630 * property." 19631 */ 19632 if (head == elemDecl) 19633 circ = head; 19634 else if (WXS_SUBST_HEAD(head) != NULL) 19635 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19636 else 19637 circ = NULL; 19638 if (circ != NULL) { 19639 xmlChar *strA = NULL, *strB = NULL; 19640 19641 xmlSchemaPCustomErrExt(pctxt, 19642 XML_SCHEMAP_E_PROPS_CORRECT_6, 19643 WXS_BASIC_CAST circ, NULL, 19644 "The element declaration '%s' defines a circular " 19645 "substitution group to element declaration '%s'", 19646 xmlSchemaGetComponentQName(&strA, circ), 19647 xmlSchemaGetComponentQName(&strB, head), 19648 NULL); 19649 FREE_AND_NULL(strA) 19650 FREE_AND_NULL(strB) 19651 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19652 } 19653 /* 19654 * SPEC (4) "If there is a {substitution group affiliation}, 19655 * the {type definition} 19656 * of the element declaration must be validly derived from the {type 19657 * definition} of the {substitution group affiliation}, given the value 19658 * of the {substitution group exclusions} of the {substitution group 19659 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6) 19660 * (if the {type definition} is complex) or as defined in 19661 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is 19662 * simple)." 19663 * 19664 * NOTE: {substitution group exclusions} means the values of the 19665 * attribute "final". 19666 */ 19667 19668 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19669 int set = 0; 19670 19671 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19672 set |= SUBSET_EXTENSION; 19673 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19674 set |= SUBSET_RESTRICTION; 19675 19676 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19677 WXS_ELEM_TYPEDEF(head), set) != 0) { 19678 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19679 19680 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19681 xmlSchemaPCustomErrExt(pctxt, 19682 XML_SCHEMAP_E_PROPS_CORRECT_4, 19683 WXS_BASIC_CAST elemDecl, NULL, 19684 "The type definition '%s' was " 19685 "either rejected by the substitution group " 19686 "affiliation '%s', or not validly derived from its type " 19687 "definition '%s'", 19688 xmlSchemaGetComponentQName(&strA, typeDef), 19689 xmlSchemaGetComponentQName(&strB, head), 19690 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19691 FREE_AND_NULL(strA) 19692 FREE_AND_NULL(strB) 19693 FREE_AND_NULL(strC) 19694 } 19695 } 19696 } 19697 /* 19698 * SPEC (5) "If the {type definition} or {type definition}'s 19699 * {content type} 19700 * is or is derived from ID then there must not be a {value constraint}. 19701 * Note: The use of ID as a type definition for elements goes beyond 19702 * XML 1.0, and should be avoided if backwards compatibility is desired" 19703 */ 19704 if ((elemDecl->value != NULL) && 19705 ((WXS_IS_SIMPLE(typeDef) && 19706 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19707 (WXS_IS_COMPLEX(typeDef) && 19708 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19709 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19710 XML_SCHEMAS_ID)))) { 19711 19712 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19713 xmlSchemaPCustomErr(pctxt, 19714 XML_SCHEMAP_E_PROPS_CORRECT_5, 19715 WXS_BASIC_CAST elemDecl, NULL, 19716 "The type definition (or type definition's content type) is or " 19717 "is derived from ID; value constraints are not allowed in " 19718 "conjunction with such a type definition", NULL); 19719 } else if (elemDecl->value != NULL) { 19720 int vcret; 19721 xmlNodePtr node = NULL; 19722 19723 /* 19724 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19725 * representation of its value must be `valid` with respect to the 19726 * {type definition} as defined in Element Default Valid (Immediate) 19727 * ($3.3.6)." 19728 */ 19729 if (typeDef == NULL) { 19730 xmlSchemaPErr(pctxt, elemDecl->node, 19731 XML_SCHEMAP_INTERNAL, 19732 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19733 "type is missing... skipping validation of " 19734 "the value constraint", NULL, NULL); 19735 return (-1); 19736 } 19737 if (elemDecl->node != NULL) { 19738 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19739 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19740 BAD_CAST "fixed"); 19741 else 19742 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19743 BAD_CAST "default"); 19744 } 19745 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19746 typeDef, elemDecl->value, &(elemDecl->defVal)); 19747 if (vcret != 0) { 19748 if (vcret < 0) { 19749 PERROR_INT("xmlSchemaElemCheckValConstr", 19750 "failed to validate the value constraint of an " 19751 "element declaration"); 19752 return (-1); 19753 } 19754 return (vcret); 19755 } 19756 } 19757 19758 return (ret); 19759 } 19760 19761 /** 19762 * xmlSchemaCheckElemSubstGroup: 19763 * @ctxt: a schema parser context 19764 * @decl: the element declaration 19765 * @name: the name of the attribute 19766 * 19767 * Schema Component Constraint: 19768 * Substitution Group (cos-equiv-class) 19769 * 19770 * In Libxml2 the subst. groups will be precomputed, in terms of that 19771 * a list will be built for each subst. group head, holding all direct 19772 * referents to this head. 19773 * NOTE that this function needs: 19774 * 1. circular subst. groups to be checked beforehand 19775 * 2. the declaration's type to be derived from the head's type 19776 * 19777 * STATUS: 19778 * 19779 */ 19780 static void 19781 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19782 xmlSchemaElementPtr elemDecl) 19783 { 19784 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19785 /* SPEC (1) "Its {abstract} is false." */ 19786 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19787 return; 19788 { 19789 xmlSchemaElementPtr head; 19790 xmlSchemaTypePtr headType, type; 19791 int set, methSet; 19792 /* 19793 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19794 * {disallowed substitutions} as the blocking constraint, as defined in 19795 * Substitution Group OK (Transitive) ($3.3.6)." 19796 */ 19797 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19798 head = WXS_SUBST_HEAD(head)) { 19799 set = 0; 19800 methSet = 0; 19801 /* 19802 * The blocking constraints. 19803 */ 19804 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19805 continue; 19806 headType = head->subtypes; 19807 type = elemDecl->subtypes; 19808 if (headType == type) 19809 goto add_member; 19810 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19811 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19812 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19813 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19814 /* 19815 * SPEC: Substitution Group OK (Transitive) (2.3) 19816 * "The set of all {derivation method}s involved in the 19817 * derivation of D's {type definition} from C's {type definition} 19818 * does not intersect with the union of the blocking constraint, 19819 * C's {prohibited substitutions} (if C is complex, otherwise the 19820 * empty set) and the {prohibited substitutions} (respectively the 19821 * empty set) of any intermediate {type definition}s in the 19822 * derivation of D's {type definition} from C's {type definition}." 19823 */ 19824 /* 19825 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19826 * subst.head axis, the methSet does not need to be computed for 19827 * the full depth over and over. 19828 */ 19829 /* 19830 * The set of all {derivation method}s involved in the derivation 19831 */ 19832 while ((type != NULL) && (type != headType)) { 19833 if ((WXS_IS_EXTENSION(type)) && 19834 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19835 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19836 19837 if (WXS_IS_RESTRICTION(type) && 19838 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19839 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19840 19841 type = type->baseType; 19842 } 19843 /* 19844 * The {prohibited substitutions} of all intermediate types + 19845 * the head's type. 19846 */ 19847 type = elemDecl->subtypes->baseType; 19848 while (type != NULL) { 19849 if (WXS_IS_COMPLEX(type)) { 19850 if ((type->flags & 19851 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19852 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19853 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19854 if ((type->flags & 19855 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19856 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19857 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19858 } else 19859 break; 19860 if (type == headType) 19861 break; 19862 type = type->baseType; 19863 } 19864 if ((set != 0) && 19865 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19866 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19867 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19868 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19869 continue; 19870 } 19871 add_member: 19872 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19873 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19874 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19875 } 19876 } 19877 } 19878 19879 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19880 /** 19881 * xmlSchemaCheckElementDeclComponent 19882 * @pctxt: the schema parser context 19883 * @ctxtComponent: the context component (an element declaration) 19884 * @ctxtParticle: the first particle of the context component 19885 * @searchParticle: the element declaration particle to be analysed 19886 * 19887 * Schema Component Constraint: Element Declarations Consistent 19888 */ 19889 static int 19890 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19891 xmlSchemaBasicItemPtr ctxtComponent, 19892 xmlSchemaParticlePtr ctxtParticle, 19893 xmlSchemaParticlePtr searchParticle, 19894 xmlSchemaParticlePtr curParticle, 19895 int search) 19896 { 19897 return(0); 19898 19899 int ret = 0; 19900 xmlSchemaParticlePtr cur = curParticle; 19901 if (curParticle == NULL) { 19902 return(0); 19903 } 19904 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19905 /* 19906 * Just return in this case. A missing "term" of the particle 19907 * might arise due to an invalid "term" component. 19908 */ 19909 return(0); 19910 } 19911 while (cur != NULL) { 19912 switch (WXS_PARTICLE_TERM(cur)->type) { 19913 case XML_SCHEMA_TYPE_ANY: 19914 break; 19915 case XML_SCHEMA_TYPE_ELEMENT: 19916 if (search == 0) { 19917 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19918 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19919 if (ret != 0) 19920 return(ret); 19921 } else { 19922 xmlSchemaElementPtr elem = 19923 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19924 /* 19925 * SPEC Element Declarations Consistent: 19926 * "If the {particles} contains, either directly, 19927 * indirectly (that is, within the {particles} of a 19928 * contained model group, recursively) or `implicitly` 19929 * two or more element declaration particles with 19930 * the same {name} and {target namespace}, then 19931 * all their type definitions must be the same 19932 * top-level definition [...]" 19933 */ 19934 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19935 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19936 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19937 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19938 { 19939 xmlChar *strA = NULL, *strB = NULL; 19940 19941 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19942 /* TODO: error code */ 19943 XML_SCHEMAP_COS_NONAMBIG, 19944 WXS_ITEM_NODE(cur), NULL, 19945 "In the content model of %s, there are multiple " 19946 "element declarations for '%s' with different " 19947 "type definitions", 19948 xmlSchemaGetComponentDesignation(&strA, 19949 ctxtComponent), 19950 xmlSchemaFormatQName(&strB, 19951 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19952 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19953 FREE_AND_NULL(strA); 19954 FREE_AND_NULL(strB); 19955 return(XML_SCHEMAP_COS_NONAMBIG); 19956 } 19957 } 19958 break; 19959 case XML_SCHEMA_TYPE_SEQUENCE: { 19960 break; 19961 } 19962 case XML_SCHEMA_TYPE_CHOICE:{ 19963 /* 19964 xmlSchemaTreeItemPtr sub; 19965 19966 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19967 while (sub != NULL) { 19968 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19969 ctxtParticle, ctxtElem); 19970 if (ret != 0) 19971 return(ret); 19972 sub = sub->next; 19973 } 19974 */ 19975 break; 19976 } 19977 case XML_SCHEMA_TYPE_ALL: 19978 break; 19979 case XML_SCHEMA_TYPE_GROUP: 19980 break; 19981 default: 19982 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19983 "xmlSchemaCheckElementDeclConsistent", 19984 "found unexpected term of type '%s' in content model", 19985 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19986 return(-1); 19987 } 19988 cur = (xmlSchemaParticlePtr) cur->next; 19989 } 19990 19991 exit: 19992 return(ret); 19993 } 19994 #endif 19995 19996 /** 19997 * xmlSchemaCheckElementDeclComponent 19998 * @item: an schema element declaration/particle 19999 * @ctxt: a schema parser context 20000 * @name: the name of the attribute 20001 * 20002 * Validates the value constraints of an element declaration. 20003 * Adds substitution group members. 20004 */ 20005 static void 20006 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 20007 xmlSchemaParserCtxtPtr ctxt) 20008 { 20009 if (elemDecl == NULL) 20010 return; 20011 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 20012 return; 20013 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 20014 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 20015 /* 20016 * Adds substitution group members. 20017 */ 20018 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 20019 } 20020 } 20021 20022 /** 20023 * xmlSchemaResolveModelGroupParticleReferences: 20024 * @particle: a particle component 20025 * @ctxt: a parser context 20026 * 20027 * Resolves references of a model group's {particles} to 20028 * model group definitions and to element declarations. 20029 */ 20030 static void 20031 xmlSchemaResolveModelGroupParticleReferences( 20032 xmlSchemaParserCtxtPtr ctxt, 20033 xmlSchemaModelGroupPtr mg) 20034 { 20035 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 20036 xmlSchemaQNameRefPtr ref; 20037 xmlSchemaBasicItemPtr refItem; 20038 20039 /* 20040 * URGENT TODO: Test this. 20041 */ 20042 while (particle != NULL) { 20043 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20044 ((WXS_PARTICLE_TERM(particle))->type != 20045 XML_SCHEMA_EXTRA_QNAMEREF)) 20046 { 20047 goto next_particle; 20048 } 20049 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20050 /* 20051 * Resolve the reference. 20052 * NULL the {term} by default. 20053 */ 20054 particle->children = NULL; 20055 20056 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20057 ref->itemType, ref->name, ref->targetNamespace); 20058 if (refItem == NULL) { 20059 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20060 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20061 ref->targetNamespace, ref->itemType, NULL); 20062 /* TODO: remove the particle. */ 20063 goto next_particle; 20064 } 20065 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20066 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20067 /* TODO: remove the particle. */ 20068 goto next_particle; 20069 /* 20070 * NOTE that we will assign the model group definition 20071 * itself to the "term" of the particle. This will ease 20072 * the check for circular model group definitions. After 20073 * that the "term" will be assigned the model group of the 20074 * model group definition. 20075 */ 20076 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20077 XML_SCHEMA_TYPE_ALL) { 20078 /* 20079 * SPEC cos-all-limited (1) 20080 * SPEC cos-all-limited (1.2) 20081 * "It appears only as the value of one or both of the 20082 * following properties:" 20083 * (1.1) "the {model group} property of a model group 20084 * definition." 20085 * (1.2) "the {term} property of a particle [... of] the " 20086 * {content type} of a complex type definition." 20087 */ 20088 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20089 /* TODO: error code */ 20090 XML_SCHEMAP_COS_ALL_LIMITED, 20091 WXS_ITEM_NODE(particle), NULL, 20092 "A model group definition is referenced, but " 20093 "it contains an 'all' model group, which " 20094 "cannot be contained by model groups", 20095 NULL, NULL); 20096 /* TODO: remove the particle. */ 20097 goto next_particle; 20098 } 20099 particle->children = (xmlSchemaTreeItemPtr) refItem; 20100 } else { 20101 /* 20102 * TODO: Are referenced element declarations the only 20103 * other components we expect here? 20104 */ 20105 particle->children = (xmlSchemaTreeItemPtr) refItem; 20106 } 20107 next_particle: 20108 particle = WXS_PTC_CAST particle->next; 20109 } 20110 } 20111 20112 static int 20113 xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20114 xmlSchemaValPtr y) 20115 { 20116 xmlSchemaTypePtr tx, ty, ptx, pty; 20117 int ret; 20118 20119 while (x != NULL) { 20120 /* Same types. */ 20121 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20122 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20123 ptx = xmlSchemaGetPrimitiveType(tx); 20124 pty = xmlSchemaGetPrimitiveType(ty); 20125 /* 20126 * (1) if a datatype T' is `derived` by `restriction` from an 20127 * atomic datatype T then the `value space` of T' is a subset of 20128 * the `value space` of T. */ 20129 /* 20130 * (2) if datatypes T' and T'' are `derived` by `restriction` 20131 * from a common atomic ancestor T then the `value space`s of T' 20132 * and T'' may overlap. 20133 */ 20134 if (ptx != pty) 20135 return(0); 20136 /* 20137 * We assume computed values to be normalized, so do a fast 20138 * string comparison for string based types. 20139 */ 20140 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20141 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20142 if (! xmlStrEqual( 20143 xmlSchemaValueGetAsString(x), 20144 xmlSchemaValueGetAsString(y))) 20145 return (0); 20146 } else { 20147 ret = xmlSchemaCompareValuesWhtsp( 20148 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20149 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20150 if (ret == -2) 20151 return(-1); 20152 if (ret != 0) 20153 return(0); 20154 } 20155 /* 20156 * Lists. 20157 */ 20158 x = xmlSchemaValueGetNext(x); 20159 if (x != NULL) { 20160 y = xmlSchemaValueGetNext(y); 20161 if (y == NULL) 20162 return (0); 20163 } else if (xmlSchemaValueGetNext(y) != NULL) 20164 return (0); 20165 else 20166 return (1); 20167 } 20168 return (0); 20169 } 20170 20171 /** 20172 * xmlSchemaResolveAttrUseReferences: 20173 * @item: an attribute use 20174 * @ctxt: a parser context 20175 * 20176 * Resolves the referenced attribute declaration. 20177 */ 20178 static int 20179 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20180 xmlSchemaParserCtxtPtr ctxt) 20181 { 20182 if ((ctxt == NULL) || (ause == NULL)) 20183 return(-1); 20184 if ((ause->attrDecl == NULL) || 20185 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20186 return(0); 20187 20188 { 20189 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20190 20191 /* 20192 * TODO: Evaluate, what errors could occur if the declaration is not 20193 * found. 20194 */ 20195 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20196 ref->name, ref->targetNamespace); 20197 if (ause->attrDecl == NULL) { 20198 xmlSchemaPResCompAttrErr(ctxt, 20199 XML_SCHEMAP_SRC_RESOLVE, 20200 WXS_BASIC_CAST ause, ause->node, 20201 "ref", ref->name, ref->targetNamespace, 20202 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20203 return(ctxt->err);; 20204 } 20205 } 20206 return(0); 20207 } 20208 20209 /** 20210 * xmlSchemaCheckAttrUsePropsCorrect: 20211 * @ctxt: a parser context 20212 * @use: an attribute use 20213 * 20214 * Schema Component Constraint: 20215 * Attribute Use Correct (au-props-correct) 20216 * 20217 */ 20218 static int 20219 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20220 xmlSchemaAttributeUsePtr use) 20221 { 20222 if ((ctxt == NULL) || (use == NULL)) 20223 return(-1); 20224 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20225 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20226 return(0); 20227 20228 /* 20229 * SPEC au-props-correct (1) 20230 * "The values of the properties of an attribute use must be as 20231 * described in the property tableau in The Attribute Use Schema 20232 * Component ($3.5.1), modulo the impact of Missing 20233 * Sub-components ($5.3)." 20234 */ 20235 20236 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20237 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20238 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20239 { 20240 xmlSchemaPCustomErr(ctxt, 20241 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20242 WXS_BASIC_CAST use, NULL, 20243 "The attribute declaration has a 'fixed' value constraint " 20244 ", thus the attribute use must also have a 'fixed' value " 20245 "constraint", 20246 NULL); 20247 return(ctxt->err); 20248 } 20249 /* 20250 * Compute and check the value constraint's value. 20251 */ 20252 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20253 int ret; 20254 /* 20255 * TODO: The spec seems to be missing a check of the 20256 * value constraint of the attribute use. We will do it here. 20257 */ 20258 /* 20259 * SPEC a-props-correct (3) 20260 */ 20261 if (xmlSchemaIsDerivedFromBuiltInType( 20262 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20263 { 20264 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20265 XML_SCHEMAP_AU_PROPS_CORRECT, 20266 NULL, WXS_BASIC_CAST use, 20267 "Value constraints are not allowed if the type definition " 20268 "is or is derived from xs:ID", 20269 NULL, NULL); 20270 return(ctxt->err); 20271 } 20272 20273 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20274 use->node, WXS_ATTRUSE_TYPEDEF(use), 20275 use->defValue, &(use->defVal), 20276 1, 1, 0); 20277 if (ret != 0) { 20278 if (ret < 0) { 20279 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20280 "calling xmlSchemaVCheckCVCSimpleType()"); 20281 return(-1); 20282 } 20283 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20284 XML_SCHEMAP_AU_PROPS_CORRECT, 20285 NULL, WXS_BASIC_CAST use, 20286 "The value of the value constraint is not valid", 20287 NULL, NULL); 20288 return(ctxt->err); 20289 } 20290 } 20291 /* 20292 * SPEC au-props-correct (2) 20293 * "If the {attribute declaration} has a fixed 20294 * {value constraint}, then if the attribute use itself has a 20295 * {value constraint}, it must also be fixed and its value must match 20296 * that of the {attribute declaration}'s {value constraint}." 20297 */ 20298 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20299 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20300 { 20301 if (! xmlSchemaAreValuesEqual(use->defVal, 20302 (WXS_ATTRUSE_DECL(use))->defVal)) 20303 { 20304 xmlSchemaPCustomErr(ctxt, 20305 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20306 WXS_BASIC_CAST use, NULL, 20307 "The 'fixed' value constraint of the attribute use " 20308 "must match the attribute declaration's value " 20309 "constraint '%s'", 20310 (WXS_ATTRUSE_DECL(use))->defValue); 20311 } 20312 return(ctxt->err); 20313 } 20314 return(0); 20315 } 20316 20317 20318 20319 20320 /** 20321 * xmlSchemaResolveAttrTypeReferences: 20322 * @item: an attribute declaration 20323 * @ctxt: a parser context 20324 * 20325 * Resolves the referenced type definition component. 20326 */ 20327 static int 20328 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20329 xmlSchemaParserCtxtPtr ctxt) 20330 { 20331 /* 20332 * The simple type definition corresponding to the <simpleType> element 20333 * information item in the [children], if present, otherwise the simple 20334 * type definition `resolved` to by the `actual value` of the type 20335 * [attribute], if present, otherwise the `simple ur-type definition`. 20336 */ 20337 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20338 return(0); 20339 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20340 if (item->subtypes != NULL) 20341 return(0); 20342 if (item->typeName != NULL) { 20343 xmlSchemaTypePtr type; 20344 20345 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20346 item->typeNs); 20347 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20348 xmlSchemaPResCompAttrErr(ctxt, 20349 XML_SCHEMAP_SRC_RESOLVE, 20350 WXS_BASIC_CAST item, item->node, 20351 "type", item->typeName, item->typeNs, 20352 XML_SCHEMA_TYPE_SIMPLE, NULL); 20353 return(ctxt->err); 20354 } else 20355 item->subtypes = type; 20356 20357 } else { 20358 /* 20359 * The type defaults to the xs:anySimpleType. 20360 */ 20361 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20362 } 20363 return(0); 20364 } 20365 20366 /** 20367 * xmlSchemaResolveIDCKeyReferences: 20368 * @idc: the identity-constraint definition 20369 * @ctxt: the schema parser context 20370 * @name: the attribute name 20371 * 20372 * Resolve keyRef references to key/unique IDCs. 20373 * Schema Component Constraint: 20374 * Identity-constraint Definition Properties Correct (c-props-correct) 20375 */ 20376 static int 20377 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20378 xmlSchemaParserCtxtPtr pctxt) 20379 { 20380 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20381 return(0); 20382 if (idc->ref->name != NULL) { 20383 idc->ref->item = (xmlSchemaBasicItemPtr) 20384 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20385 idc->ref->targetNamespace); 20386 if (idc->ref->item == NULL) { 20387 /* 20388 * TODO: It is actually not an error to fail to resolve 20389 * at this stage. BUT we need to be that strict! 20390 */ 20391 xmlSchemaPResCompAttrErr(pctxt, 20392 XML_SCHEMAP_SRC_RESOLVE, 20393 WXS_BASIC_CAST idc, idc->node, 20394 "refer", idc->ref->name, 20395 idc->ref->targetNamespace, 20396 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20397 return(pctxt->err); 20398 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20399 /* 20400 * SPEC c-props-correct (1) 20401 */ 20402 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20403 XML_SCHEMAP_C_PROPS_CORRECT, 20404 NULL, WXS_BASIC_CAST idc, 20405 "The keyref references a keyref", 20406 NULL, NULL); 20407 idc->ref->item = NULL; 20408 return(pctxt->err); 20409 } else { 20410 if (idc->nbFields != 20411 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20412 xmlChar *str = NULL; 20413 xmlSchemaIDCPtr refer; 20414 20415 refer = (xmlSchemaIDCPtr) idc->ref->item; 20416 /* 20417 * SPEC c-props-correct(2) 20418 * "If the {identity-constraint category} is keyref, 20419 * the cardinality of the {fields} must equal that of 20420 * the {fields} of the {referenced key}. 20421 */ 20422 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20423 XML_SCHEMAP_C_PROPS_CORRECT, 20424 NULL, WXS_BASIC_CAST idc, 20425 "The cardinality of the keyref differs from the " 20426 "cardinality of the referenced key/unique '%s'", 20427 xmlSchemaFormatQName(&str, refer->targetNamespace, 20428 refer->name), 20429 NULL); 20430 FREE_AND_NULL(str) 20431 return(pctxt->err); 20432 } 20433 } 20434 } 20435 return(0); 20436 } 20437 20438 static int 20439 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20440 xmlSchemaParserCtxtPtr pctxt) 20441 { 20442 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20443 prohib->targetNamespace) == NULL) { 20444 20445 xmlSchemaPResCompAttrErr(pctxt, 20446 XML_SCHEMAP_SRC_RESOLVE, 20447 NULL, prohib->node, 20448 "ref", prohib->name, prohib->targetNamespace, 20449 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20450 return(XML_SCHEMAP_SRC_RESOLVE); 20451 } 20452 return(0); 20453 } 20454 20455 #define WXS_REDEFINED_TYPE(c) \ 20456 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20457 20458 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20459 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20460 20461 #define WXS_REDEFINED_ATTR_GROUP(c) \ 20462 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20463 20464 static int 20465 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20466 { 20467 int err = 0; 20468 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20469 xmlSchemaBasicItemPtr prev, item; 20470 int wasRedefined; 20471 20472 if (redef == NULL) 20473 return(0); 20474 20475 do { 20476 item = redef->item; 20477 /* 20478 * First try to locate the redefined component in the 20479 * schema graph starting with the redefined schema. 20480 * NOTE: According to this schema bug entry: 20481 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20482 * it's not clear if the referenced component needs to originate 20483 * from the <redefine>d schema _document_ or the schema; the latter 20484 * would include all imported and included sub-schemas of the 20485 * <redefine>d schema. Currenlty we latter approach is used. 20486 * SUPPLEMENT: It seems that the WG moves towards the latter 20487 * approach, so we are doing it right. 20488 * 20489 */ 20490 prev = xmlSchemaFindRedefCompInGraph( 20491 redef->targetBucket, item->type, 20492 redef->refName, redef->refTargetNs); 20493 if (prev == NULL) { 20494 xmlChar *str = NULL; 20495 xmlNodePtr node; 20496 20497 /* 20498 * SPEC src-redefine: 20499 * (6.2.1) "The `actual value` of its own name attribute plus 20500 * target namespace must successfully `resolve` to a model 20501 * group definition in I." 20502 * (7.2.1) "The `actual value` of its own name attribute plus 20503 * target namespace must successfully `resolve` to an attribute 20504 * group definition in I." 20505 20506 * 20507 * Note that, if we are redefining with the use of references 20508 * to components, the spec assumes the src-resolve to be used; 20509 * but this won't assure that we search only *inside* the 20510 * redefined schema. 20511 */ 20512 if (redef->reference) 20513 node = WXS_ITEM_NODE(redef->reference); 20514 else 20515 node = WXS_ITEM_NODE(item); 20516 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20517 /* 20518 * TODO: error code. 20519 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20520 * reference kind. 20521 */ 20522 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20523 "The %s '%s' to be redefined could not be found in " 20524 "the redefined schema", 20525 WXS_ITEM_TYPE_NAME(item), 20526 xmlSchemaFormatQName(&str, redef->refTargetNs, 20527 redef->refName)); 20528 FREE_AND_NULL(str); 20529 err = pctxt->err; 20530 redef = redef->next; 20531 continue; 20532 } 20533 /* 20534 * TODO: Obtaining and setting the redefinition state is really 20535 * clumsy. 20536 */ 20537 wasRedefined = 0; 20538 switch (item->type) { 20539 case XML_SCHEMA_TYPE_COMPLEX: 20540 case XML_SCHEMA_TYPE_SIMPLE: 20541 if ((WXS_TYPE_CAST prev)->flags & 20542 XML_SCHEMAS_TYPE_REDEFINED) 20543 { 20544 wasRedefined = 1; 20545 break; 20546 } 20547 /* Mark it as redefined. */ 20548 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20549 /* 20550 * Assign the redefined type to the 20551 * base type of the redefining type. 20552 * TODO: How 20553 */ 20554 ((xmlSchemaTypePtr) item)->baseType = 20555 (xmlSchemaTypePtr) prev; 20556 break; 20557 case XML_SCHEMA_TYPE_GROUP: 20558 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20559 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20560 { 20561 wasRedefined = 1; 20562 break; 20563 } 20564 /* Mark it as redefined. */ 20565 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20566 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20567 if (redef->reference != NULL) { 20568 /* 20569 * Overwrite the QName-reference with the 20570 * referenced model group def. 20571 */ 20572 (WXS_PTC_CAST redef->reference)->children = 20573 WXS_TREE_CAST prev; 20574 } 20575 redef->target = prev; 20576 break; 20577 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20578 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20579 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20580 { 20581 wasRedefined = 1; 20582 break; 20583 } 20584 (WXS_ATTR_GROUP_CAST prev)->flags |= 20585 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20586 if (redef->reference != NULL) { 20587 /* 20588 * Assign the redefined attribute group to the 20589 * QName-reference component. 20590 * This is the easy case, since we will just 20591 * expand the redefined group. 20592 */ 20593 (WXS_QNAME_CAST redef->reference)->item = prev; 20594 redef->target = NULL; 20595 } else { 20596 /* 20597 * This is the complicated case: we need 20598 * to apply src-redefine (7.2.2) at a later 20599 * stage, i.e. when attribute group references 20600 * have beed expanded and simple types have 20601 * beed fixed. 20602 */ 20603 redef->target = prev; 20604 } 20605 break; 20606 default: 20607 PERROR_INT("xmlSchemaResolveRedefReferences", 20608 "Unexpected redefined component type"); 20609 return(-1); 20610 } 20611 if (wasRedefined) { 20612 xmlChar *str = NULL; 20613 xmlNodePtr node; 20614 20615 if (redef->reference) 20616 node = WXS_ITEM_NODE(redef->reference); 20617 else 20618 node = WXS_ITEM_NODE(redef->item); 20619 20620 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20621 /* TODO: error code. */ 20622 XML_SCHEMAP_SRC_REDEFINE, 20623 node, NULL, 20624 "The referenced %s was already redefined. Multiple " 20625 "redefinition of the same component is not supported", 20626 xmlSchemaGetComponentDesignation(&str, prev), 20627 NULL); 20628 FREE_AND_NULL(str) 20629 err = pctxt->err; 20630 redef = redef->next; 20631 continue; 20632 } 20633 redef = redef->next; 20634 } while (redef != NULL); 20635 20636 return(err); 20637 } 20638 20639 static int 20640 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20641 { 20642 int err = 0; 20643 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20644 xmlSchemaBasicItemPtr item; 20645 20646 if (redef == NULL) 20647 return(0); 20648 20649 do { 20650 if (redef->target == NULL) { 20651 redef = redef->next; 20652 continue; 20653 } 20654 item = redef->item; 20655 20656 switch (item->type) { 20657 case XML_SCHEMA_TYPE_SIMPLE: 20658 case XML_SCHEMA_TYPE_COMPLEX: 20659 /* 20660 * Since the spec wants the {name} of the redefined 20661 * type to be 'absent', we'll NULL it. 20662 */ 20663 (WXS_TYPE_CAST redef->target)->name = NULL; 20664 20665 /* 20666 * TODO: Seems like there's nothing more to do. The normal 20667 * inheritance mechanism is used. But not 100% sure. 20668 */ 20669 break; 20670 case XML_SCHEMA_TYPE_GROUP: 20671 /* 20672 * URGENT TODO: 20673 * SPEC src-redefine: 20674 * (6.2.2) "The {model group} of the model group definition 20675 * which corresponds to it per XML Representation of Model 20676 * Group Definition Schema Components ($3.7.2) must be a 20677 * `valid restriction` of the {model group} of that model 20678 * group definition in I, as defined in Particle Valid 20679 * (Restriction) ($3.9.6)." 20680 */ 20681 break; 20682 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20683 /* 20684 * SPEC src-redefine: 20685 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20686 * the attribute group definition which corresponds to it 20687 * per XML Representation of Attribute Group Definition Schema 20688 * Components ($3.6.2) must be `valid restrictions` of the 20689 * {attribute uses} and {attribute wildcard} of that attribute 20690 * group definition in I, as defined in clause 2, clause 3 and 20691 * clause 4 of Derivation Valid (Restriction, Complex) 20692 * ($3.4.6) (where references to the base type definition are 20693 * understood as references to the attribute group definition 20694 * in I)." 20695 */ 20696 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20697 XML_SCHEMA_ACTION_REDEFINE, 20698 item, redef->target, 20699 (WXS_ATTR_GROUP_CAST item)->attrUses, 20700 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20701 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20702 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20703 if (err == -1) 20704 return(-1); 20705 break; 20706 default: 20707 break; 20708 } 20709 redef = redef->next; 20710 } while (redef != NULL); 20711 return(0); 20712 } 20713 20714 20715 static int 20716 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20717 xmlSchemaBucketPtr bucket) 20718 { 20719 xmlSchemaBasicItemPtr item; 20720 int err; 20721 xmlHashTablePtr *table; 20722 const xmlChar *name; 20723 int i; 20724 20725 #define WXS_GET_GLOBAL_HASH(c, slot) { \ 20726 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20727 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20728 else \ 20729 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20730 20731 /* 20732 * Add global components to the schema's hash tables. 20733 * This is the place where duplicate components will be 20734 * detected. 20735 * TODO: I think normally we should support imports of the 20736 * same namespace from multiple locations. We don't do currently, 20737 * but if we do then according to: 20738 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20739 * we would need, if imported directly, to import redefined 20740 * components as well to be able to catch clashing components. 20741 * (I hope I'll still know what this means after some months :-() 20742 */ 20743 if (bucket == NULL) 20744 return(-1); 20745 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20746 return(0); 20747 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20748 20749 for (i = 0; i < bucket->globals->nbItems; i++) { 20750 item = bucket->globals->items[i]; 20751 table = NULL; 20752 switch (item->type) { 20753 case XML_SCHEMA_TYPE_COMPLEX: 20754 case XML_SCHEMA_TYPE_SIMPLE: 20755 if (WXS_REDEFINED_TYPE(item)) 20756 continue; 20757 name = (WXS_TYPE_CAST item)->name; 20758 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20759 break; 20760 case XML_SCHEMA_TYPE_ELEMENT: 20761 name = (WXS_ELEM_CAST item)->name; 20762 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20763 break; 20764 case XML_SCHEMA_TYPE_ATTRIBUTE: 20765 name = (WXS_ATTR_CAST item)->name; 20766 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20767 break; 20768 case XML_SCHEMA_TYPE_GROUP: 20769 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20770 continue; 20771 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20772 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20773 break; 20774 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20775 if (WXS_REDEFINED_ATTR_GROUP(item)) 20776 continue; 20777 name = (WXS_ATTR_GROUP_CAST item)->name; 20778 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20779 break; 20780 case XML_SCHEMA_TYPE_IDC_KEY: 20781 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20782 case XML_SCHEMA_TYPE_IDC_KEYREF: 20783 name = (WXS_IDC_CAST item)->name; 20784 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20785 break; 20786 case XML_SCHEMA_TYPE_NOTATION: 20787 name = ((xmlSchemaNotationPtr) item)->name; 20788 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20789 break; 20790 default: 20791 PERROR_INT("xmlSchemaAddComponents", 20792 "Unexpected global component type"); 20793 continue; 20794 } 20795 if (*table == NULL) { 20796 *table = xmlHashCreateDict(10, pctxt->dict); 20797 if (*table == NULL) { 20798 PERROR_INT("xmlSchemaAddComponents", 20799 "failed to create a component hash table"); 20800 return(-1); 20801 } 20802 } 20803 err = xmlHashAddEntry(*table, name, item); 20804 if (err != 0) { 20805 xmlChar *str = NULL; 20806 20807 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20808 XML_SCHEMAP_REDEFINED_TYPE, 20809 WXS_ITEM_NODE(item), 20810 WXS_BASIC_CAST item, 20811 "A global %s '%s' does already exist", 20812 WXS_ITEM_TYPE_NAME(item), 20813 xmlSchemaGetComponentQName(&str, item)); 20814 FREE_AND_NULL(str); 20815 } 20816 } 20817 /* 20818 * Process imported/included schemas. 20819 */ 20820 if (bucket->relations != NULL) { 20821 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20822 do { 20823 if ((rel->bucket != NULL) && 20824 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20825 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20826 return(-1); 20827 } 20828 rel = rel->next; 20829 } while (rel != NULL); 20830 } 20831 return(0); 20832 } 20833 20834 static int 20835 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20836 xmlSchemaBucketPtr rootBucket) 20837 { 20838 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20839 xmlSchemaTreeItemPtr item, *items; 20840 int nbItems, i, ret = 0; 20841 xmlSchemaBucketPtr oldbucket = con->bucket; 20842 xmlSchemaElementPtr elemDecl; 20843 20844 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20845 20846 if ((con->pending == NULL) || 20847 (con->pending->nbItems == 0)) 20848 return(0); 20849 20850 /* 20851 * Since xmlSchemaFixupComplexType() will create new particles 20852 * (local components), and those particle components need a bucket 20853 * on the constructor, we'll assure here that the constructor has 20854 * a bucket. 20855 * TODO: Think about storing locals _only_ on the main bucket. 20856 */ 20857 if (con->bucket == NULL) 20858 con->bucket = rootBucket; 20859 20860 /* TODO: 20861 * SPEC (src-redefine): 20862 * (6.2) "If it has no such self-reference, then all of the 20863 * following must be true:" 20864 20865 * (6.2.2) The {model group} of the model group definition which 20866 * corresponds to it per XML Representation of Model Group 20867 * Definition Schema Components ($3.7.2) must be a `valid 20868 * restriction` of the {model group} of that model group definition 20869 * in I, as defined in Particle Valid (Restriction) ($3.9.6)." 20870 */ 20871 xmlSchemaCheckSRCRedefineFirst(pctxt); 20872 20873 /* 20874 * Add global components to the schemata's hash tables. 20875 */ 20876 xmlSchemaAddComponents(pctxt, rootBucket); 20877 20878 pctxt->ctxtType = NULL; 20879 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20880 nbItems = con->pending->nbItems; 20881 /* 20882 * Now that we have parsed *all* the schema document(s) and converted 20883 * them to schema components, we can resolve references, apply component 20884 * constraints, create the FSA from the content model, etc. 20885 */ 20886 /* 20887 * Resolve references of.. 20888 * 20889 * 1. element declarations: 20890 * - the type definition 20891 * - the substitution group affiliation 20892 * 2. simple/complex types: 20893 * - the base type definition 20894 * - the memberTypes of union types 20895 * - the itemType of list types 20896 * 3. attributes declarations and attribute uses: 20897 * - the type definition 20898 * - if an attribute use, then the attribute declaration 20899 * 4. attribute group references: 20900 * - the attribute group definition 20901 * 5. particles: 20902 * - the term of the particle (e.g. a model group) 20903 * 6. IDC key-references: 20904 * - the referenced IDC 'key' or 'unique' definition 20905 * 7. Attribute prohibitions which had a "ref" attribute. 20906 */ 20907 for (i = 0; i < nbItems; i++) { 20908 item = items[i]; 20909 switch (item->type) { 20910 case XML_SCHEMA_TYPE_ELEMENT: 20911 xmlSchemaResolveElementReferences( 20912 (xmlSchemaElementPtr) item, pctxt); 20913 FIXHFAILURE; 20914 break; 20915 case XML_SCHEMA_TYPE_COMPLEX: 20916 case XML_SCHEMA_TYPE_SIMPLE: 20917 xmlSchemaResolveTypeReferences( 20918 (xmlSchemaTypePtr) item, pctxt); 20919 FIXHFAILURE; 20920 break; 20921 case XML_SCHEMA_TYPE_ATTRIBUTE: 20922 xmlSchemaResolveAttrTypeReferences( 20923 (xmlSchemaAttributePtr) item, pctxt); 20924 FIXHFAILURE; 20925 break; 20926 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20927 xmlSchemaResolveAttrUseReferences( 20928 (xmlSchemaAttributeUsePtr) item, pctxt); 20929 FIXHFAILURE; 20930 break; 20931 case XML_SCHEMA_EXTRA_QNAMEREF: 20932 if ((WXS_QNAME_CAST item)->itemType == 20933 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20934 { 20935 xmlSchemaResolveAttrGroupReferences( 20936 WXS_QNAME_CAST item, pctxt); 20937 } 20938 FIXHFAILURE; 20939 break; 20940 case XML_SCHEMA_TYPE_SEQUENCE: 20941 case XML_SCHEMA_TYPE_CHOICE: 20942 case XML_SCHEMA_TYPE_ALL: 20943 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20944 WXS_MODEL_GROUP_CAST item); 20945 FIXHFAILURE; 20946 break; 20947 case XML_SCHEMA_TYPE_IDC_KEY: 20948 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20949 case XML_SCHEMA_TYPE_IDC_KEYREF: 20950 xmlSchemaResolveIDCKeyReferences( 20951 (xmlSchemaIDCPtr) item, pctxt); 20952 FIXHFAILURE; 20953 break; 20954 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20955 /* 20956 * Handle attribue prohibition which had a 20957 * "ref" attribute. 20958 */ 20959 xmlSchemaResolveAttrUseProhibReferences( 20960 WXS_ATTR_PROHIB_CAST item, pctxt); 20961 FIXHFAILURE; 20962 break; 20963 default: 20964 break; 20965 } 20966 } 20967 if (pctxt->nberrors != 0) 20968 goto exit_error; 20969 20970 /* 20971 * Now that all references are resolved we 20972 * can check for circularity of... 20973 * 1. the base axis of type definitions 20974 * 2. nested model group definitions 20975 * 3. nested attribute group definitions 20976 * TODO: check for circual substitution groups. 20977 */ 20978 for (i = 0; i < nbItems; i++) { 20979 item = items[i]; 20980 /* 20981 * Let's better stop on the first error here. 20982 */ 20983 switch (item->type) { 20984 case XML_SCHEMA_TYPE_COMPLEX: 20985 case XML_SCHEMA_TYPE_SIMPLE: 20986 xmlSchemaCheckTypeDefCircular( 20987 (xmlSchemaTypePtr) item, pctxt); 20988 FIXHFAILURE; 20989 if (pctxt->nberrors != 0) 20990 goto exit_error; 20991 break; 20992 case XML_SCHEMA_TYPE_GROUP: 20993 xmlSchemaCheckGroupDefCircular( 20994 (xmlSchemaModelGroupDefPtr) item, pctxt); 20995 FIXHFAILURE; 20996 if (pctxt->nberrors != 0) 20997 goto exit_error; 20998 break; 20999 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21000 xmlSchemaCheckAttrGroupCircular( 21001 (xmlSchemaAttributeGroupPtr) item, pctxt); 21002 FIXHFAILURE; 21003 if (pctxt->nberrors != 0) 21004 goto exit_error; 21005 break; 21006 default: 21007 break; 21008 } 21009 } 21010 if (pctxt->nberrors != 0) 21011 goto exit_error; 21012 /* 21013 * Model group definition references: 21014 * Such a reference is reflected by a particle at the component 21015 * level. Until now the 'term' of such particles pointed 21016 * to the model group definition; this was done, in order to 21017 * ease circularity checks. Now we need to set the 'term' of 21018 * such particles to the model group of the model group definition. 21019 */ 21020 for (i = 0; i < nbItems; i++) { 21021 item = items[i]; 21022 switch (item->type) { 21023 case XML_SCHEMA_TYPE_SEQUENCE: 21024 case XML_SCHEMA_TYPE_CHOICE: 21025 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 21026 WXS_MODEL_GROUP_CAST item); 21027 break; 21028 default: 21029 break; 21030 } 21031 } 21032 if (pctxt->nberrors != 0) 21033 goto exit_error; 21034 /* 21035 * Expand attribute group references of attribute group definitions. 21036 */ 21037 for (i = 0; i < nbItems; i++) { 21038 item = items[i]; 21039 switch (item->type) { 21040 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21041 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 21042 WXS_ATTR_GROUP_HAS_REFS(item)) 21043 { 21044 xmlSchemaAttributeGroupExpandRefs(pctxt, 21045 WXS_ATTR_GROUP_CAST item); 21046 FIXHFAILURE; 21047 } 21048 break; 21049 default: 21050 break; 21051 } 21052 } 21053 if (pctxt->nberrors != 0) 21054 goto exit_error; 21055 /* 21056 * First compute the variety of simple types. This is needed as 21057 * a seperate step, since otherwise we won't be able to detect 21058 * circular union types in all cases. 21059 */ 21060 for (i = 0; i < nbItems; i++) { 21061 item = items[i]; 21062 switch (item->type) { 21063 case XML_SCHEMA_TYPE_SIMPLE: 21064 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21065 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21066 (xmlSchemaTypePtr) item); 21067 FIXHFAILURE; 21068 } 21069 break; 21070 default: 21071 break; 21072 } 21073 } 21074 if (pctxt->nberrors != 0) 21075 goto exit_error; 21076 /* 21077 * Detect circular union types. Note that this needs the variety to 21078 * be already computed. 21079 */ 21080 for (i = 0; i < nbItems; i++) { 21081 item = items[i]; 21082 switch (item->type) { 21083 case XML_SCHEMA_TYPE_SIMPLE: 21084 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21085 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21086 (xmlSchemaTypePtr) item); 21087 FIXHFAILURE; 21088 } 21089 break; 21090 default: 21091 break; 21092 } 21093 } 21094 if (pctxt->nberrors != 0) 21095 goto exit_error; 21096 21097 /* 21098 * Do the complete type fixup for simple types. 21099 */ 21100 for (i = 0; i < nbItems; i++) { 21101 item = items[i]; 21102 switch (item->type) { 21103 case XML_SCHEMA_TYPE_SIMPLE: 21104 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21105 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21106 FIXHFAILURE; 21107 } 21108 break; 21109 default: 21110 break; 21111 } 21112 } 21113 if (pctxt->nberrors != 0) 21114 goto exit_error; 21115 /* 21116 * At this point we need build and check all simple types. 21117 */ 21118 /* 21119 * Apply contraints for attribute declarations. 21120 */ 21121 for (i = 0; i < nbItems; i++) { 21122 item = items[i]; 21123 switch (item->type) { 21124 case XML_SCHEMA_TYPE_ATTRIBUTE: 21125 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21126 FIXHFAILURE; 21127 break; 21128 default: 21129 break; 21130 } 21131 } 21132 if (pctxt->nberrors != 0) 21133 goto exit_error; 21134 /* 21135 * Apply constraints for attribute uses. 21136 */ 21137 for (i = 0; i < nbItems; i++) { 21138 item = items[i]; 21139 switch (item->type) { 21140 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21141 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21142 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21143 WXS_ATTR_USE_CAST item); 21144 FIXHFAILURE; 21145 } 21146 break; 21147 default: 21148 break; 21149 } 21150 } 21151 if (pctxt->nberrors != 0) 21152 goto exit_error; 21153 21154 /* 21155 * Apply constraints for attribute group definitions. 21156 */ 21157 for (i = 0; i < nbItems; i++) { 21158 item = items[i]; 21159 switch (item->type) { 21160 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21161 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21162 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21163 { 21164 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21165 FIXHFAILURE; 21166 } 21167 break; 21168 default: 21169 break; 21170 } 21171 } 21172 if (pctxt->nberrors != 0) 21173 goto exit_error; 21174 21175 /* 21176 * Apply constraints for redefinitions. 21177 */ 21178 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21179 xmlSchemaCheckSRCRedefineSecond(pctxt); 21180 if (pctxt->nberrors != 0) 21181 goto exit_error; 21182 21183 /* 21184 * Complex types are builded and checked. 21185 */ 21186 for (i = 0; i < nbItems; i++) { 21187 item = con->pending->items[i]; 21188 switch (item->type) { 21189 case XML_SCHEMA_TYPE_COMPLEX: 21190 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21191 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21192 FIXHFAILURE; 21193 } 21194 break; 21195 default: 21196 break; 21197 } 21198 } 21199 if (pctxt->nberrors != 0) 21200 goto exit_error; 21201 21202 /* 21203 * The list could have changed, since xmlSchemaFixupComplexType() 21204 * will create particles and model groups in some cases. 21205 */ 21206 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21207 nbItems = con->pending->nbItems; 21208 21209 /* 21210 * Apply some constraints for element declarations. 21211 */ 21212 for (i = 0; i < nbItems; i++) { 21213 item = items[i]; 21214 switch (item->type) { 21215 case XML_SCHEMA_TYPE_ELEMENT: 21216 elemDecl = (xmlSchemaElementPtr) item; 21217 21218 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21219 { 21220 xmlSchemaCheckElementDeclComponent( 21221 (xmlSchemaElementPtr) elemDecl, pctxt); 21222 FIXHFAILURE; 21223 } 21224 21225 #ifdef WXS_ELEM_DECL_CONS_ENABLED 21226 /* 21227 * Schema Component Constraint: Element Declarations Consistent 21228 * Apply this constraint to local types of element declarations. 21229 */ 21230 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21231 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21232 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21233 { 21234 xmlSchemaCheckElementDeclConsistent(pctxt, 21235 WXS_BASIC_CAST elemDecl, 21236 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21237 NULL, NULL, 0); 21238 } 21239 #endif 21240 break; 21241 default: 21242 break; 21243 } 21244 } 21245 if (pctxt->nberrors != 0) 21246 goto exit_error; 21247 21248 /* 21249 * Finally we can build the automaton from the content model of 21250 * complex types. 21251 */ 21252 21253 for (i = 0; i < nbItems; i++) { 21254 item = items[i]; 21255 switch (item->type) { 21256 case XML_SCHEMA_TYPE_COMPLEX: 21257 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21258 /* FIXHFAILURE; */ 21259 break; 21260 default: 21261 break; 21262 } 21263 } 21264 if (pctxt->nberrors != 0) 21265 goto exit_error; 21266 /* 21267 * URGENT TODO: cos-element-consistent 21268 */ 21269 goto exit; 21270 21271 exit_error: 21272 ret = pctxt->err; 21273 goto exit; 21274 21275 exit_failure: 21276 ret = -1; 21277 21278 exit: 21279 /* 21280 * Reset the constructor. This is needed for XSI acquisition, since 21281 * those items will be processed over and over again for every XSI 21282 * if not cleared here. 21283 */ 21284 con->bucket = oldbucket; 21285 con->pending->nbItems = 0; 21286 if (con->substGroups != NULL) { 21287 xmlHashFree(con->substGroups, 21288 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 21289 con->substGroups = NULL; 21290 } 21291 if (con->redefs != NULL) { 21292 xmlSchemaRedefListFree(con->redefs); 21293 con->redefs = NULL; 21294 } 21295 return(ret); 21296 } 21297 /** 21298 * xmlSchemaParse: 21299 * @ctxt: a schema validation context 21300 * 21301 * parse a schema definition resource and build an internal 21302 * XML Shema struture which can be used to validate instances. 21303 * 21304 * Returns the internal XML Schema structure built from the resource or 21305 * NULL in case of error 21306 */ 21307 xmlSchemaPtr 21308 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21309 { 21310 xmlSchemaPtr mainSchema = NULL; 21311 xmlSchemaBucketPtr bucket = NULL; 21312 int res; 21313 21314 /* 21315 * This one is used if the schema to be parsed was specified via 21316 * the API; i.e. not automatically by the validated instance document. 21317 */ 21318 21319 xmlSchemaInitTypes(); 21320 21321 if (ctxt == NULL) 21322 return (NULL); 21323 21324 /* TODO: Init the context. Is this all we need?*/ 21325 ctxt->nberrors = 0; 21326 ctxt->err = 0; 21327 ctxt->counter = 0; 21328 21329 /* Create the *main* schema. */ 21330 mainSchema = xmlSchemaNewSchema(ctxt); 21331 if (mainSchema == NULL) 21332 goto exit_failure; 21333 /* 21334 * Create the schema constructor. 21335 */ 21336 if (ctxt->constructor == NULL) { 21337 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21338 if (ctxt->constructor == NULL) 21339 return(NULL); 21340 /* Take ownership of the constructor to be able to free it. */ 21341 ctxt->ownsConstructor = 1; 21342 } 21343 ctxt->constructor->mainSchema = mainSchema; 21344 /* 21345 * Locate and add the schema document. 21346 */ 21347 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21348 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21349 NULL, NULL, &bucket); 21350 if (res == -1) 21351 goto exit_failure; 21352 if (res != 0) 21353 goto exit; 21354 21355 if (bucket == NULL) { 21356 /* TODO: Error code, actually we failed to *locate* the schema. */ 21357 if (ctxt->URL) 21358 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21359 NULL, NULL, 21360 "Failed to locate the main schema resource at '%s'", 21361 ctxt->URL, NULL); 21362 else 21363 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21364 NULL, NULL, 21365 "Failed to locate the main schema resource", 21366 NULL, NULL); 21367 goto exit; 21368 } 21369 /* Then do the parsing for good. */ 21370 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21371 goto exit_failure; 21372 if (ctxt->nberrors != 0) 21373 goto exit; 21374 21375 mainSchema->doc = bucket->doc; 21376 mainSchema->preserve = ctxt->preserve; 21377 21378 ctxt->schema = mainSchema; 21379 21380 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21381 goto exit_failure; 21382 21383 /* 21384 * TODO: This is not nice, since we cannot distinguish from the 21385 * result if there was an internal error or not. 21386 */ 21387 exit: 21388 if (ctxt->nberrors != 0) { 21389 if (mainSchema) { 21390 xmlSchemaFree(mainSchema); 21391 mainSchema = NULL; 21392 } 21393 if (ctxt->constructor) { 21394 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21395 ctxt->constructor = NULL; 21396 ctxt->ownsConstructor = 0; 21397 } 21398 } 21399 ctxt->schema = NULL; 21400 return(mainSchema); 21401 exit_failure: 21402 /* 21403 * Quite verbose, but should catch internal errors, which were 21404 * not communitated. 21405 */ 21406 if (mainSchema) { 21407 xmlSchemaFree(mainSchema); 21408 mainSchema = NULL; 21409 } 21410 if (ctxt->constructor) { 21411 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21412 ctxt->constructor = NULL; 21413 ctxt->ownsConstructor = 0; 21414 } 21415 PERROR_INT2("xmlSchemaParse", 21416 "An internal error occured"); 21417 ctxt->schema = NULL; 21418 return(NULL); 21419 } 21420 21421 /** 21422 * xmlSchemaSetParserErrors: 21423 * @ctxt: a schema validation context 21424 * @err: the error callback 21425 * @warn: the warning callback 21426 * @ctx: contextual data for the callbacks 21427 * 21428 * Set the callback functions used to handle errors for a validation context 21429 */ 21430 void 21431 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21432 xmlSchemaValidityErrorFunc err, 21433 xmlSchemaValidityWarningFunc warn, void *ctx) 21434 { 21435 if (ctxt == NULL) 21436 return; 21437 ctxt->error = err; 21438 ctxt->warning = warn; 21439 ctxt->errCtxt = ctx; 21440 if (ctxt->vctxt != NULL) 21441 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21442 } 21443 21444 /** 21445 * xmlSchemaSetParserStructuredErrors: 21446 * @ctxt: a schema parser context 21447 * @serror: the structured error function 21448 * @ctx: the functions context 21449 * 21450 * Set the structured error callback 21451 */ 21452 void 21453 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21454 xmlStructuredErrorFunc serror, 21455 void *ctx) 21456 { 21457 if (ctxt == NULL) 21458 return; 21459 ctxt->serror = serror; 21460 ctxt->errCtxt = ctx; 21461 if (ctxt->vctxt != NULL) 21462 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21463 } 21464 21465 /** 21466 * xmlSchemaGetParserErrors: 21467 * @ctxt: a XMl-Schema parser context 21468 * @err: the error callback result 21469 * @warn: the warning callback result 21470 * @ctx: contextual data for the callbacks result 21471 * 21472 * Get the callback information used to handle errors for a parser context 21473 * 21474 * Returns -1 in case of failure, 0 otherwise 21475 */ 21476 int 21477 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21478 xmlSchemaValidityErrorFunc * err, 21479 xmlSchemaValidityWarningFunc * warn, void **ctx) 21480 { 21481 if (ctxt == NULL) 21482 return(-1); 21483 if (err != NULL) 21484 *err = ctxt->error; 21485 if (warn != NULL) 21486 *warn = ctxt->warning; 21487 if (ctx != NULL) 21488 *ctx = ctxt->errCtxt; 21489 return(0); 21490 } 21491 21492 /** 21493 * xmlSchemaFacetTypeToString: 21494 * @type: the facet type 21495 * 21496 * Convert the xmlSchemaTypeType to a char string. 21497 * 21498 * Returns the char string representation of the facet type if the 21499 * type is a facet and an "Internal Error" string otherwise. 21500 */ 21501 static const xmlChar * 21502 xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21503 { 21504 switch (type) { 21505 case XML_SCHEMA_FACET_PATTERN: 21506 return (BAD_CAST "pattern"); 21507 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21508 return (BAD_CAST "maxExclusive"); 21509 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21510 return (BAD_CAST "maxInclusive"); 21511 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21512 return (BAD_CAST "minExclusive"); 21513 case XML_SCHEMA_FACET_MININCLUSIVE: 21514 return (BAD_CAST "minInclusive"); 21515 case XML_SCHEMA_FACET_WHITESPACE: 21516 return (BAD_CAST "whiteSpace"); 21517 case XML_SCHEMA_FACET_ENUMERATION: 21518 return (BAD_CAST "enumeration"); 21519 case XML_SCHEMA_FACET_LENGTH: 21520 return (BAD_CAST "length"); 21521 case XML_SCHEMA_FACET_MAXLENGTH: 21522 return (BAD_CAST "maxLength"); 21523 case XML_SCHEMA_FACET_MINLENGTH: 21524 return (BAD_CAST "minLength"); 21525 case XML_SCHEMA_FACET_TOTALDIGITS: 21526 return (BAD_CAST "totalDigits"); 21527 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21528 return (BAD_CAST "fractionDigits"); 21529 default: 21530 break; 21531 } 21532 return (BAD_CAST "Internal Error"); 21533 } 21534 21535 static xmlSchemaWhitespaceValueType 21536 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21537 { 21538 /* 21539 * The normalization type can be changed only for types which are derived 21540 * from xsd:string. 21541 */ 21542 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21543 /* 21544 * Note that we assume a whitespace of preserve for anySimpleType. 21545 */ 21546 if ((type->builtInType == XML_SCHEMAS_STRING) || 21547 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21548 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21549 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21550 return(XML_SCHEMA_WHITESPACE_REPLACE); 21551 else { 21552 /* 21553 * For all `atomic` datatypes other than string (and types `derived` 21554 * by `restriction` from it) the value of whiteSpace is fixed to 21555 * collapse 21556 * Note that this includes built-in list datatypes. 21557 */ 21558 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21559 } 21560 } else if (WXS_IS_LIST(type)) { 21561 /* 21562 * For list types the facet "whiteSpace" is fixed to "collapse". 21563 */ 21564 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21565 } else if (WXS_IS_UNION(type)) { 21566 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21567 } else if (WXS_IS_ATOMIC(type)) { 21568 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21569 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21570 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21571 return (XML_SCHEMA_WHITESPACE_REPLACE); 21572 else 21573 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21574 } 21575 return (-1); 21576 } 21577 21578 /************************************************************************ 21579 * * 21580 * Simple type validation * 21581 * * 21582 ************************************************************************/ 21583 21584 21585 /************************************************************************ 21586 * * 21587 * DOM Validation code * 21588 * * 21589 ************************************************************************/ 21590 21591 /** 21592 * xmlSchemaAssembleByLocation: 21593 * @pctxt: a schema parser context 21594 * @vctxt: a schema validation context 21595 * @schema: the existing schema 21596 * @node: the node that fired the assembling 21597 * @nsName: the namespace name of the new schema 21598 * @location: the location of the schema 21599 * 21600 * Expands an existing schema by an additional schema. 21601 * 21602 * Returns 0 if the new schema is correct, a positive error code 21603 * number otherwise and -1 in case of an internal or API error. 21604 */ 21605 static int 21606 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21607 xmlSchemaPtr schema, 21608 xmlNodePtr node, 21609 const xmlChar *nsName, 21610 const xmlChar *location) 21611 { 21612 int ret = 0; 21613 xmlSchemaParserCtxtPtr pctxt; 21614 xmlSchemaBucketPtr bucket = NULL; 21615 21616 if ((vctxt == NULL) || (schema == NULL)) 21617 return (-1); 21618 21619 if (vctxt->pctxt == NULL) { 21620 VERROR_INT("xmlSchemaAssembleByLocation", 21621 "no parser context available"); 21622 return(-1); 21623 } 21624 pctxt = vctxt->pctxt; 21625 if (pctxt->constructor == NULL) { 21626 PERROR_INT("xmlSchemaAssembleByLocation", 21627 "no constructor"); 21628 return(-1); 21629 } 21630 /* 21631 * Acquire the schema document. 21632 */ 21633 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21634 location, node); 21635 /* 21636 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21637 * the process will automatically change this to 21638 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21639 */ 21640 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21641 location, NULL, NULL, 0, node, NULL, nsName, 21642 &bucket); 21643 if (ret != 0) 21644 return(ret); 21645 if (bucket == NULL) { 21646 /* 21647 * Generate a warning that the document could not be located. 21648 */ 21649 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21650 node, NULL, 21651 "The document at location '%s' could not be acquired", 21652 location, NULL, NULL); 21653 return(ret); 21654 } 21655 /* 21656 * The first located schema will be handled as if all other 21657 * schemas imported by XSI were imported by this first schema. 21658 */ 21659 if ((bucket != NULL) && 21660 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21661 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21662 /* 21663 * TODO: Is this handled like an import? I.e. is it not an error 21664 * if the schema cannot be located? 21665 */ 21666 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21667 return(0); 21668 /* 21669 * We will reuse the parser context for every schema imported 21670 * directly via XSI. So reset the context. 21671 */ 21672 pctxt->nberrors = 0; 21673 pctxt->err = 0; 21674 pctxt->doc = bucket->doc; 21675 21676 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21677 if (ret == -1) { 21678 pctxt->doc = NULL; 21679 goto exit_failure; 21680 } 21681 /* Paranoid error channelling. */ 21682 if ((ret == 0) && (pctxt->nberrors != 0)) 21683 ret = pctxt->err; 21684 if (pctxt->nberrors == 0) { 21685 /* 21686 * Only bother to fixup pending components, if there was 21687 * no error yet. 21688 * For every XSI acquired schema (and its sub-schemata) we will 21689 * fixup the components. 21690 */ 21691 xmlSchemaFixupComponents(pctxt, bucket); 21692 ret = pctxt->err; 21693 /* 21694 * Not nice, but we need somehow to channel the schema parser 21695 * error to the validation context. 21696 */ 21697 if ((ret != 0) && (vctxt->err == 0)) 21698 vctxt->err = ret; 21699 vctxt->nberrors += pctxt->nberrors; 21700 } else { 21701 /* Add to validation error sum. */ 21702 vctxt->nberrors += pctxt->nberrors; 21703 } 21704 pctxt->doc = NULL; 21705 return(ret); 21706 exit_failure: 21707 pctxt->doc = NULL; 21708 return (-1); 21709 } 21710 21711 static xmlSchemaAttrInfoPtr 21712 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21713 int metaType) 21714 { 21715 if (vctxt->nbAttrInfos == 0) 21716 return (NULL); 21717 { 21718 int i; 21719 xmlSchemaAttrInfoPtr iattr; 21720 21721 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21722 iattr = vctxt->attrInfos[i]; 21723 if (iattr->metaType == metaType) 21724 return (iattr); 21725 } 21726 21727 } 21728 return (NULL); 21729 } 21730 21731 /** 21732 * xmlSchemaAssembleByXSI: 21733 * @vctxt: a schema validation context 21734 * 21735 * Expands an existing schema by an additional schema using 21736 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21737 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21738 * must be set to 1. 21739 * 21740 * Returns 0 if the new schema is correct, a positive error code 21741 * number otherwise and -1 in case of an internal or API error. 21742 */ 21743 static int 21744 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21745 { 21746 const xmlChar *cur, *end; 21747 const xmlChar *nsname = NULL, *location; 21748 int count = 0; 21749 int ret = 0; 21750 xmlSchemaAttrInfoPtr iattr; 21751 21752 /* 21753 * Parse the value; we will assume an even number of values 21754 * to be given (this is how Xerces and XSV work). 21755 * 21756 * URGENT TODO: !! This needs to work for both 21757 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21758 * element !! 21759 */ 21760 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21761 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21762 if (iattr == NULL) 21763 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21764 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21765 if (iattr == NULL) 21766 return (0); 21767 cur = iattr->value; 21768 do { 21769 /* 21770 * TODO: Move the string parsing mechanism away from here. 21771 */ 21772 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21773 /* 21774 * Get the namespace name. 21775 */ 21776 while (IS_BLANK_CH(*cur)) 21777 cur++; 21778 end = cur; 21779 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21780 end++; 21781 if (end == cur) 21782 break; 21783 count++; /* TODO: Don't use the schema's dict. */ 21784 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21785 cur = end; 21786 } 21787 /* 21788 * Get the URI. 21789 */ 21790 while (IS_BLANK_CH(*cur)) 21791 cur++; 21792 end = cur; 21793 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21794 end++; 21795 if (end == cur) { 21796 if (iattr->metaType == 21797 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21798 { 21799 /* 21800 * If using @schemaLocation then tuples are expected. 21801 * I.e. the namespace name *and* the document's URI. 21802 */ 21803 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21804 iattr->node, NULL, 21805 "The value must consist of tuples: the target namespace " 21806 "name and the document's URI", NULL, NULL, NULL); 21807 } 21808 break; 21809 } 21810 count++; /* TODO: Don't use the schema's dict. */ 21811 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21812 cur = end; 21813 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21814 iattr->node, nsname, location); 21815 if (ret == -1) { 21816 VERROR_INT("xmlSchemaAssembleByXSI", 21817 "assembling schemata"); 21818 return (-1); 21819 } 21820 } while (*cur != 0); 21821 return (ret); 21822 } 21823 21824 static const xmlChar * 21825 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21826 const xmlChar *prefix) 21827 { 21828 if (vctxt->sax != NULL) { 21829 int i, j; 21830 xmlSchemaNodeInfoPtr inode; 21831 21832 for (i = vctxt->depth; i >= 0; i--) { 21833 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21834 inode = vctxt->elemInfos[i]; 21835 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21836 if (((prefix == NULL) && 21837 (inode->nsBindings[j] == NULL)) || 21838 ((prefix != NULL) && xmlStrEqual(prefix, 21839 inode->nsBindings[j]))) { 21840 21841 /* 21842 * Note that the namespace bindings are already 21843 * in a string dict. 21844 */ 21845 return (inode->nsBindings[j+1]); 21846 } 21847 } 21848 } 21849 } 21850 return (NULL); 21851 #ifdef LIBXML_READER_ENABLED 21852 } else if (vctxt->reader != NULL) { 21853 xmlChar *nsName; 21854 21855 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21856 if (nsName != NULL) { 21857 const xmlChar *ret; 21858 21859 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21860 xmlFree(nsName); 21861 return (ret); 21862 } else 21863 return (NULL); 21864 #endif 21865 } else { 21866 xmlNsPtr ns; 21867 21868 if ((vctxt->inode->node == NULL) || 21869 (vctxt->inode->node->doc == NULL)) { 21870 VERROR_INT("xmlSchemaLookupNamespace", 21871 "no node or node's doc avaliable"); 21872 return (NULL); 21873 } 21874 ns = xmlSearchNs(vctxt->inode->node->doc, 21875 vctxt->inode->node, prefix); 21876 if (ns != NULL) 21877 return (ns->href); 21878 return (NULL); 21879 } 21880 } 21881 21882 /* 21883 * This one works on the schema of the validation context. 21884 */ 21885 static int 21886 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21887 xmlSchemaPtr schema, 21888 xmlNodePtr node, 21889 const xmlChar *value, 21890 xmlSchemaValPtr *val, 21891 int valNeeded) 21892 { 21893 int ret; 21894 21895 if (vctxt && (vctxt->schema == NULL)) { 21896 VERROR_INT("xmlSchemaValidateNotation", 21897 "a schema is needed on the validation context"); 21898 return (-1); 21899 } 21900 ret = xmlValidateQName(value, 1); 21901 if (ret != 0) 21902 return (ret); 21903 { 21904 xmlChar *localName = NULL; 21905 xmlChar *prefix = NULL; 21906 21907 localName = xmlSplitQName2(value, &prefix); 21908 if (prefix != NULL) { 21909 const xmlChar *nsName = NULL; 21910 21911 if (vctxt != NULL) 21912 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21913 else if (node != NULL) { 21914 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21915 if (ns != NULL) 21916 nsName = ns->href; 21917 } else { 21918 xmlFree(prefix); 21919 xmlFree(localName); 21920 return (1); 21921 } 21922 if (nsName == NULL) { 21923 xmlFree(prefix); 21924 xmlFree(localName); 21925 return (1); 21926 } 21927 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21928 if ((valNeeded) && (val != NULL)) { 21929 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21930 xmlStrdup(nsName)); 21931 if (*val == NULL) 21932 ret = -1; 21933 } 21934 } else 21935 ret = 1; 21936 xmlFree(prefix); 21937 xmlFree(localName); 21938 } else { 21939 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21940 if (valNeeded && (val != NULL)) { 21941 (*val) = xmlSchemaNewNOTATIONValue( 21942 BAD_CAST xmlStrdup(value), NULL); 21943 if (*val == NULL) 21944 ret = -1; 21945 } 21946 } else 21947 return (1); 21948 } 21949 } 21950 return (ret); 21951 } 21952 21953 static int 21954 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21955 const xmlChar* lname, 21956 const xmlChar* nsname) 21957 { 21958 int i; 21959 21960 lname = xmlDictLookup(vctxt->dict, lname, -1); 21961 if (lname == NULL) 21962 return(-1); 21963 if (nsname != NULL) { 21964 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21965 if (nsname == NULL) 21966 return(-1); 21967 } 21968 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21969 if ((vctxt->nodeQNames->items [i] == lname) && 21970 (vctxt->nodeQNames->items[i +1] == nsname)) 21971 /* Already there */ 21972 return(i); 21973 } 21974 /* Add new entry. */ 21975 i = vctxt->nodeQNames->nbItems; 21976 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21977 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21978 return(i); 21979 } 21980 21981 /************************************************************************ 21982 * * 21983 * Validation of identity-constraints (IDC) * 21984 * * 21985 ************************************************************************/ 21986 21987 /** 21988 * xmlSchemaAugmentIDC: 21989 * @idcDef: the IDC definition 21990 * 21991 * Creates an augmented IDC definition item. 21992 * 21993 * Returns the item, or NULL on internal errors. 21994 */ 21995 static void 21996 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, 21997 xmlSchemaValidCtxtPtr vctxt) 21998 { 21999 xmlSchemaIDCAugPtr aidc; 22000 22001 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 22002 if (aidc == NULL) { 22003 xmlSchemaVErrMemory(vctxt, 22004 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 22005 NULL); 22006 return; 22007 } 22008 aidc->keyrefDepth = -1; 22009 aidc->def = idcDef; 22010 aidc->next = NULL; 22011 if (vctxt->aidcs == NULL) 22012 vctxt->aidcs = aidc; 22013 else { 22014 aidc->next = vctxt->aidcs; 22015 vctxt->aidcs = aidc; 22016 } 22017 /* 22018 * Save if we have keyrefs at all. 22019 */ 22020 if ((vctxt->hasKeyrefs == 0) && 22021 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 22022 vctxt->hasKeyrefs = 1; 22023 } 22024 22025 /** 22026 * xmlSchemaAugmentImportedIDC: 22027 * @imported: the imported schema 22028 * 22029 * Creates an augmented IDC definition for the imported schema. 22030 */ 22031 static void 22032 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) { 22033 if (imported->schema->idcDef != NULL) { 22034 xmlHashScan(imported->schema->idcDef , 22035 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); 22036 } 22037 } 22038 22039 /** 22040 * xmlSchemaIDCNewBinding: 22041 * @idcDef: the IDC definition of this binding 22042 * 22043 * Creates a new IDC binding. 22044 * 22045 * Returns the new IDC binding, NULL on internal errors. 22046 */ 22047 static xmlSchemaPSVIIDCBindingPtr 22048 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22049 { 22050 xmlSchemaPSVIIDCBindingPtr ret; 22051 22052 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22053 sizeof(xmlSchemaPSVIIDCBinding)); 22054 if (ret == NULL) { 22055 xmlSchemaVErrMemory(NULL, 22056 "allocating a PSVI IDC binding item", NULL); 22057 return (NULL); 22058 } 22059 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22060 ret->definition = idcDef; 22061 return (ret); 22062 } 22063 22064 /** 22065 * xmlSchemaIDCStoreNodeTableItem: 22066 * @vctxt: the WXS validation context 22067 * @item: the IDC node table item 22068 * 22069 * The validation context is used to store IDC node table items. 22070 * They are stored to avoid copying them if IDC node-tables are merged 22071 * with corresponding parent IDC node-tables (bubbling). 22072 * 22073 * Returns 0 if succeeded, -1 on internal errors. 22074 */ 22075 static int 22076 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22077 xmlSchemaPSVIIDCNodePtr item) 22078 { 22079 /* 22080 * Add to gobal list. 22081 */ 22082 if (vctxt->idcNodes == NULL) { 22083 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22084 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22085 if (vctxt->idcNodes == NULL) { 22086 xmlSchemaVErrMemory(vctxt, 22087 "allocating the IDC node table item list", NULL); 22088 return (-1); 22089 } 22090 vctxt->sizeIdcNodes = 20; 22091 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22092 vctxt->sizeIdcNodes *= 2; 22093 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22094 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22095 sizeof(xmlSchemaPSVIIDCNodePtr)); 22096 if (vctxt->idcNodes == NULL) { 22097 xmlSchemaVErrMemory(vctxt, 22098 "re-allocating the IDC node table item list", NULL); 22099 return (-1); 22100 } 22101 } 22102 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22103 22104 return (0); 22105 } 22106 22107 /** 22108 * xmlSchemaIDCStoreKey: 22109 * @vctxt: the WXS validation context 22110 * @item: the IDC key 22111 * 22112 * The validation context is used to store an IDC key. 22113 * 22114 * Returns 0 if succeeded, -1 on internal errors. 22115 */ 22116 static int 22117 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22118 xmlSchemaPSVIIDCKeyPtr key) 22119 { 22120 /* 22121 * Add to gobal list. 22122 */ 22123 if (vctxt->idcKeys == NULL) { 22124 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22125 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22126 if (vctxt->idcKeys == NULL) { 22127 xmlSchemaVErrMemory(vctxt, 22128 "allocating the IDC key storage list", NULL); 22129 return (-1); 22130 } 22131 vctxt->sizeIdcKeys = 40; 22132 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22133 vctxt->sizeIdcKeys *= 2; 22134 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22135 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22136 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22137 if (vctxt->idcKeys == NULL) { 22138 xmlSchemaVErrMemory(vctxt, 22139 "re-allocating the IDC key storage list", NULL); 22140 return (-1); 22141 } 22142 } 22143 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22144 22145 return (0); 22146 } 22147 22148 /** 22149 * xmlSchemaIDCAppendNodeTableItem: 22150 * @bind: the IDC binding 22151 * @ntItem: the node-table item 22152 * 22153 * Appends the IDC node-table item to the binding. 22154 * 22155 * Returns 0 on success and -1 on internal errors. 22156 */ 22157 static int 22158 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22159 xmlSchemaPSVIIDCNodePtr ntItem) 22160 { 22161 if (bind->nodeTable == NULL) { 22162 bind->sizeNodes = 10; 22163 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22164 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22165 if (bind->nodeTable == NULL) { 22166 xmlSchemaVErrMemory(NULL, 22167 "allocating an array of IDC node-table items", NULL); 22168 return(-1); 22169 } 22170 } else if (bind->sizeNodes <= bind->nbNodes) { 22171 bind->sizeNodes *= 2; 22172 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22173 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22174 sizeof(xmlSchemaPSVIIDCNodePtr)); 22175 if (bind->nodeTable == NULL) { 22176 xmlSchemaVErrMemory(NULL, 22177 "re-allocating an array of IDC node-table items", NULL); 22178 return(-1); 22179 } 22180 } 22181 bind->nodeTable[bind->nbNodes++] = ntItem; 22182 return(0); 22183 } 22184 22185 /** 22186 * xmlSchemaIDCAcquireBinding: 22187 * @vctxt: the WXS validation context 22188 * @matcher: the IDC matcher 22189 * 22190 * Looks up an PSVI IDC binding, for the IDC definition and 22191 * of the given matcher. If none found, a new one is created 22192 * and added to the IDC table. 22193 * 22194 * Returns an IDC binding or NULL on internal errors. 22195 */ 22196 static xmlSchemaPSVIIDCBindingPtr 22197 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22198 xmlSchemaIDCMatcherPtr matcher) 22199 { 22200 xmlSchemaNodeInfoPtr ielem; 22201 22202 ielem = vctxt->elemInfos[matcher->depth]; 22203 22204 if (ielem->idcTable == NULL) { 22205 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22206 if (ielem->idcTable == NULL) 22207 return (NULL); 22208 return(ielem->idcTable); 22209 } else { 22210 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22211 22212 bind = ielem->idcTable; 22213 do { 22214 if (bind->definition == matcher->aidc->def) 22215 return(bind); 22216 if (bind->next == NULL) { 22217 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22218 if (bind->next == NULL) 22219 return (NULL); 22220 return(bind->next); 22221 } 22222 bind = bind->next; 22223 } while (bind != NULL); 22224 } 22225 return (NULL); 22226 } 22227 22228 static xmlSchemaItemListPtr 22229 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22230 xmlSchemaIDCMatcherPtr matcher) 22231 { 22232 if (matcher->targets == NULL) 22233 matcher->targets = xmlSchemaItemListCreate(); 22234 return(matcher->targets); 22235 } 22236 22237 /** 22238 * xmlSchemaIDCFreeKey: 22239 * @key: the IDC key 22240 * 22241 * Frees an IDC key together with its compiled value. 22242 */ 22243 static void 22244 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22245 { 22246 if (key->val != NULL) 22247 xmlSchemaFreeValue(key->val); 22248 xmlFree(key); 22249 } 22250 22251 /** 22252 * xmlSchemaIDCFreeBinding: 22253 * 22254 * Frees an IDC binding. Note that the node table-items 22255 * are not freed. 22256 */ 22257 static void 22258 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22259 { 22260 if (bind->nodeTable != NULL) 22261 xmlFree(bind->nodeTable); 22262 if (bind->dupls != NULL) 22263 xmlSchemaItemListFree(bind->dupls); 22264 xmlFree(bind); 22265 } 22266 22267 /** 22268 * xmlSchemaIDCFreeIDCTable: 22269 * @bind: the first IDC binding in the list 22270 * 22271 * Frees an IDC table, i.e. all the IDC bindings in the list. 22272 */ 22273 static void 22274 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22275 { 22276 xmlSchemaPSVIIDCBindingPtr prev; 22277 22278 while (bind != NULL) { 22279 prev = bind; 22280 bind = bind->next; 22281 xmlSchemaIDCFreeBinding(prev); 22282 } 22283 } 22284 22285 /** 22286 * xmlSchemaIDCFreeMatcherList: 22287 * @matcher: the first IDC matcher in the list 22288 * 22289 * Frees a list of IDC matchers. 22290 */ 22291 static void 22292 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22293 { 22294 xmlSchemaIDCMatcherPtr next; 22295 22296 while (matcher != NULL) { 22297 next = matcher->next; 22298 if (matcher->keySeqs != NULL) { 22299 int i; 22300 for (i = 0; i < matcher->sizeKeySeqs; i++) 22301 if (matcher->keySeqs[i] != NULL) 22302 xmlFree(matcher->keySeqs[i]); 22303 xmlFree(matcher->keySeqs); 22304 } 22305 if (matcher->targets != NULL) { 22306 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22307 int i; 22308 xmlSchemaPSVIIDCNodePtr idcNode; 22309 /* 22310 * Node-table items for keyrefs are not stored globally 22311 * to the validation context, since they are not bubbled. 22312 * We need to free them here. 22313 */ 22314 for (i = 0; i < matcher->targets->nbItems; i++) { 22315 idcNode = 22316 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22317 xmlFree(idcNode->keys); 22318 xmlFree(idcNode); 22319 } 22320 } 22321 xmlSchemaItemListFree(matcher->targets); 22322 } 22323 xmlFree(matcher); 22324 matcher = next; 22325 } 22326 } 22327 22328 /** 22329 * xmlSchemaIDCReleaseMatcherList: 22330 * @vctxt: the WXS validation context 22331 * @matcher: the first IDC matcher in the list 22332 * 22333 * Caches a list of IDC matchers for reuse. 22334 */ 22335 static void 22336 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22337 xmlSchemaIDCMatcherPtr matcher) 22338 { 22339 xmlSchemaIDCMatcherPtr next; 22340 22341 while (matcher != NULL) { 22342 next = matcher->next; 22343 if (matcher->keySeqs != NULL) { 22344 int i; 22345 /* 22346 * Don't free the array, but only the content. 22347 */ 22348 for (i = 0; i < matcher->sizeKeySeqs; i++) 22349 if (matcher->keySeqs[i] != NULL) { 22350 xmlFree(matcher->keySeqs[i]); 22351 matcher->keySeqs[i] = NULL; 22352 } 22353 } 22354 if (matcher->targets) { 22355 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22356 int i; 22357 xmlSchemaPSVIIDCNodePtr idcNode; 22358 /* 22359 * Node-table items for keyrefs are not stored globally 22360 * to the validation context, since they are not bubbled. 22361 * We need to free them here. 22362 */ 22363 for (i = 0; i < matcher->targets->nbItems; i++) { 22364 idcNode = 22365 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22366 xmlFree(idcNode->keys); 22367 xmlFree(idcNode); 22368 } 22369 } 22370 xmlSchemaItemListFree(matcher->targets); 22371 matcher->targets = NULL; 22372 } 22373 matcher->next = NULL; 22374 /* 22375 * Cache the matcher. 22376 */ 22377 if (vctxt->idcMatcherCache != NULL) 22378 matcher->nextCached = vctxt->idcMatcherCache; 22379 vctxt->idcMatcherCache = matcher; 22380 22381 matcher = next; 22382 } 22383 } 22384 22385 /** 22386 * xmlSchemaIDCAddStateObject: 22387 * @vctxt: the WXS validation context 22388 * @matcher: the IDC matcher 22389 * @sel: the XPath information 22390 * @parent: the parent "selector" state object if any 22391 * @type: "selector" or "field" 22392 * 22393 * Creates/reuses and activates state objects for the given 22394 * XPath information; if the XPath expression consists of unions, 22395 * multiple state objects are created for every unioned expression. 22396 * 22397 * Returns 0 on success and -1 on internal errors. 22398 */ 22399 static int 22400 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22401 xmlSchemaIDCMatcherPtr matcher, 22402 xmlSchemaIDCSelectPtr sel, 22403 int type) 22404 { 22405 xmlSchemaIDCStateObjPtr sto; 22406 22407 /* 22408 * Reuse the state objects from the pool. 22409 */ 22410 if (vctxt->xpathStatePool != NULL) { 22411 sto = vctxt->xpathStatePool; 22412 vctxt->xpathStatePool = sto->next; 22413 sto->next = NULL; 22414 } else { 22415 /* 22416 * Create a new state object. 22417 */ 22418 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22419 if (sto == NULL) { 22420 xmlSchemaVErrMemory(NULL, 22421 "allocating an IDC state object", NULL); 22422 return (-1); 22423 } 22424 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22425 } 22426 /* 22427 * Add to global list. 22428 */ 22429 if (vctxt->xpathStates != NULL) 22430 sto->next = vctxt->xpathStates; 22431 vctxt->xpathStates = sto; 22432 22433 /* 22434 * Free the old xpath validation context. 22435 */ 22436 if (sto->xpathCtxt != NULL) 22437 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22438 22439 /* 22440 * Create a new XPath (pattern) validation context. 22441 */ 22442 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22443 (xmlPatternPtr) sel->xpathComp); 22444 if (sto->xpathCtxt == NULL) { 22445 VERROR_INT("xmlSchemaIDCAddStateObject", 22446 "failed to create an XPath validation context"); 22447 return (-1); 22448 } 22449 sto->type = type; 22450 sto->depth = vctxt->depth; 22451 sto->matcher = matcher; 22452 sto->sel = sel; 22453 sto->nbHistory = 0; 22454 22455 #ifdef DEBUG_IDC 22456 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22457 sto->sel->xpath); 22458 #endif 22459 return (0); 22460 } 22461 22462 /** 22463 * xmlSchemaXPathEvaluate: 22464 * @vctxt: the WXS validation context 22465 * @nodeType: the nodeType of the current node 22466 * 22467 * Evaluates all active XPath state objects. 22468 * 22469 * Returns the number of IC "field" state objects which resolved to 22470 * this node, 0 if none resolved and -1 on internal errors. 22471 */ 22472 static int 22473 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22474 xmlElementType nodeType) 22475 { 22476 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22477 int res, resolved = 0, depth = vctxt->depth; 22478 22479 if (vctxt->xpathStates == NULL) 22480 return (0); 22481 22482 if (nodeType == XML_ATTRIBUTE_NODE) 22483 depth++; 22484 #ifdef DEBUG_IDC 22485 { 22486 xmlChar *str = NULL; 22487 xmlGenericError(xmlGenericErrorContext, 22488 "IDC: EVAL on %s, depth %d, type %d\n", 22489 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22490 vctxt->inode->localName), depth, nodeType); 22491 FREE_AND_NULL(str) 22492 } 22493 #endif 22494 /* 22495 * Process all active XPath state objects. 22496 */ 22497 first = vctxt->xpathStates; 22498 sto = first; 22499 while (sto != head) { 22500 #ifdef DEBUG_IDC 22501 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22502 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22503 sto->matcher->aidc->def->name, sto->sel->xpath); 22504 else 22505 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22506 sto->matcher->aidc->def->name, sto->sel->xpath); 22507 #endif 22508 if (nodeType == XML_ELEMENT_NODE) 22509 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22510 vctxt->inode->localName, vctxt->inode->nsName); 22511 else 22512 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22513 vctxt->inode->localName, vctxt->inode->nsName); 22514 22515 if (res == -1) { 22516 VERROR_INT("xmlSchemaXPathEvaluate", 22517 "calling xmlStreamPush()"); 22518 return (-1); 22519 } 22520 if (res == 0) 22521 goto next_sto; 22522 /* 22523 * Full match. 22524 */ 22525 #ifdef DEBUG_IDC 22526 xmlGenericError(xmlGenericErrorContext, "IDC: " 22527 "MATCH\n"); 22528 #endif 22529 /* 22530 * Register a match in the state object history. 22531 */ 22532 if (sto->history == NULL) { 22533 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22534 if (sto->history == NULL) { 22535 xmlSchemaVErrMemory(NULL, 22536 "allocating the state object history", NULL); 22537 return(-1); 22538 } 22539 sto->sizeHistory = 5; 22540 } else if (sto->sizeHistory <= sto->nbHistory) { 22541 sto->sizeHistory *= 2; 22542 sto->history = (int *) xmlRealloc(sto->history, 22543 sto->sizeHistory * sizeof(int)); 22544 if (sto->history == NULL) { 22545 xmlSchemaVErrMemory(NULL, 22546 "re-allocating the state object history", NULL); 22547 return(-1); 22548 } 22549 } 22550 sto->history[sto->nbHistory++] = depth; 22551 22552 #ifdef DEBUG_IDC 22553 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22554 vctxt->depth); 22555 #endif 22556 22557 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22558 xmlSchemaIDCSelectPtr sel; 22559 /* 22560 * Activate state objects for the IDC fields of 22561 * the IDC selector. 22562 */ 22563 #ifdef DEBUG_IDC 22564 xmlGenericError(xmlGenericErrorContext, "IDC: " 22565 "activating field states\n"); 22566 #endif 22567 sel = sto->matcher->aidc->def->fields; 22568 while (sel != NULL) { 22569 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22570 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22571 return (-1); 22572 sel = sel->next; 22573 } 22574 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22575 /* 22576 * An IDC key node was found by the IDC field. 22577 */ 22578 #ifdef DEBUG_IDC 22579 xmlGenericError(xmlGenericErrorContext, 22580 "IDC: key found\n"); 22581 #endif 22582 /* 22583 * Notify that the character value of this node is 22584 * needed. 22585 */ 22586 if (resolved == 0) { 22587 if ((vctxt->inode->flags & 22588 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22589 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22590 } 22591 resolved++; 22592 } 22593 next_sto: 22594 if (sto->next == NULL) { 22595 /* 22596 * Evaluate field state objects created on this node as well. 22597 */ 22598 head = first; 22599 sto = vctxt->xpathStates; 22600 } else 22601 sto = sto->next; 22602 } 22603 return (resolved); 22604 } 22605 22606 static const xmlChar * 22607 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22608 xmlChar **buf, 22609 xmlSchemaPSVIIDCKeyPtr *seq, 22610 int count) 22611 { 22612 int i, res; 22613 xmlChar *value = NULL; 22614 22615 *buf = xmlStrdup(BAD_CAST "["); 22616 for (i = 0; i < count; i++) { 22617 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22618 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22619 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22620 &value); 22621 if (res == 0) 22622 *buf = xmlStrcat(*buf, BAD_CAST value); 22623 else { 22624 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22625 "failed to compute a canonical value"); 22626 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22627 } 22628 if (i < count -1) 22629 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22630 else 22631 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22632 if (value != NULL) { 22633 xmlFree(value); 22634 value = NULL; 22635 } 22636 } 22637 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22638 22639 return (BAD_CAST *buf); 22640 } 22641 22642 /** 22643 * xmlSchemaXPathPop: 22644 * @vctxt: the WXS validation context 22645 * 22646 * Pops all XPath states. 22647 * 22648 * Returns 0 on success and -1 on internal errors. 22649 */ 22650 static int 22651 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22652 { 22653 xmlSchemaIDCStateObjPtr sto; 22654 int res; 22655 22656 if (vctxt->xpathStates == NULL) 22657 return(0); 22658 sto = vctxt->xpathStates; 22659 do { 22660 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22661 if (res == -1) 22662 return (-1); 22663 sto = sto->next; 22664 } while (sto != NULL); 22665 return(0); 22666 } 22667 22668 /** 22669 * xmlSchemaXPathProcessHistory: 22670 * @vctxt: the WXS validation context 22671 * @type: the simple/complex type of the current node if any at all 22672 * @val: the precompiled value 22673 * 22674 * Processes and pops the history items of the IDC state objects. 22675 * IDC key-sequences are validated/created on IDC bindings. 22676 * 22677 * Returns 0 on success and -1 on internal errors. 22678 */ 22679 static int 22680 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22681 int depth) 22682 { 22683 xmlSchemaIDCStateObjPtr sto, nextsto; 22684 int res, matchDepth; 22685 xmlSchemaPSVIIDCKeyPtr key = NULL; 22686 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22687 22688 if (vctxt->xpathStates == NULL) 22689 return (0); 22690 sto = vctxt->xpathStates; 22691 22692 #ifdef DEBUG_IDC 22693 { 22694 xmlChar *str = NULL; 22695 xmlGenericError(xmlGenericErrorContext, 22696 "IDC: BACK on %s, depth %d\n", 22697 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22698 vctxt->inode->localName), vctxt->depth); 22699 FREE_AND_NULL(str) 22700 } 22701 #endif 22702 /* 22703 * Evaluate the state objects. 22704 */ 22705 while (sto != NULL) { 22706 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22707 if (res == -1) { 22708 VERROR_INT("xmlSchemaXPathProcessHistory", 22709 "calling xmlStreamPop()"); 22710 return (-1); 22711 } 22712 #ifdef DEBUG_IDC 22713 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22714 sto->sel->xpath); 22715 #endif 22716 if (sto->nbHistory == 0) 22717 goto deregister_check; 22718 22719 matchDepth = sto->history[sto->nbHistory -1]; 22720 22721 /* 22722 * Only matches at the current depth are of interest. 22723 */ 22724 if (matchDepth != depth) { 22725 sto = sto->next; 22726 continue; 22727 } 22728 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22729 /* 22730 * NOTE: According to 22731 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22732 * ... the simple-content of complex types is also allowed. 22733 */ 22734 22735 if (WXS_IS_COMPLEX(type)) { 22736 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22737 /* 22738 * Sanity check for complex types with simple content. 22739 */ 22740 simpleType = type->contentTypeDef; 22741 if (simpleType == NULL) { 22742 VERROR_INT("xmlSchemaXPathProcessHistory", 22743 "field resolves to a CT with simple content " 22744 "but the CT is missing the ST definition"); 22745 return (-1); 22746 } 22747 } else 22748 simpleType = NULL; 22749 } else 22750 simpleType = type; 22751 if (simpleType == NULL) { 22752 xmlChar *str = NULL; 22753 22754 /* 22755 * Not qualified if the field resolves to a node of non 22756 * simple type. 22757 */ 22758 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22759 XML_SCHEMAV_CVC_IDC, NULL, 22760 WXS_BASIC_CAST sto->matcher->aidc->def, 22761 "The XPath '%s' of a field of %s does evaluate to a node of " 22762 "non-simple type", 22763 sto->sel->xpath, 22764 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22765 FREE_AND_NULL(str); 22766 sto->nbHistory--; 22767 goto deregister_check; 22768 } 22769 22770 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22771 /* 22772 * Failed to provide the normalized value; maybe 22773 * the value was invalid. 22774 */ 22775 VERROR(XML_SCHEMAV_CVC_IDC, 22776 WXS_BASIC_CAST sto->matcher->aidc->def, 22777 "Warning: No precomputed value available, the value " 22778 "was either invalid or something strange happend"); 22779 sto->nbHistory--; 22780 goto deregister_check; 22781 } else { 22782 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22783 xmlSchemaPSVIIDCKeyPtr *keySeq; 22784 int pos, idx; 22785 22786 /* 22787 * The key will be anchored on the matcher's list of 22788 * key-sequences. The position in this list is determined 22789 * by the target node's depth relative to the matcher's 22790 * depth of creation (i.e. the depth of the scope element). 22791 * 22792 * Element Depth Pos List-entries 22793 * <scope> 0 NULL 22794 * <bar> 1 NULL 22795 * <target/> 2 2 target 22796 * <bar> 22797 * </scope> 22798 * 22799 * The size of the list is only dependant on the depth of 22800 * the tree. 22801 * An entry will be NULLed in selector_leave, i.e. when 22802 * we hit the target's 22803 */ 22804 pos = sto->depth - matcher->depth; 22805 idx = sto->sel->index; 22806 22807 /* 22808 * Create/grow the array of key-sequences. 22809 */ 22810 if (matcher->keySeqs == NULL) { 22811 if (pos > 9) 22812 matcher->sizeKeySeqs = pos * 2; 22813 else 22814 matcher->sizeKeySeqs = 10; 22815 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22816 xmlMalloc(matcher->sizeKeySeqs * 22817 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22818 if (matcher->keySeqs == NULL) { 22819 xmlSchemaVErrMemory(NULL, 22820 "allocating an array of key-sequences", 22821 NULL); 22822 return(-1); 22823 } 22824 memset(matcher->keySeqs, 0, 22825 matcher->sizeKeySeqs * 22826 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22827 } else if (pos >= matcher->sizeKeySeqs) { 22828 int i = matcher->sizeKeySeqs; 22829 22830 matcher->sizeKeySeqs *= 2; 22831 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22832 xmlRealloc(matcher->keySeqs, 22833 matcher->sizeKeySeqs * 22834 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22835 if (matcher->keySeqs == NULL) { 22836 xmlSchemaVErrMemory(NULL, 22837 "reallocating an array of key-sequences", 22838 NULL); 22839 return (-1); 22840 } 22841 /* 22842 * The array needs to be NULLed. 22843 * TODO: Use memset? 22844 */ 22845 for (; i < matcher->sizeKeySeqs; i++) 22846 matcher->keySeqs[i] = NULL; 22847 } 22848 22849 /* 22850 * Get/create the key-sequence. 22851 */ 22852 keySeq = matcher->keySeqs[pos]; 22853 if (keySeq == NULL) { 22854 goto create_sequence; 22855 } else if (keySeq[idx] != NULL) { 22856 xmlChar *str = NULL; 22857 /* 22858 * cvc-identity-constraint: 22859 * 3 For each node in the `target node set` all 22860 * of the {fields}, with that node as the context 22861 * node, evaluate to either an empty node-set or 22862 * a node-set with exactly one member, which must 22863 * have a simple type. 22864 * 22865 * The key was already set; report an error. 22866 */ 22867 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22868 XML_SCHEMAV_CVC_IDC, NULL, 22869 WXS_BASIC_CAST matcher->aidc->def, 22870 "The XPath '%s' of a field of %s evaluates to a " 22871 "node-set with more than one member", 22872 sto->sel->xpath, 22873 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22874 FREE_AND_NULL(str); 22875 sto->nbHistory--; 22876 goto deregister_check; 22877 } else 22878 goto create_key; 22879 22880 create_sequence: 22881 /* 22882 * Create a key-sequence. 22883 */ 22884 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22885 matcher->aidc->def->nbFields * 22886 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22887 if (keySeq == NULL) { 22888 xmlSchemaVErrMemory(NULL, 22889 "allocating an IDC key-sequence", NULL); 22890 return(-1); 22891 } 22892 memset(keySeq, 0, matcher->aidc->def->nbFields * 22893 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22894 matcher->keySeqs[pos] = keySeq; 22895 create_key: 22896 /* 22897 * Create a key once per node only. 22898 */ 22899 if (key == NULL) { 22900 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22901 sizeof(xmlSchemaPSVIIDCKey)); 22902 if (key == NULL) { 22903 xmlSchemaVErrMemory(NULL, 22904 "allocating a IDC key", NULL); 22905 xmlFree(keySeq); 22906 matcher->keySeqs[pos] = NULL; 22907 return(-1); 22908 } 22909 /* 22910 * Consume the compiled value. 22911 */ 22912 key->type = simpleType; 22913 key->val = vctxt->inode->val; 22914 vctxt->inode->val = NULL; 22915 /* 22916 * Store the key in a global list. 22917 */ 22918 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22919 xmlSchemaIDCFreeKey(key); 22920 return (-1); 22921 } 22922 } 22923 keySeq[idx] = key; 22924 } 22925 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22926 22927 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22928 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22929 xmlSchemaPSVIIDCNodePtr ntItem; 22930 xmlSchemaIDCMatcherPtr matcher; 22931 xmlSchemaIDCPtr idc; 22932 xmlSchemaItemListPtr targets; 22933 int pos, i, j, nbKeys; 22934 /* 22935 * Here we have the following scenario: 22936 * An IDC 'selector' state object resolved to a target node, 22937 * during the time this target node was in the 22938 * ancestor-or-self axis, the 'field' state object(s) looked 22939 * out for matching nodes to create a key-sequence for this 22940 * target node. Now we are back to this target node and need 22941 * to put the key-sequence, together with the target node 22942 * itself, into the node-table of the corresponding IDC 22943 * binding. 22944 */ 22945 matcher = sto->matcher; 22946 idc = matcher->aidc->def; 22947 nbKeys = idc->nbFields; 22948 pos = depth - matcher->depth; 22949 /* 22950 * Check if the matcher has any key-sequences at all, plus 22951 * if it has a key-sequence for the current target node. 22952 */ 22953 if ((matcher->keySeqs == NULL) || 22954 (matcher->sizeKeySeqs <= pos)) { 22955 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22956 goto selector_key_error; 22957 else 22958 goto selector_leave; 22959 } 22960 22961 keySeq = &(matcher->keySeqs[pos]); 22962 if (*keySeq == NULL) { 22963 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22964 goto selector_key_error; 22965 else 22966 goto selector_leave; 22967 } 22968 22969 for (i = 0; i < nbKeys; i++) { 22970 if ((*keySeq)[i] == NULL) { 22971 /* 22972 * Not qualified, if not all fields did resolve. 22973 */ 22974 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22975 /* 22976 * All fields of a "key" IDC must resolve. 22977 */ 22978 goto selector_key_error; 22979 } 22980 goto selector_leave; 22981 } 22982 } 22983 /* 22984 * All fields did resolve. 22985 */ 22986 22987 /* 22988 * 4.1 If the {identity-constraint category} is unique(/key), 22989 * then no two members of the `qualified node set` have 22990 * `key-sequences` whose members are pairwise equal, as 22991 * defined by Equal in [XML Schemas: Datatypes]. 22992 * 22993 * Get the IDC binding from the matcher and check for 22994 * duplicate key-sequences. 22995 */ 22996 #if 0 22997 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 22998 #endif 22999 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 23000 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 23001 (targets->nbItems != 0)) { 23002 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 23003 23004 i = 0; 23005 res = 0; 23006 /* 23007 * Compare the key-sequences, key by key. 23008 */ 23009 do { 23010 bkeySeq = 23011 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 23012 for (j = 0; j < nbKeys; j++) { 23013 ckey = (*keySeq)[j]; 23014 bkey = bkeySeq[j]; 23015 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 23016 if (res == -1) { 23017 return (-1); 23018 } else if (res == 0) { 23019 /* 23020 * One of the keys differs, so the key-sequence 23021 * won't be equal; get out. 23022 */ 23023 break; 23024 } 23025 } 23026 if (res == 1) { 23027 /* 23028 * Duplicate key-sequence found. 23029 */ 23030 break; 23031 } 23032 i++; 23033 } while (i < targets->nbItems); 23034 if (i != targets->nbItems) { 23035 xmlChar *str = NULL, *strB = NULL; 23036 /* 23037 * TODO: Try to report the key-sequence. 23038 */ 23039 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23040 XML_SCHEMAV_CVC_IDC, NULL, 23041 WXS_BASIC_CAST idc, 23042 "Duplicate key-sequence %s in %s", 23043 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23044 (*keySeq), nbKeys), 23045 xmlSchemaGetIDCDesignation(&strB, idc)); 23046 FREE_AND_NULL(str); 23047 FREE_AND_NULL(strB); 23048 goto selector_leave; 23049 } 23050 } 23051 /* 23052 * Add a node-table item to the IDC binding. 23053 */ 23054 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23055 sizeof(xmlSchemaPSVIIDCNode)); 23056 if (ntItem == NULL) { 23057 xmlSchemaVErrMemory(NULL, 23058 "allocating an IDC node-table item", NULL); 23059 xmlFree(*keySeq); 23060 *keySeq = NULL; 23061 return(-1); 23062 } 23063 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23064 23065 /* 23066 * Store the node-table item in a global list. 23067 */ 23068 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23069 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23070 xmlFree(ntItem); 23071 xmlFree(*keySeq); 23072 *keySeq = NULL; 23073 return (-1); 23074 } 23075 ntItem->nodeQNameID = -1; 23076 } else { 23077 /* 23078 * Save a cached QName for this node on the IDC node, to be 23079 * able to report it, even if the node is not saved. 23080 */ 23081 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23082 vctxt->inode->localName, vctxt->inode->nsName); 23083 if (ntItem->nodeQNameID == -1) { 23084 xmlFree(ntItem); 23085 xmlFree(*keySeq); 23086 *keySeq = NULL; 23087 return (-1); 23088 } 23089 } 23090 /* 23091 * Init the node-table item: Save the node, position and 23092 * consume the key-sequence. 23093 */ 23094 ntItem->node = vctxt->node; 23095 ntItem->nodeLine = vctxt->inode->nodeLine; 23096 ntItem->keys = *keySeq; 23097 *keySeq = NULL; 23098 #if 0 23099 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23100 #endif 23101 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23102 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23103 /* 23104 * Free the item, since keyref items won't be 23105 * put on a global list. 23106 */ 23107 xmlFree(ntItem->keys); 23108 xmlFree(ntItem); 23109 } 23110 return (-1); 23111 } 23112 23113 goto selector_leave; 23114 selector_key_error: 23115 { 23116 xmlChar *str = NULL; 23117 /* 23118 * 4.2.1 (KEY) The `target node set` and the 23119 * `qualified node set` are equal, that is, every 23120 * member of the `target node set` is also a member 23121 * of the `qualified node set` and vice versa. 23122 */ 23123 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23124 XML_SCHEMAV_CVC_IDC, NULL, 23125 WXS_BASIC_CAST idc, 23126 "Not all fields of %s evaluate to a node", 23127 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23128 FREE_AND_NULL(str); 23129 } 23130 selector_leave: 23131 /* 23132 * Free the key-sequence if not added to the IDC table. 23133 */ 23134 if ((keySeq != NULL) && (*keySeq != NULL)) { 23135 xmlFree(*keySeq); 23136 *keySeq = NULL; 23137 } 23138 } /* if selector */ 23139 23140 sto->nbHistory--; 23141 23142 deregister_check: 23143 /* 23144 * Deregister state objects if they reach the depth of creation. 23145 */ 23146 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23147 #ifdef DEBUG_IDC 23148 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23149 sto->sel->xpath); 23150 #endif 23151 if (vctxt->xpathStates != sto) { 23152 VERROR_INT("xmlSchemaXPathProcessHistory", 23153 "The state object to be removed is not the first " 23154 "in the list"); 23155 } 23156 nextsto = sto->next; 23157 /* 23158 * Unlink from the list of active XPath state objects. 23159 */ 23160 vctxt->xpathStates = sto->next; 23161 sto->next = vctxt->xpathStatePool; 23162 /* 23163 * Link it to the pool of reusable state objects. 23164 */ 23165 vctxt->xpathStatePool = sto; 23166 sto = nextsto; 23167 } else 23168 sto = sto->next; 23169 } /* while (sto != NULL) */ 23170 return (0); 23171 } 23172 23173 /** 23174 * xmlSchemaIDCRegisterMatchers: 23175 * @vctxt: the WXS validation context 23176 * @elemDecl: the element declaration 23177 * 23178 * Creates helper objects to evaluate IDC selectors/fields 23179 * successively. 23180 * 23181 * Returns 0 if OK and -1 on internal errors. 23182 */ 23183 static int 23184 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23185 xmlSchemaElementPtr elemDecl) 23186 { 23187 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23188 xmlSchemaIDCPtr idc, refIdc; 23189 xmlSchemaIDCAugPtr aidc; 23190 23191 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23192 if (idc == NULL) 23193 return (0); 23194 23195 #ifdef DEBUG_IDC 23196 { 23197 xmlChar *str = NULL; 23198 xmlGenericError(xmlGenericErrorContext, 23199 "IDC: REGISTER on %s, depth %d\n", 23200 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23201 vctxt->inode->localName), vctxt->depth); 23202 FREE_AND_NULL(str) 23203 } 23204 #endif 23205 if (vctxt->inode->idcMatchers != NULL) { 23206 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23207 "The chain of IDC matchers is expected to be empty"); 23208 return (-1); 23209 } 23210 do { 23211 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23212 /* 23213 * Since IDCs bubbles are expensive we need to know the 23214 * depth at which the bubbles should stop; this will be 23215 * the depth of the top-most keyref IDC. If no keyref 23216 * references a key/unique IDC, the keyrefDepth will 23217 * be -1, indicating that no bubbles are needed. 23218 */ 23219 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23220 if (refIdc != NULL) { 23221 /* 23222 * Remember that we have keyrefs on this node. 23223 */ 23224 vctxt->inode->hasKeyrefs = 1; 23225 /* 23226 * Lookup the referenced augmented IDC info. 23227 */ 23228 aidc = vctxt->aidcs; 23229 while (aidc != NULL) { 23230 if (aidc->def == refIdc) 23231 break; 23232 aidc = aidc->next; 23233 } 23234 if (aidc == NULL) { 23235 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23236 "Could not find an augmented IDC item for an IDC " 23237 "definition"); 23238 return (-1); 23239 } 23240 if ((aidc->keyrefDepth == -1) || 23241 (vctxt->depth < aidc->keyrefDepth)) 23242 aidc->keyrefDepth = vctxt->depth; 23243 } 23244 } 23245 /* 23246 * Lookup the augmented IDC item for the IDC definition. 23247 */ 23248 aidc = vctxt->aidcs; 23249 while (aidc != NULL) { 23250 if (aidc->def == idc) 23251 break; 23252 aidc = aidc->next; 23253 } 23254 if (aidc == NULL) { 23255 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23256 "Could not find an augmented IDC item for an IDC definition"); 23257 return (-1); 23258 } 23259 /* 23260 * Create an IDC matcher for every IDC definition. 23261 */ 23262 if (vctxt->idcMatcherCache != NULL) { 23263 /* 23264 * Reuse a cached matcher. 23265 */ 23266 matcher = vctxt->idcMatcherCache; 23267 vctxt->idcMatcherCache = matcher->nextCached; 23268 matcher->nextCached = NULL; 23269 } else { 23270 matcher = (xmlSchemaIDCMatcherPtr) 23271 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23272 if (matcher == NULL) { 23273 xmlSchemaVErrMemory(vctxt, 23274 "allocating an IDC matcher", NULL); 23275 return (-1); 23276 } 23277 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23278 } 23279 if (last == NULL) 23280 vctxt->inode->idcMatchers = matcher; 23281 else 23282 last->next = matcher; 23283 last = matcher; 23284 23285 matcher->type = IDC_MATCHER; 23286 matcher->depth = vctxt->depth; 23287 matcher->aidc = aidc; 23288 matcher->idcType = aidc->def->type; 23289 #ifdef DEBUG_IDC 23290 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23291 #endif 23292 /* 23293 * Init the automaton state object. 23294 */ 23295 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23296 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23297 return (-1); 23298 23299 idc = idc->next; 23300 } while (idc != NULL); 23301 return (0); 23302 } 23303 23304 static int 23305 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23306 xmlSchemaNodeInfoPtr ielem) 23307 { 23308 xmlSchemaPSVIIDCBindingPtr bind; 23309 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23310 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23311 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23312 23313 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23314 /* vctxt->createIDCNodeTables */ 23315 while (matcher != NULL) { 23316 /* 23317 * Skip keyref IDCs and empty IDC target-lists. 23318 */ 23319 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23320 WXS_ILIST_IS_EMPTY(matcher->targets)) 23321 { 23322 matcher = matcher->next; 23323 continue; 23324 } 23325 /* 23326 * If we _want_ the IDC node-table to be created in any case 23327 * then do so. Otherwise create them only if keyrefs need them. 23328 */ 23329 if ((! vctxt->createIDCNodeTables) && 23330 ((matcher->aidc->keyrefDepth == -1) || 23331 (matcher->aidc->keyrefDepth > vctxt->depth))) 23332 { 23333 matcher = matcher->next; 23334 continue; 23335 } 23336 /* 23337 * Get/create the IDC binding on this element for the IDC definition. 23338 */ 23339 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23340 23341 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23342 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23343 nbDupls = bind->dupls->nbItems; 23344 } else { 23345 dupls = NULL; 23346 nbDupls = 0; 23347 } 23348 if (bind->nodeTable != NULL) { 23349 nbNodeTable = bind->nbNodes; 23350 } else { 23351 nbNodeTable = 0; 23352 } 23353 23354 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23355 /* 23356 * Transfer all IDC target-nodes to the IDC node-table. 23357 */ 23358 bind->nodeTable = 23359 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23360 bind->sizeNodes = matcher->targets->sizeItems; 23361 bind->nbNodes = matcher->targets->nbItems; 23362 23363 matcher->targets->items = NULL; 23364 matcher->targets->sizeItems = 0; 23365 matcher->targets->nbItems = 0; 23366 } else { 23367 /* 23368 * Compare the key-sequences and add to the IDC node-table. 23369 */ 23370 nbTargets = matcher->targets->nbItems; 23371 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23372 nbFields = matcher->aidc->def->nbFields; 23373 i = 0; 23374 do { 23375 keys = targets[i]->keys; 23376 if (nbDupls) { 23377 /* 23378 * Search in already found duplicates first. 23379 */ 23380 j = 0; 23381 do { 23382 if (nbFields == 1) { 23383 res = xmlSchemaAreValuesEqual(keys[0]->val, 23384 dupls[j]->keys[0]->val); 23385 if (res == -1) 23386 goto internal_error; 23387 if (res == 1) { 23388 /* 23389 * Equal key-sequence. 23390 */ 23391 goto next_target; 23392 } 23393 } else { 23394 res = 0; 23395 ntkeys = dupls[j]->keys; 23396 for (k = 0; k < nbFields; k++) { 23397 res = xmlSchemaAreValuesEqual(keys[k]->val, 23398 ntkeys[k]->val); 23399 if (res == -1) 23400 goto internal_error; 23401 if (res == 0) { 23402 /* 23403 * One of the keys differs. 23404 */ 23405 break; 23406 } 23407 } 23408 if (res == 1) { 23409 /* 23410 * Equal key-sequence found. 23411 */ 23412 goto next_target; 23413 } 23414 } 23415 j++; 23416 } while (j < nbDupls); 23417 } 23418 if (nbNodeTable) { 23419 j = 0; 23420 do { 23421 if (nbFields == 1) { 23422 res = xmlSchemaAreValuesEqual(keys[0]->val, 23423 bind->nodeTable[j]->keys[0]->val); 23424 if (res == -1) 23425 goto internal_error; 23426 if (res == 0) { 23427 /* 23428 * The key-sequence differs. 23429 */ 23430 goto next_node_table_entry; 23431 } 23432 } else { 23433 res = 0; 23434 ntkeys = bind->nodeTable[j]->keys; 23435 for (k = 0; k < nbFields; k++) { 23436 res = xmlSchemaAreValuesEqual(keys[k]->val, 23437 ntkeys[k]->val); 23438 if (res == -1) 23439 goto internal_error; 23440 if (res == 0) { 23441 /* 23442 * One of the keys differs. 23443 */ 23444 goto next_node_table_entry; 23445 } 23446 } 23447 } 23448 /* 23449 * Add the duplicate to the list of duplicates. 23450 */ 23451 if (bind->dupls == NULL) { 23452 bind->dupls = xmlSchemaItemListCreate(); 23453 if (bind->dupls == NULL) 23454 goto internal_error; 23455 } 23456 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23457 goto internal_error; 23458 /* 23459 * Remove the duplicate entry from the IDC node-table. 23460 */ 23461 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23462 bind->nbNodes--; 23463 23464 goto next_target; 23465 23466 next_node_table_entry: 23467 j++; 23468 } while (j < nbNodeTable); 23469 } 23470 /* 23471 * If everything is fine, then add the IDC target-node to 23472 * the IDC node-table. 23473 */ 23474 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23475 goto internal_error; 23476 23477 next_target: 23478 i++; 23479 } while (i < nbTargets); 23480 } 23481 matcher = matcher->next; 23482 } 23483 return(0); 23484 23485 internal_error: 23486 return(-1); 23487 } 23488 23489 /** 23490 * xmlSchemaBubbleIDCNodeTables: 23491 * @depth: the current tree depth 23492 * 23493 * Merges IDC bindings of an element at @depth into the corresponding IDC 23494 * bindings of its parent element. If a duplicate note-table entry is found, 23495 * both, the parent node-table entry and child entry are discarded from the 23496 * node-table of the parent. 23497 * 23498 * Returns 0 if OK and -1 on internal errors. 23499 */ 23500 static int 23501 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23502 { 23503 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23504 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23505 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23506 xmlSchemaIDCAugPtr aidc; 23507 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23508 23509 bind = vctxt->inode->idcTable; 23510 if (bind == NULL) { 23511 /* Fine, no table, no bubbles. */ 23512 return (0); 23513 } 23514 23515 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23516 /* 23517 * Walk all bindings; create new or add to existing bindings. 23518 * Remove duplicate key-sequences. 23519 */ 23520 while (bind != NULL) { 23521 23522 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23523 goto next_binding; 23524 /* 23525 * Check if the key/unique IDC table needs to be bubbled. 23526 */ 23527 if (! vctxt->createIDCNodeTables) { 23528 aidc = vctxt->aidcs; 23529 do { 23530 if (aidc->def == bind->definition) { 23531 if ((aidc->keyrefDepth == -1) || 23532 (aidc->keyrefDepth >= vctxt->depth)) { 23533 goto next_binding; 23534 } 23535 break; 23536 } 23537 aidc = aidc->next; 23538 } while (aidc != NULL); 23539 } 23540 23541 if (parTable != NULL) 23542 parBind = *parTable; 23543 /* 23544 * Search a matching parent binding for the 23545 * IDC definition. 23546 */ 23547 while (parBind != NULL) { 23548 if (parBind->definition == bind->definition) 23549 break; 23550 parBind = parBind->next; 23551 } 23552 23553 if (parBind != NULL) { 23554 /* 23555 * Compare every node-table entry of the child node, 23556 * i.e. the key-sequence within, ... 23557 */ 23558 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23559 23560 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23561 oldDupls = parBind->dupls->nbItems; 23562 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23563 } else { 23564 dupls = NULL; 23565 oldDupls = 0; 23566 } 23567 23568 parNodes = parBind->nodeTable; 23569 nbFields = bind->definition->nbFields; 23570 23571 for (i = 0; i < bind->nbNodes; i++) { 23572 node = bind->nodeTable[i]; 23573 if (node == NULL) 23574 continue; 23575 /* 23576 * ...with every key-sequence of the parent node, already 23577 * evaluated to be a duplicate key-sequence. 23578 */ 23579 if (oldDupls) { 23580 j = 0; 23581 while (j < oldDupls) { 23582 if (nbFields == 1) { 23583 ret = xmlSchemaAreValuesEqual( 23584 node->keys[0]->val, 23585 dupls[j]->keys[0]->val); 23586 if (ret == -1) 23587 goto internal_error; 23588 if (ret == 0) { 23589 j++; 23590 continue; 23591 } 23592 } else { 23593 parNode = dupls[j]; 23594 for (k = 0; k < nbFields; k++) { 23595 ret = xmlSchemaAreValuesEqual( 23596 node->keys[k]->val, 23597 parNode->keys[k]->val); 23598 if (ret == -1) 23599 goto internal_error; 23600 if (ret == 0) 23601 break; 23602 } 23603 } 23604 if (ret == 1) 23605 /* Duplicate found. */ 23606 break; 23607 j++; 23608 } 23609 if (j != oldDupls) { 23610 /* Duplicate found. Skip this entry. */ 23611 continue; 23612 } 23613 } 23614 /* 23615 * ... and with every key-sequence of the parent node. 23616 */ 23617 if (oldNum) { 23618 j = 0; 23619 while (j < oldNum) { 23620 parNode = parNodes[j]; 23621 if (nbFields == 1) { 23622 ret = xmlSchemaAreValuesEqual( 23623 node->keys[0]->val, 23624 parNode->keys[0]->val); 23625 if (ret == -1) 23626 goto internal_error; 23627 if (ret == 0) { 23628 j++; 23629 continue; 23630 } 23631 } else { 23632 for (k = 0; k < nbFields; k++) { 23633 ret = xmlSchemaAreValuesEqual( 23634 node->keys[k]->val, 23635 parNode->keys[k]->val); 23636 if (ret == -1) 23637 goto internal_error; 23638 if (ret == 0) 23639 break; 23640 } 23641 } 23642 if (ret == 1) 23643 /* Duplicate found. */ 23644 break; 23645 j++; 23646 } 23647 if (j != oldNum) { 23648 /* 23649 * Handle duplicates. Move the duplicate in 23650 * the parent's node-table to the list of 23651 * duplicates. 23652 */ 23653 oldNum--; 23654 parBind->nbNodes--; 23655 /* 23656 * Move last old item to pos of duplicate. 23657 */ 23658 parNodes[j] = parNodes[oldNum]; 23659 23660 if (parBind->nbNodes != oldNum) { 23661 /* 23662 * If new items exist, move last new item to 23663 * last of old items. 23664 */ 23665 parNodes[oldNum] = 23666 parNodes[parBind->nbNodes]; 23667 } 23668 if (parBind->dupls == NULL) { 23669 parBind->dupls = xmlSchemaItemListCreate(); 23670 if (parBind->dupls == NULL) 23671 goto internal_error; 23672 } 23673 xmlSchemaItemListAdd(parBind->dupls, parNode); 23674 } else { 23675 /* 23676 * Add the node-table entry (node and key-sequence) of 23677 * the child node to the node table of the parent node. 23678 */ 23679 if (parBind->nodeTable == NULL) { 23680 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23681 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23682 if (parBind->nodeTable == NULL) { 23683 xmlSchemaVErrMemory(NULL, 23684 "allocating IDC list of node-table items", NULL); 23685 goto internal_error; 23686 } 23687 parBind->sizeNodes = 1; 23688 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23689 parBind->sizeNodes *= 2; 23690 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23691 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23692 sizeof(xmlSchemaPSVIIDCNodePtr)); 23693 if (parBind->nodeTable == NULL) { 23694 xmlSchemaVErrMemory(NULL, 23695 "re-allocating IDC list of node-table items", NULL); 23696 goto internal_error; 23697 } 23698 } 23699 parNodes = parBind->nodeTable; 23700 /* 23701 * Append the new node-table entry to the 'new node-table 23702 * entries' section. 23703 */ 23704 parNodes[parBind->nbNodes++] = node; 23705 } 23706 23707 } 23708 23709 } 23710 } else { 23711 /* 23712 * No binding for the IDC was found: create a new one and 23713 * copy all node-tables. 23714 */ 23715 parBind = xmlSchemaIDCNewBinding(bind->definition); 23716 if (parBind == NULL) 23717 goto internal_error; 23718 23719 /* 23720 * TODO: Hmm, how to optimize the initial number of 23721 * allocated entries? 23722 */ 23723 if (bind->nbNodes != 0) { 23724 /* 23725 * Add all IDC node-table entries. 23726 */ 23727 if (! vctxt->psviExposeIDCNodeTables) { 23728 /* 23729 * Just move the entries. 23730 * NOTE: this is quite save here, since 23731 * all the keyref lookups have already been 23732 * performed. 23733 */ 23734 parBind->nodeTable = bind->nodeTable; 23735 bind->nodeTable = NULL; 23736 parBind->sizeNodes = bind->sizeNodes; 23737 bind->sizeNodes = 0; 23738 parBind->nbNodes = bind->nbNodes; 23739 bind->nbNodes = 0; 23740 } else { 23741 /* 23742 * Copy the entries. 23743 */ 23744 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23745 xmlMalloc(bind->nbNodes * 23746 sizeof(xmlSchemaPSVIIDCNodePtr)); 23747 if (parBind->nodeTable == NULL) { 23748 xmlSchemaVErrMemory(NULL, 23749 "allocating an array of IDC node-table " 23750 "items", NULL); 23751 xmlSchemaIDCFreeBinding(parBind); 23752 goto internal_error; 23753 } 23754 parBind->sizeNodes = bind->nbNodes; 23755 parBind->nbNodes = bind->nbNodes; 23756 memcpy(parBind->nodeTable, bind->nodeTable, 23757 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23758 } 23759 } 23760 if (bind->dupls) { 23761 /* 23762 * Move the duplicates. 23763 */ 23764 if (parBind->dupls != NULL) 23765 xmlSchemaItemListFree(parBind->dupls); 23766 parBind->dupls = bind->dupls; 23767 bind->dupls = NULL; 23768 } 23769 if (parTable != NULL) { 23770 if (*parTable == NULL) 23771 *parTable = parBind; 23772 else { 23773 parBind->next = *parTable; 23774 *parTable = parBind; 23775 } 23776 } 23777 } 23778 23779 next_binding: 23780 bind = bind->next; 23781 } 23782 return (0); 23783 23784 internal_error: 23785 return(-1); 23786 } 23787 23788 /** 23789 * xmlSchemaCheckCVCIDCKeyRef: 23790 * @vctxt: the WXS validation context 23791 * @elemDecl: the element declaration 23792 * 23793 * Check the cvc-idc-keyref constraints. 23794 */ 23795 static int 23796 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23797 { 23798 xmlSchemaIDCMatcherPtr matcher; 23799 xmlSchemaPSVIIDCBindingPtr bind; 23800 23801 matcher = vctxt->inode->idcMatchers; 23802 /* 23803 * Find a keyref. 23804 */ 23805 while (matcher != NULL) { 23806 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23807 matcher->targets && 23808 matcher->targets->nbItems) 23809 { 23810 int i, j, k, res, nbFields, hasDupls; 23811 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23812 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23813 23814 nbFields = matcher->aidc->def->nbFields; 23815 23816 /* 23817 * Find the IDC node-table for the referenced IDC key/unique. 23818 */ 23819 bind = vctxt->inode->idcTable; 23820 while (bind != NULL) { 23821 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23822 bind->definition) 23823 break; 23824 bind = bind->next; 23825 } 23826 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23827 /* 23828 * Search for a matching key-sequences. 23829 */ 23830 for (i = 0; i < matcher->targets->nbItems; i++) { 23831 res = 0; 23832 refNode = matcher->targets->items[i]; 23833 if (bind != NULL) { 23834 refKeys = refNode->keys; 23835 for (j = 0; j < bind->nbNodes; j++) { 23836 keys = bind->nodeTable[j]->keys; 23837 for (k = 0; k < nbFields; k++) { 23838 res = xmlSchemaAreValuesEqual(keys[k]->val, 23839 refKeys[k]->val); 23840 if (res == 0) 23841 break; 23842 else if (res == -1) { 23843 return (-1); 23844 } 23845 } 23846 if (res == 1) { 23847 /* 23848 * Match found. 23849 */ 23850 break; 23851 } 23852 } 23853 if ((res == 0) && hasDupls) { 23854 /* 23855 * Search in duplicates 23856 */ 23857 for (j = 0; j < bind->dupls->nbItems; j++) { 23858 keys = ((xmlSchemaPSVIIDCNodePtr) 23859 bind->dupls->items[j])->keys; 23860 for (k = 0; k < nbFields; k++) { 23861 res = xmlSchemaAreValuesEqual(keys[k]->val, 23862 refKeys[k]->val); 23863 if (res == 0) 23864 break; 23865 else if (res == -1) { 23866 return (-1); 23867 } 23868 } 23869 if (res == 1) { 23870 /* 23871 * Match in duplicates found. 23872 */ 23873 xmlChar *str = NULL, *strB = NULL; 23874 xmlSchemaKeyrefErr(vctxt, 23875 XML_SCHEMAV_CVC_IDC, refNode, 23876 (xmlSchemaTypePtr) matcher->aidc->def, 23877 "More than one match found for " 23878 "key-sequence %s of keyref '%s'", 23879 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23880 refNode->keys, nbFields), 23881 xmlSchemaGetComponentQName(&strB, 23882 matcher->aidc->def)); 23883 FREE_AND_NULL(str); 23884 FREE_AND_NULL(strB); 23885 break; 23886 } 23887 } 23888 } 23889 } 23890 23891 if (res == 0) { 23892 xmlChar *str = NULL, *strB = NULL; 23893 xmlSchemaKeyrefErr(vctxt, 23894 XML_SCHEMAV_CVC_IDC, refNode, 23895 (xmlSchemaTypePtr) matcher->aidc->def, 23896 "No match found for key-sequence %s of keyref '%s'", 23897 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23898 refNode->keys, nbFields), 23899 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23900 FREE_AND_NULL(str); 23901 FREE_AND_NULL(strB); 23902 } 23903 } 23904 } 23905 matcher = matcher->next; 23906 } 23907 /* TODO: Return an error if any error encountered. */ 23908 return (0); 23909 } 23910 23911 /************************************************************************ 23912 * * 23913 * XML Reader validation code * 23914 * * 23915 ************************************************************************/ 23916 23917 static xmlSchemaAttrInfoPtr 23918 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23919 { 23920 xmlSchemaAttrInfoPtr iattr; 23921 /* 23922 * Grow/create list of attribute infos. 23923 */ 23924 if (vctxt->attrInfos == NULL) { 23925 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23926 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23927 vctxt->sizeAttrInfos = 1; 23928 if (vctxt->attrInfos == NULL) { 23929 xmlSchemaVErrMemory(vctxt, 23930 "allocating attribute info list", NULL); 23931 return (NULL); 23932 } 23933 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23934 vctxt->sizeAttrInfos++; 23935 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23936 xmlRealloc(vctxt->attrInfos, 23937 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23938 if (vctxt->attrInfos == NULL) { 23939 xmlSchemaVErrMemory(vctxt, 23940 "re-allocating attribute info list", NULL); 23941 return (NULL); 23942 } 23943 } else { 23944 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23945 if (iattr->localName != NULL) { 23946 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23947 "attr info not cleared"); 23948 return (NULL); 23949 } 23950 iattr->nodeType = XML_ATTRIBUTE_NODE; 23951 return (iattr); 23952 } 23953 /* 23954 * Create an attribute info. 23955 */ 23956 iattr = (xmlSchemaAttrInfoPtr) 23957 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23958 if (iattr == NULL) { 23959 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23960 return (NULL); 23961 } 23962 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23963 iattr->nodeType = XML_ATTRIBUTE_NODE; 23964 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23965 23966 return (iattr); 23967 } 23968 23969 static int 23970 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23971 xmlNodePtr attrNode, 23972 int nodeLine, 23973 const xmlChar *localName, 23974 const xmlChar *nsName, 23975 int ownedNames, 23976 xmlChar *value, 23977 int ownedValue) 23978 { 23979 xmlSchemaAttrInfoPtr attr; 23980 23981 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23982 if (attr == NULL) { 23983 VERROR_INT("xmlSchemaPushAttribute", 23984 "calling xmlSchemaGetFreshAttrInfo()"); 23985 return (-1); 23986 } 23987 attr->node = attrNode; 23988 attr->nodeLine = nodeLine; 23989 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 23990 attr->localName = localName; 23991 attr->nsName = nsName; 23992 if (ownedNames) 23993 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 23994 /* 23995 * Evaluate if it's an XSI attribute. 23996 */ 23997 if (nsName != NULL) { 23998 if (xmlStrEqual(localName, BAD_CAST "nil")) { 23999 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24000 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 24001 } 24002 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 24003 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24004 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 24005 } 24006 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 24007 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24008 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 24009 } 24010 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 24011 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24012 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 24013 } 24014 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 24015 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 24016 } 24017 } 24018 attr->value = value; 24019 if (ownedValue) 24020 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 24021 if (attr->metaType != 0) 24022 attr->state = XML_SCHEMAS_ATTR_META; 24023 return (0); 24024 } 24025 24026 /** 24027 * xmlSchemaClearElemInfo: 24028 * @vctxt: the WXS validation context 24029 * @ielem: the element information item 24030 */ 24031 static void 24032 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 24033 xmlSchemaNodeInfoPtr ielem) 24034 { 24035 ielem->hasKeyrefs = 0; 24036 ielem->appliedXPath = 0; 24037 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 24038 FREE_AND_NULL(ielem->localName); 24039 FREE_AND_NULL(ielem->nsName); 24040 } else { 24041 ielem->localName = NULL; 24042 ielem->nsName = NULL; 24043 } 24044 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24045 FREE_AND_NULL(ielem->value); 24046 } else { 24047 ielem->value = NULL; 24048 } 24049 if (ielem->val != NULL) { 24050 /* 24051 * PSVI TODO: Be careful not to free it when the value is 24052 * exposed via PSVI. 24053 */ 24054 xmlSchemaFreeValue(ielem->val); 24055 ielem->val = NULL; 24056 } 24057 if (ielem->idcMatchers != NULL) { 24058 /* 24059 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24060 * Does it work? 24061 */ 24062 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24063 #if 0 24064 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24065 #endif 24066 ielem->idcMatchers = NULL; 24067 } 24068 if (ielem->idcTable != NULL) { 24069 /* 24070 * OPTIMIZE TODO: Use a pool of IDC tables??. 24071 */ 24072 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24073 ielem->idcTable = NULL; 24074 } 24075 if (ielem->regexCtxt != NULL) { 24076 xmlRegFreeExecCtxt(ielem->regexCtxt); 24077 ielem->regexCtxt = NULL; 24078 } 24079 if (ielem->nsBindings != NULL) { 24080 xmlFree((xmlChar **)ielem->nsBindings); 24081 ielem->nsBindings = NULL; 24082 ielem->nbNsBindings = 0; 24083 ielem->sizeNsBindings = 0; 24084 } 24085 } 24086 24087 /** 24088 * xmlSchemaGetFreshElemInfo: 24089 * @vctxt: the schema validation context 24090 * 24091 * Creates/reuses and initializes the element info item for 24092 * the currect tree depth. 24093 * 24094 * Returns the element info item or NULL on API or internal errors. 24095 */ 24096 static xmlSchemaNodeInfoPtr 24097 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24098 { 24099 xmlSchemaNodeInfoPtr info = NULL; 24100 24101 if (vctxt->depth > vctxt->sizeElemInfos) { 24102 VERROR_INT("xmlSchemaGetFreshElemInfo", 24103 "inconsistent depth encountered"); 24104 return (NULL); 24105 } 24106 if (vctxt->elemInfos == NULL) { 24107 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24108 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24109 if (vctxt->elemInfos == NULL) { 24110 xmlSchemaVErrMemory(vctxt, 24111 "allocating the element info array", NULL); 24112 return (NULL); 24113 } 24114 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24115 vctxt->sizeElemInfos = 10; 24116 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24117 int i = vctxt->sizeElemInfos; 24118 24119 vctxt->sizeElemInfos *= 2; 24120 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24121 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24122 sizeof(xmlSchemaNodeInfoPtr)); 24123 if (vctxt->elemInfos == NULL) { 24124 xmlSchemaVErrMemory(vctxt, 24125 "re-allocating the element info array", NULL); 24126 return (NULL); 24127 } 24128 /* 24129 * We need the new memory to be NULLed. 24130 * TODO: Use memset instead? 24131 */ 24132 for (; i < vctxt->sizeElemInfos; i++) 24133 vctxt->elemInfos[i] = NULL; 24134 } else 24135 info = vctxt->elemInfos[vctxt->depth]; 24136 24137 if (info == NULL) { 24138 info = (xmlSchemaNodeInfoPtr) 24139 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24140 if (info == NULL) { 24141 xmlSchemaVErrMemory(vctxt, 24142 "allocating an element info", NULL); 24143 return (NULL); 24144 } 24145 vctxt->elemInfos[vctxt->depth] = info; 24146 } else { 24147 if (info->localName != NULL) { 24148 VERROR_INT("xmlSchemaGetFreshElemInfo", 24149 "elem info has not been cleared"); 24150 return (NULL); 24151 } 24152 } 24153 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24154 info->nodeType = XML_ELEMENT_NODE; 24155 info->depth = vctxt->depth; 24156 24157 return (info); 24158 } 24159 24160 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24161 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24162 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24163 24164 static int 24165 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24166 xmlNodePtr node, 24167 xmlSchemaTypePtr type, 24168 xmlSchemaValType valType, 24169 const xmlChar * value, 24170 xmlSchemaValPtr val, 24171 unsigned long length, 24172 int fireErrors) 24173 { 24174 int ret, error = 0; 24175 24176 xmlSchemaTypePtr tmpType; 24177 xmlSchemaFacetLinkPtr facetLink; 24178 xmlSchemaFacetPtr facet; 24179 unsigned long len = 0; 24180 xmlSchemaWhitespaceValueType ws; 24181 24182 /* 24183 * In Libxml2, derived built-in types have currently no explicit facets. 24184 */ 24185 if (type->type == XML_SCHEMA_TYPE_BASIC) 24186 return (0); 24187 24188 /* 24189 * NOTE: Do not jump away, if the facetSet of the given type is 24190 * empty: until now, "pattern" and "enumeration" facets of the 24191 * *base types* need to be checked as well. 24192 */ 24193 if (type->facetSet == NULL) 24194 goto pattern_and_enum; 24195 24196 if (! WXS_IS_ATOMIC(type)) { 24197 if (WXS_IS_LIST(type)) 24198 goto WXS_IS_LIST; 24199 else 24200 goto pattern_and_enum; 24201 } 24202 24203 /* 24204 * Whitespace handling is only of importance for string-based 24205 * types. 24206 */ 24207 tmpType = xmlSchemaGetPrimitiveType(type); 24208 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24209 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24210 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24211 } else 24212 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24213 24214 /* 24215 * If the value was not computed (for string or 24216 * anySimpleType based types), then use the provided 24217 * type. 24218 */ 24219 if (val != NULL) 24220 valType = xmlSchemaGetValType(val); 24221 24222 ret = 0; 24223 for (facetLink = type->facetSet; facetLink != NULL; 24224 facetLink = facetLink->next) { 24225 /* 24226 * Skip the pattern "whiteSpace": it is used to 24227 * format the character content beforehand. 24228 */ 24229 switch (facetLink->facet->type) { 24230 case XML_SCHEMA_FACET_WHITESPACE: 24231 case XML_SCHEMA_FACET_PATTERN: 24232 case XML_SCHEMA_FACET_ENUMERATION: 24233 continue; 24234 case XML_SCHEMA_FACET_LENGTH: 24235 case XML_SCHEMA_FACET_MINLENGTH: 24236 case XML_SCHEMA_FACET_MAXLENGTH: 24237 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24238 valType, value, val, &len, ws); 24239 break; 24240 default: 24241 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24242 valType, value, val, ws); 24243 break; 24244 } 24245 if (ret < 0) { 24246 AERROR_INT("xmlSchemaValidateFacets", 24247 "validating against a atomic type facet"); 24248 return (-1); 24249 } else if (ret > 0) { 24250 if (fireErrors) 24251 xmlSchemaFacetErr(actxt, ret, node, 24252 value, len, type, facetLink->facet, NULL, NULL, NULL); 24253 else 24254 return (ret); 24255 if (error == 0) 24256 error = ret; 24257 } 24258 ret = 0; 24259 } 24260 24261 WXS_IS_LIST: 24262 if (! WXS_IS_LIST(type)) 24263 goto pattern_and_enum; 24264 /* 24265 * "length", "minLength" and "maxLength" of list types. 24266 */ 24267 ret = 0; 24268 for (facetLink = type->facetSet; facetLink != NULL; 24269 facetLink = facetLink->next) { 24270 24271 switch (facetLink->facet->type) { 24272 case XML_SCHEMA_FACET_LENGTH: 24273 case XML_SCHEMA_FACET_MINLENGTH: 24274 case XML_SCHEMA_FACET_MAXLENGTH: 24275 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24276 value, length, NULL); 24277 break; 24278 default: 24279 continue; 24280 } 24281 if (ret < 0) { 24282 AERROR_INT("xmlSchemaValidateFacets", 24283 "validating against a list type facet"); 24284 return (-1); 24285 } else if (ret > 0) { 24286 if (fireErrors) 24287 xmlSchemaFacetErr(actxt, ret, node, 24288 value, length, type, facetLink->facet, NULL, NULL, NULL); 24289 else 24290 return (ret); 24291 if (error == 0) 24292 error = ret; 24293 } 24294 ret = 0; 24295 } 24296 24297 pattern_and_enum: 24298 if (error >= 0) { 24299 int found = 0; 24300 /* 24301 * Process enumerations. Facet values are in the value space 24302 * of the defining type's base type. This seems to be a bug in the 24303 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24304 * Only the first set of enumerations in the ancestor-or-self axis 24305 * is used for validation. 24306 */ 24307 ret = 0; 24308 tmpType = type; 24309 do { 24310 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24311 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24312 continue; 24313 found = 1; 24314 ret = xmlSchemaAreValuesEqual(facet->val, val); 24315 if (ret == 1) 24316 break; 24317 else if (ret < 0) { 24318 AERROR_INT("xmlSchemaValidateFacets", 24319 "validating against an enumeration facet"); 24320 return (-1); 24321 } 24322 } 24323 if (ret != 0) 24324 break; 24325 /* 24326 * Break on the first set of enumerations. Any additional 24327 * enumerations which might be existent on the ancestors 24328 * of the current type are restricted by this set; thus 24329 * *must* *not* be taken into account. 24330 */ 24331 if (found) 24332 break; 24333 tmpType = tmpType->baseType; 24334 } while ((tmpType != NULL) && 24335 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24336 if (found && (ret == 0)) { 24337 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24338 if (fireErrors) { 24339 xmlSchemaFacetErr(actxt, ret, node, 24340 value, 0, type, NULL, NULL, NULL, NULL); 24341 } else 24342 return (ret); 24343 if (error == 0) 24344 error = ret; 24345 } 24346 } 24347 24348 if (error >= 0) { 24349 int found; 24350 /* 24351 * Process patters. Pattern facets are ORed at type level 24352 * and ANDed if derived. Walk the base type axis. 24353 */ 24354 tmpType = type; 24355 facet = NULL; 24356 do { 24357 found = 0; 24358 for (facetLink = tmpType->facetSet; facetLink != NULL; 24359 facetLink = facetLink->next) { 24360 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24361 continue; 24362 found = 1; 24363 /* 24364 * NOTE that for patterns, @value needs to be the 24365 * normalized vaule. 24366 */ 24367 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24368 if (ret == 1) 24369 break; 24370 else if (ret < 0) { 24371 AERROR_INT("xmlSchemaValidateFacets", 24372 "validating against a pattern facet"); 24373 return (-1); 24374 } else { 24375 /* 24376 * Save the last non-validating facet. 24377 */ 24378 facet = facetLink->facet; 24379 } 24380 } 24381 if (found && (ret != 1)) { 24382 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24383 if (fireErrors) { 24384 xmlSchemaFacetErr(actxt, ret, node, 24385 value, 0, type, facet, NULL, NULL, NULL); 24386 } else 24387 return (ret); 24388 if (error == 0) 24389 error = ret; 24390 break; 24391 } 24392 tmpType = tmpType->baseType; 24393 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24394 } 24395 24396 return (error); 24397 } 24398 24399 static xmlChar * 24400 xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24401 const xmlChar *value) 24402 { 24403 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24404 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24405 return (xmlSchemaCollapseString(value)); 24406 case XML_SCHEMA_WHITESPACE_REPLACE: 24407 return (xmlSchemaWhiteSpaceReplace(value)); 24408 default: 24409 return (NULL); 24410 } 24411 } 24412 24413 static int 24414 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24415 const xmlChar *value, 24416 xmlSchemaValPtr *val, 24417 int valNeeded) 24418 { 24419 int ret; 24420 const xmlChar *nsName; 24421 xmlChar *local, *prefix = NULL; 24422 24423 ret = xmlValidateQName(value, 1); 24424 if (ret != 0) { 24425 if (ret == -1) { 24426 VERROR_INT("xmlSchemaValidateQName", 24427 "calling xmlValidateQName()"); 24428 return (-1); 24429 } 24430 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24431 } 24432 /* 24433 * NOTE: xmlSplitQName2 will always return a duplicated 24434 * strings. 24435 */ 24436 local = xmlSplitQName2(value, &prefix); 24437 if (local == NULL) 24438 local = xmlStrdup(value); 24439 /* 24440 * OPTIMIZE TODO: Use flags for: 24441 * - is there any namespace binding? 24442 * - is there a default namespace? 24443 */ 24444 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24445 24446 if (prefix != NULL) { 24447 xmlFree(prefix); 24448 /* 24449 * A namespace must be found if the prefix is 24450 * NOT NULL. 24451 */ 24452 if (nsName == NULL) { 24453 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24454 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24455 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24456 "The QName value '%s' has no " 24457 "corresponding namespace declaration in " 24458 "scope", value, NULL); 24459 if (local != NULL) 24460 xmlFree(local); 24461 return (ret); 24462 } 24463 } 24464 if (valNeeded && val) { 24465 if (nsName != NULL) 24466 *val = xmlSchemaNewQNameValue( 24467 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24468 else 24469 *val = xmlSchemaNewQNameValue(NULL, 24470 BAD_CAST local); 24471 } else 24472 xmlFree(local); 24473 return (0); 24474 } 24475 24476 /* 24477 * cvc-simple-type 24478 */ 24479 static int 24480 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24481 xmlNodePtr node, 24482 xmlSchemaTypePtr type, 24483 const xmlChar *value, 24484 xmlSchemaValPtr *retVal, 24485 int fireErrors, 24486 int normalize, 24487 int isNormalized) 24488 { 24489 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24490 xmlSchemaValPtr val = NULL; 24491 /* xmlSchemaWhitespaceValueType ws; */ 24492 xmlChar *normValue = NULL; 24493 24494 #define NORMALIZE(atype) \ 24495 if ((! isNormalized) && \ 24496 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24497 normValue = xmlSchemaNormalizeValue(atype, value); \ 24498 if (normValue != NULL) \ 24499 value = normValue; \ 24500 isNormalized = 1; \ 24501 } 24502 24503 if ((retVal != NULL) && (*retVal != NULL)) { 24504 xmlSchemaFreeValue(*retVal); 24505 *retVal = NULL; 24506 } 24507 /* 24508 * 3.14.4 Simple Type Definition Validation Rules 24509 * Validation Rule: String Valid 24510 */ 24511 /* 24512 * 1 It is schema-valid with respect to that definition as defined 24513 * by Datatype Valid in [XML Schemas: Datatypes]. 24514 */ 24515 /* 24516 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24517 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then 24518 * the string must be a `declared entity name`. 24519 */ 24520 /* 24521 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24522 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), 24523 * then every whitespace-delimited substring of the string must be a `declared 24524 * entity name`. 24525 */ 24526 /* 24527 * 2.3 otherwise no further condition applies. 24528 */ 24529 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24530 valNeeded = 1; 24531 if (value == NULL) 24532 value = BAD_CAST ""; 24533 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24534 xmlSchemaTypePtr biType; /* The built-in type. */ 24535 /* 24536 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match` 24537 * a literal in the `lexical space` of {base type definition}" 24538 */ 24539 /* 24540 * Whitespace-normalize. 24541 */ 24542 NORMALIZE(type); 24543 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24544 /* 24545 * Get the built-in type. 24546 */ 24547 biType = type->baseType; 24548 while ((biType != NULL) && 24549 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24550 biType = biType->baseType; 24551 24552 if (biType == NULL) { 24553 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24554 "could not get the built-in type"); 24555 goto internal_error; 24556 } 24557 } else 24558 biType = type; 24559 /* 24560 * NOTATIONs need to be processed here, since they need 24561 * to lookup in the hashtable of NOTATION declarations of the schema. 24562 */ 24563 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24564 switch (biType->builtInType) { 24565 case XML_SCHEMAS_NOTATION: 24566 ret = xmlSchemaValidateNotation( 24567 (xmlSchemaValidCtxtPtr) actxt, 24568 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24569 NULL, value, &val, valNeeded); 24570 break; 24571 case XML_SCHEMAS_QNAME: 24572 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24573 value, &val, valNeeded); 24574 break; 24575 default: 24576 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24577 if (valNeeded) 24578 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24579 value, &val, node); 24580 else 24581 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24582 value, NULL, node); 24583 break; 24584 } 24585 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24586 switch (biType->builtInType) { 24587 case XML_SCHEMAS_NOTATION: 24588 ret = xmlSchemaValidateNotation(NULL, 24589 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24590 value, &val, valNeeded); 24591 break; 24592 default: 24593 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24594 if (valNeeded) 24595 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24596 value, &val, node); 24597 else 24598 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24599 value, NULL, node); 24600 break; 24601 } 24602 } else { 24603 /* 24604 * Validation via a public API is not implemented yet. 24605 */ 24606 TODO 24607 goto internal_error; 24608 } 24609 if (ret != 0) { 24610 if (ret < 0) { 24611 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24612 "validating against a built-in type"); 24613 goto internal_error; 24614 } 24615 if (WXS_IS_LIST(type)) 24616 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24617 else 24618 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24619 } 24620 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24621 /* 24622 * Check facets. 24623 */ 24624 ret = xmlSchemaValidateFacets(actxt, node, type, 24625 (xmlSchemaValType) biType->builtInType, value, val, 24626 0, fireErrors); 24627 if (ret != 0) { 24628 if (ret < 0) { 24629 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24630 "validating facets of atomic simple type"); 24631 goto internal_error; 24632 } 24633 if (WXS_IS_LIST(type)) 24634 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24635 else 24636 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24637 } 24638 } 24639 if (fireErrors && (ret > 0)) 24640 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24641 } else if (WXS_IS_LIST(type)) { 24642 24643 xmlSchemaTypePtr itemType; 24644 const xmlChar *cur, *end; 24645 xmlChar *tmpValue = NULL; 24646 unsigned long len = 0; 24647 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24648 /* 1.2.2 if {variety} is `list` then the string must be a sequence 24649 * of white space separated tokens, each of which `match`es a literal 24650 * in the `lexical space` of {item type definition} 24651 */ 24652 /* 24653 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24654 * the list type has an enum or pattern facet. 24655 */ 24656 NORMALIZE(type); 24657 /* 24658 * VAL TODO: Optimize validation of empty values. 24659 * VAL TODO: We do not have computed values for lists. 24660 */ 24661 itemType = WXS_LIST_ITEMTYPE(type); 24662 cur = value; 24663 do { 24664 while (IS_BLANK_CH(*cur)) 24665 cur++; 24666 end = cur; 24667 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24668 end++; 24669 if (end == cur) 24670 break; 24671 tmpValue = xmlStrndup(cur, end - cur); 24672 len++; 24673 24674 if (valNeeded) 24675 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24676 tmpValue, &curVal, fireErrors, 0, 1); 24677 else 24678 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24679 tmpValue, NULL, fireErrors, 0, 1); 24680 FREE_AND_NULL(tmpValue); 24681 if (curVal != NULL) { 24682 /* 24683 * Add to list of computed values. 24684 */ 24685 if (val == NULL) 24686 val = curVal; 24687 else 24688 xmlSchemaValueAppend(prevVal, curVal); 24689 prevVal = curVal; 24690 curVal = NULL; 24691 } 24692 if (ret != 0) { 24693 if (ret < 0) { 24694 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24695 "validating an item of list simple type"); 24696 goto internal_error; 24697 } 24698 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24699 break; 24700 } 24701 cur = end; 24702 } while (*cur != 0); 24703 FREE_AND_NULL(tmpValue); 24704 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24705 /* 24706 * Apply facets (pattern, enumeration). 24707 */ 24708 ret = xmlSchemaValidateFacets(actxt, node, type, 24709 XML_SCHEMAS_UNKNOWN, value, val, 24710 len, fireErrors); 24711 if (ret != 0) { 24712 if (ret < 0) { 24713 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24714 "validating facets of list simple type"); 24715 goto internal_error; 24716 } 24717 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24718 } 24719 } 24720 if (fireErrors && (ret > 0)) { 24721 /* 24722 * Report the normalized value. 24723 */ 24724 normalize = 1; 24725 NORMALIZE(type); 24726 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24727 } 24728 } else if (WXS_IS_UNION(type)) { 24729 xmlSchemaTypeLinkPtr memberLink; 24730 /* 24731 * TODO: For all datatypes `derived` by `union` whiteSpace does 24732 * not apply directly; however, the normalization behavior of `union` 24733 * types is controlled by the value of whiteSpace on that one of the 24734 * `memberTypes` against which the `union` is successfully validated. 24735 * 24736 * This means that the value is normalized by the first validating 24737 * member type, then the facets of the union type are applied. This 24738 * needs changing of the value! 24739 */ 24740 24741 /* 24742 * 1.2.3 if {variety} is `union` then the string must `match` a 24743 * literal in the `lexical space` of at least one member of 24744 * {member type definitions} 24745 */ 24746 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24747 if (memberLink == NULL) { 24748 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24749 "union simple type has no member types"); 24750 goto internal_error; 24751 } 24752 /* 24753 * Always normalize union type values, since we currently 24754 * cannot store the whitespace information with the value 24755 * itself; otherwise a later value-comparison would be 24756 * not possible. 24757 */ 24758 while (memberLink != NULL) { 24759 if (valNeeded) 24760 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24761 memberLink->type, value, &val, 0, 1, 0); 24762 else 24763 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24764 memberLink->type, value, NULL, 0, 1, 0); 24765 if (ret <= 0) 24766 break; 24767 memberLink = memberLink->next; 24768 } 24769 if (ret != 0) { 24770 if (ret < 0) { 24771 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24772 "validating members of union simple type"); 24773 goto internal_error; 24774 } 24775 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24776 } 24777 /* 24778 * Apply facets (pattern, enumeration). 24779 */ 24780 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24781 /* 24782 * The normalization behavior of `union` types is controlled by 24783 * the value of whiteSpace on that one of the `memberTypes` 24784 * against which the `union` is successfully validated. 24785 */ 24786 NORMALIZE(memberLink->type); 24787 ret = xmlSchemaValidateFacets(actxt, node, type, 24788 XML_SCHEMAS_UNKNOWN, value, val, 24789 0, fireErrors); 24790 if (ret != 0) { 24791 if (ret < 0) { 24792 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24793 "validating facets of union simple type"); 24794 goto internal_error; 24795 } 24796 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24797 } 24798 } 24799 if (fireErrors && (ret > 0)) 24800 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24801 } 24802 24803 if (normValue != NULL) 24804 xmlFree(normValue); 24805 if (ret == 0) { 24806 if (retVal != NULL) 24807 *retVal = val; 24808 else if (val != NULL) 24809 xmlSchemaFreeValue(val); 24810 } else if (val != NULL) 24811 xmlSchemaFreeValue(val); 24812 return (ret); 24813 internal_error: 24814 if (normValue != NULL) 24815 xmlFree(normValue); 24816 if (val != NULL) 24817 xmlSchemaFreeValue(val); 24818 return (-1); 24819 } 24820 24821 static int 24822 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24823 const xmlChar *value, 24824 const xmlChar **nsName, 24825 const xmlChar **localName) 24826 { 24827 int ret = 0; 24828 24829 if ((nsName == NULL) || (localName == NULL)) 24830 return (-1); 24831 *nsName = NULL; 24832 *localName = NULL; 24833 24834 ret = xmlValidateQName(value, 1); 24835 if (ret == -1) 24836 return (-1); 24837 if (ret > 0) { 24838 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24839 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24840 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24841 return (1); 24842 } 24843 { 24844 xmlChar *local = NULL; 24845 xmlChar *prefix; 24846 24847 /* 24848 * NOTE: xmlSplitQName2 will return a duplicated 24849 * string. 24850 */ 24851 local = xmlSplitQName2(value, &prefix); 24852 if (local == NULL) 24853 *localName = xmlDictLookup(vctxt->dict, value, -1); 24854 else { 24855 *localName = xmlDictLookup(vctxt->dict, local, -1); 24856 xmlFree(local); 24857 } 24858 24859 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24860 24861 if (prefix != NULL) { 24862 xmlFree(prefix); 24863 /* 24864 * A namespace must be found if the prefix is NOT NULL. 24865 */ 24866 if (*nsName == NULL) { 24867 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24868 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24869 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24870 "The QName value '%s' has no " 24871 "corresponding namespace declaration in scope", 24872 value, NULL); 24873 return (2); 24874 } 24875 } 24876 } 24877 return (0); 24878 } 24879 24880 static int 24881 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24882 xmlSchemaAttrInfoPtr iattr, 24883 xmlSchemaTypePtr *localType, 24884 xmlSchemaElementPtr elemDecl) 24885 { 24886 int ret = 0; 24887 /* 24888 * cvc-elt (3.3.4) : (4) 24889 * AND 24890 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24891 * (1.2.1.2.1) - (1.2.1.2.4) 24892 * Handle 'xsi:type'. 24893 */ 24894 if (localType == NULL) 24895 return (-1); 24896 *localType = NULL; 24897 if (iattr == NULL) 24898 return (0); 24899 else { 24900 const xmlChar *nsName = NULL, *local = NULL; 24901 /* 24902 * TODO: We should report a *warning* that the type was overriden 24903 * by the instance. 24904 */ 24905 ACTIVATE_ATTRIBUTE(iattr); 24906 /* 24907 * (cvc-elt) (3.3.4) : (4.1) 24908 * (cvc-assess-elt) (1.2.1.2.2) 24909 */ 24910 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24911 &nsName, &local); 24912 if (ret != 0) { 24913 if (ret < 0) { 24914 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24915 "calling xmlSchemaQNameExpand() to validate the " 24916 "attribute 'xsi:type'"); 24917 goto internal_error; 24918 } 24919 goto exit; 24920 } 24921 /* 24922 * (cvc-elt) (3.3.4) : (4.2) 24923 * (cvc-assess-elt) (1.2.1.2.3) 24924 */ 24925 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24926 if (*localType == NULL) { 24927 xmlChar *str = NULL; 24928 24929 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24930 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24931 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24932 "The QName value '%s' of the xsi:type attribute does not " 24933 "resolve to a type definition", 24934 xmlSchemaFormatQName(&str, nsName, local), NULL); 24935 FREE_AND_NULL(str); 24936 ret = vctxt->err; 24937 goto exit; 24938 } 24939 if (elemDecl != NULL) { 24940 int set = 0; 24941 24942 /* 24943 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24944 * "The `local type definition` must be validly 24945 * derived from the {type definition} given the union of 24946 * the {disallowed substitutions} and the {type definition}'s 24947 * {prohibited substitutions}, as defined in 24948 * Type Derivation OK (Complex) ($3.4.6) 24949 * (if it is a complex type definition), 24950 * or given {disallowed substitutions} as defined in Type 24951 * Derivation OK (Simple) ($3.14.6) (if it is a simple type 24952 * definition)." 24953 * 24954 * {disallowed substitutions}: the "block" on the element decl. 24955 * {prohibited substitutions}: the "block" on the type def. 24956 */ 24957 /* 24958 * OPTIMIZE TODO: We could map types already evaluated 24959 * to be validly derived from other types to avoid checking 24960 * this over and over for the same types. 24961 */ 24962 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24963 (elemDecl->subtypes->flags & 24964 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24965 set |= SUBSET_EXTENSION; 24966 24967 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24968 (elemDecl->subtypes->flags & 24969 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24970 set |= SUBSET_RESTRICTION; 24971 24972 /* 24973 * REMOVED and CHANGED since this produced a parser context 24974 * which adds to the string dict of the schema. So this would 24975 * change the schema and we don't want this. We don't need 24976 * the parser context anymore. 24977 * 24978 * if ((vctxt->pctxt == NULL) && 24979 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24980 * return (-1); 24981 */ 24982 24983 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24984 elemDecl->subtypes, set) != 0) { 24985 xmlChar *str = NULL; 24986 24987 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24988 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 24989 "The type definition '%s', specified by xsi:type, is " 24990 "blocked or not validly derived from the type definition " 24991 "of the element declaration", 24992 xmlSchemaFormatQName(&str, 24993 (*localType)->targetNamespace, 24994 (*localType)->name), 24995 NULL); 24996 FREE_AND_NULL(str); 24997 ret = vctxt->err; 24998 *localType = NULL; 24999 } 25000 } 25001 } 25002 exit: 25003 ACTIVATE_ELEM; 25004 return (ret); 25005 internal_error: 25006 ACTIVATE_ELEM; 25007 return (-1); 25008 } 25009 25010 static int 25011 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 25012 { 25013 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 25014 xmlSchemaTypePtr actualType; 25015 25016 /* 25017 * cvc-elt (3.3.4) : 1 25018 */ 25019 if (elemDecl == NULL) { 25020 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 25021 "No matching declaration available"); 25022 return (vctxt->err); 25023 } 25024 actualType = WXS_ELEM_TYPEDEF(elemDecl); 25025 /* 25026 * cvc-elt (3.3.4) : 2 25027 */ 25028 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 25029 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 25030 "The element declaration is abstract"); 25031 return (vctxt->err); 25032 } 25033 if (actualType == NULL) { 25034 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25035 "The type definition is absent"); 25036 return (XML_SCHEMAV_CVC_TYPE_1); 25037 } 25038 if (vctxt->nbAttrInfos != 0) { 25039 int ret; 25040 xmlSchemaAttrInfoPtr iattr; 25041 /* 25042 * cvc-elt (3.3.4) : 3 25043 * Handle 'xsi:nil'. 25044 */ 25045 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25046 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25047 if (iattr) { 25048 ACTIVATE_ATTRIBUTE(iattr); 25049 /* 25050 * Validate the value. 25051 */ 25052 ret = xmlSchemaVCheckCVCSimpleType( 25053 ACTXT_CAST vctxt, NULL, 25054 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25055 iattr->value, &(iattr->val), 1, 0, 0); 25056 ACTIVATE_ELEM; 25057 if (ret < 0) { 25058 VERROR_INT("xmlSchemaValidateElemDecl", 25059 "calling xmlSchemaVCheckCVCSimpleType() to " 25060 "validate the attribute 'xsi:nil'"); 25061 return (-1); 25062 } 25063 if (ret == 0) { 25064 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25065 /* 25066 * cvc-elt (3.3.4) : 3.1 25067 */ 25068 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25069 "The element is not 'nillable'"); 25070 /* Does not return an error on purpose. */ 25071 } else { 25072 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25073 /* 25074 * cvc-elt (3.3.4) : 3.2.2 25075 */ 25076 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25077 (elemDecl->value != NULL)) { 25078 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25079 "The element cannot be 'nilled' because " 25080 "there is a fixed value constraint defined " 25081 "for it"); 25082 /* Does not return an error on purpose. */ 25083 } else 25084 vctxt->inode->flags |= 25085 XML_SCHEMA_ELEM_INFO_NILLED; 25086 } 25087 } 25088 } 25089 } 25090 /* 25091 * cvc-elt (3.3.4) : 4 25092 * Handle 'xsi:type'. 25093 */ 25094 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25095 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25096 if (iattr) { 25097 xmlSchemaTypePtr localType = NULL; 25098 25099 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25100 elemDecl); 25101 if (ret != 0) { 25102 if (ret == -1) { 25103 VERROR_INT("xmlSchemaValidateElemDecl", 25104 "calling xmlSchemaProcessXSIType() to " 25105 "process the attribute 'xsi:type'"); 25106 return (-1); 25107 } 25108 /* Does not return an error on purpose. */ 25109 } 25110 if (localType != NULL) { 25111 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25112 actualType = localType; 25113 } 25114 } 25115 } 25116 /* 25117 * IDC: Register identity-constraint XPath matchers. 25118 */ 25119 if ((elemDecl->idcs != NULL) && 25120 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25121 return (-1); 25122 /* 25123 * No actual type definition. 25124 */ 25125 if (actualType == NULL) { 25126 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25127 "The type definition is absent"); 25128 return (XML_SCHEMAV_CVC_TYPE_1); 25129 } 25130 /* 25131 * Remember the actual type definition. 25132 */ 25133 vctxt->inode->typeDef = actualType; 25134 25135 return (0); 25136 } 25137 25138 static int 25139 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25140 { 25141 xmlSchemaAttrInfoPtr iattr; 25142 int ret = 0, i; 25143 25144 /* 25145 * SPEC cvc-type (3.1.1) 25146 * "The attributes of must be empty, excepting those whose namespace 25147 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25148 * whose local name is one of type, nil, schemaLocation or 25149 * noNamespaceSchemaLocation." 25150 */ 25151 if (vctxt->nbAttrInfos == 0) 25152 return (0); 25153 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25154 iattr = vctxt->attrInfos[i]; 25155 if (! iattr->metaType) { 25156 ACTIVATE_ATTRIBUTE(iattr) 25157 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25158 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25159 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25160 } 25161 } 25162 ACTIVATE_ELEM 25163 return (ret); 25164 } 25165 25166 /* 25167 * Cleanup currently used attribute infos. 25168 */ 25169 static void 25170 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25171 { 25172 int i; 25173 xmlSchemaAttrInfoPtr attr; 25174 25175 if (vctxt->nbAttrInfos == 0) 25176 return; 25177 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25178 attr = vctxt->attrInfos[i]; 25179 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25180 if (attr->localName != NULL) 25181 xmlFree((xmlChar *) attr->localName); 25182 if (attr->nsName != NULL) 25183 xmlFree((xmlChar *) attr->nsName); 25184 } 25185 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25186 if (attr->value != NULL) 25187 xmlFree((xmlChar *) attr->value); 25188 } 25189 if (attr->val != NULL) { 25190 xmlSchemaFreeValue(attr->val); 25191 attr->val = NULL; 25192 } 25193 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25194 } 25195 vctxt->nbAttrInfos = 0; 25196 } 25197 25198 /* 25199 * 3.4.4 Complex Type Definition Validation Rules 25200 * Element Locally Valid (Complex Type) (cvc-complex-type) 25201 * 3.2.4 Attribute Declaration Validation Rules 25202 * Validation Rule: Attribute Locally Valid (cvc-attribute) 25203 * Attribute Locally Valid (Use) (cvc-au) 25204 * 25205 * Only "assessed" attribute information items will be visible to 25206 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25207 */ 25208 static int 25209 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25210 { 25211 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25212 xmlSchemaItemListPtr attrUseList; 25213 xmlSchemaAttributeUsePtr attrUse = NULL; 25214 xmlSchemaAttributePtr attrDecl = NULL; 25215 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25216 int i, j, found, nbAttrs, nbUses; 25217 int xpathRes = 0, res, wildIDs = 0, fixed; 25218 xmlNodePtr defAttrOwnerElem = NULL; 25219 25220 /* 25221 * SPEC (cvc-attribute) 25222 * (1) "The declaration must not be `absent` (see Missing 25223 * Sub-components ($5.3) for how this can fail to be 25224 * the case)." 25225 * (2) "Its {type definition} must not be absent." 25226 * 25227 * NOTE (1) + (2): This is not handled here, since we currently do not 25228 * allow validation against schemas which have missing sub-components. 25229 * 25230 * SPEC (cvc-complex-type) 25231 * (3) "For each attribute information item in the element information 25232 * item's [attributes] excepting those whose [namespace name] is 25233 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25234 * [local name] is one of type, nil, schemaLocation or 25235 * noNamespaceSchemaLocation, the appropriate case among the following 25236 * must be true: 25237 * 25238 */ 25239 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25240 /* 25241 * @nbAttrs is the number of attributes present in the instance. 25242 */ 25243 nbAttrs = vctxt->nbAttrInfos; 25244 if (attrUseList != NULL) 25245 nbUses = attrUseList->nbItems; 25246 else 25247 nbUses = 0; 25248 for (i = 0; i < nbUses; i++) { 25249 found = 0; 25250 attrUse = attrUseList->items[i]; 25251 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25252 for (j = 0; j < nbAttrs; j++) { 25253 iattr = vctxt->attrInfos[j]; 25254 /* 25255 * SPEC (cvc-complex-type) (3) 25256 * Skip meta attributes. 25257 */ 25258 if (iattr->metaType) 25259 continue; 25260 if (iattr->localName[0] != attrDecl->name[0]) 25261 continue; 25262 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25263 continue; 25264 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25265 continue; 25266 found = 1; 25267 /* 25268 * SPEC (cvc-complex-type) 25269 * (3.1) "If there is among the {attribute uses} an attribute 25270 * use with an {attribute declaration} whose {name} matches 25271 * the attribute information item's [local name] and whose 25272 * {target namespace} is identical to the attribute information 25273 * item's [namespace name] (where an `absent` {target namespace} 25274 * is taken to be identical to a [namespace name] with no value), 25275 * then the attribute information must be `valid` with respect 25276 * to that attribute use as per Attribute Locally Valid (Use) 25277 * ($3.5.4). In this case the {attribute declaration} of that 25278 * attribute use is the `context-determined declaration` for the 25279 * attribute information item with respect to Schema-Validity 25280 * Assessment (Attribute) ($3.2.4) and 25281 * Assessment Outcome (Attribute) ($3.2.5). 25282 */ 25283 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25284 iattr->use = attrUse; 25285 /* 25286 * Context-determined declaration. 25287 */ 25288 iattr->decl = attrDecl; 25289 iattr->typeDef = attrDecl->subtypes; 25290 break; 25291 } 25292 25293 if (found) 25294 continue; 25295 25296 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25297 /* 25298 * Handle non-existent, required attributes. 25299 * 25300 * SPEC (cvc-complex-type) 25301 * (4) "The {attribute declaration} of each attribute use in 25302 * the {attribute uses} whose {required} is true matches one 25303 * of the attribute information items in the element information 25304 * item's [attributes] as per clause 3.1 above." 25305 */ 25306 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25307 if (tmpiattr == NULL) { 25308 VERROR_INT( 25309 "xmlSchemaVAttributesComplex", 25310 "calling xmlSchemaGetFreshAttrInfo()"); 25311 return (-1); 25312 } 25313 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25314 tmpiattr->use = attrUse; 25315 tmpiattr->decl = attrDecl; 25316 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25317 ((attrUse->defValue != NULL) || 25318 (attrDecl->defValue != NULL))) { 25319 /* 25320 * Handle non-existent, optional, default/fixed attributes. 25321 */ 25322 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25323 if (tmpiattr == NULL) { 25324 VERROR_INT( 25325 "xmlSchemaVAttributesComplex", 25326 "calling xmlSchemaGetFreshAttrInfo()"); 25327 return (-1); 25328 } 25329 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25330 tmpiattr->use = attrUse; 25331 tmpiattr->decl = attrDecl; 25332 tmpiattr->typeDef = attrDecl->subtypes; 25333 tmpiattr->localName = attrDecl->name; 25334 tmpiattr->nsName = attrDecl->targetNamespace; 25335 } 25336 } 25337 25338 if (vctxt->nbAttrInfos == 0) 25339 return (0); 25340 /* 25341 * Validate against the wildcard. 25342 */ 25343 if (type->attributeWildcard != NULL) { 25344 /* 25345 * SPEC (cvc-complex-type) 25346 * (3.2.1) "There must be an {attribute wildcard}." 25347 */ 25348 for (i = 0; i < nbAttrs; i++) { 25349 iattr = vctxt->attrInfos[i]; 25350 /* 25351 * SPEC (cvc-complex-type) (3) 25352 * Skip meta attributes. 25353 */ 25354 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25355 continue; 25356 /* 25357 * SPEC (cvc-complex-type) 25358 * (3.2.2) "The attribute information item must be `valid` with 25359 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)." 25360 * 25361 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25362 * "... its [namespace name] must be `valid` with respect to 25363 * the wildcard constraint, as defined in Wildcard allows 25364 * Namespace Name ($3.10.4)." 25365 */ 25366 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25367 iattr->nsName) == 0) { 25368 /* 25369 * Handle processContents. 25370 * 25371 * SPEC (cvc-wildcard): 25372 * processContents | context-determined declaration: 25373 * "strict" "mustFind" 25374 * "lax" "none" 25375 * "skip" "skip" 25376 */ 25377 if (type->attributeWildcard->processContents == 25378 XML_SCHEMAS_ANY_SKIP) { 25379 /* 25380 * context-determined declaration = "skip" 25381 * 25382 * SPEC PSVI Assessment Outcome (Attribute) 25383 * [validity] = "notKnown" 25384 * [validation attempted] = "none" 25385 */ 25386 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25387 continue; 25388 } 25389 /* 25390 * Find an attribute declaration. 25391 */ 25392 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25393 iattr->localName, iattr->nsName); 25394 if (iattr->decl != NULL) { 25395 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25396 /* 25397 * SPEC (cvc-complex-type) 25398 * (5) "Let [Definition:] the wild IDs be the set of 25399 * all attribute information item to which clause 3.2 25400 * applied and whose `validation` resulted in a 25401 * `context-determined declaration` of mustFind or no 25402 * `context-determined declaration` at all, and whose 25403 * [local name] and [namespace name] resolve (as 25404 * defined by QName resolution (Instance) ($3.15.4)) to 25405 * an attribute declaration whose {type definition} is 25406 * or is derived from ID. Then all of the following 25407 * must be true:" 25408 */ 25409 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25410 if (xmlSchemaIsDerivedFromBuiltInType( 25411 iattr->typeDef, XML_SCHEMAS_ID)) { 25412 /* 25413 * SPEC (5.1) "There must be no more than one 25414 * item in `wild IDs`." 25415 */ 25416 if (wildIDs != 0) { 25417 /* VAL TODO */ 25418 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25419 TODO 25420 continue; 25421 } 25422 wildIDs++; 25423 /* 25424 * SPEC (cvc-complex-type) 25425 * (5.2) "If `wild IDs` is non-empty, there must not 25426 * be any attribute uses among the {attribute uses} 25427 * whose {attribute declaration}'s {type definition} 25428 * is or is derived from ID." 25429 */ 25430 if (attrUseList != NULL) { 25431 for (j = 0; j < attrUseList->nbItems; j++) { 25432 if (xmlSchemaIsDerivedFromBuiltInType( 25433 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25434 XML_SCHEMAS_ID)) { 25435 /* URGENT VAL TODO: implement */ 25436 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25437 TODO 25438 break; 25439 } 25440 } 25441 } 25442 } 25443 } else if (type->attributeWildcard->processContents == 25444 XML_SCHEMAS_ANY_LAX) { 25445 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25446 /* 25447 * SPEC PSVI Assessment Outcome (Attribute) 25448 * [validity] = "notKnown" 25449 * [validation attempted] = "none" 25450 */ 25451 } else { 25452 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25453 } 25454 } 25455 } 25456 } 25457 25458 if (vctxt->nbAttrInfos == 0) 25459 return (0); 25460 25461 /* 25462 * Get the owner element; needed for creation of default attributes. 25463 * This fixes bug #341337, reported by David Grohmann. 25464 */ 25465 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25466 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25467 if (ielem && ielem->node && ielem->node->doc) 25468 defAttrOwnerElem = ielem->node; 25469 } 25470 /* 25471 * Validate values, create default attributes, evaluate IDCs. 25472 */ 25473 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25474 iattr = vctxt->attrInfos[i]; 25475 /* 25476 * VAL TODO: Note that we won't try to resolve IDCs to 25477 * "lax" and "skip" validated attributes. Check what to 25478 * do in this case. 25479 */ 25480 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25481 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25482 continue; 25483 /* 25484 * VAL TODO: What to do if the type definition is missing? 25485 */ 25486 if (iattr->typeDef == NULL) { 25487 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25488 continue; 25489 } 25490 25491 ACTIVATE_ATTRIBUTE(iattr); 25492 fixed = 0; 25493 xpathRes = 0; 25494 25495 if (vctxt->xpathStates != NULL) { 25496 /* 25497 * Evaluate IDCs. 25498 */ 25499 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25500 XML_ATTRIBUTE_NODE); 25501 if (xpathRes == -1) { 25502 VERROR_INT("xmlSchemaVAttributesComplex", 25503 "calling xmlSchemaXPathEvaluate()"); 25504 goto internal_error; 25505 } 25506 } 25507 25508 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25509 /* 25510 * Default/fixed attributes. 25511 * We need the value only if we need to resolve IDCs or 25512 * will create default attributes. 25513 */ 25514 if ((xpathRes) || (defAttrOwnerElem)) { 25515 if (iattr->use->defValue != NULL) { 25516 iattr->value = (xmlChar *) iattr->use->defValue; 25517 iattr->val = iattr->use->defVal; 25518 } else { 25519 iattr->value = (xmlChar *) iattr->decl->defValue; 25520 iattr->val = iattr->decl->defVal; 25521 } 25522 /* 25523 * IDCs will consume the precomputed default value, 25524 * so we need to clone it. 25525 */ 25526 if (iattr->val == NULL) { 25527 VERROR_INT("xmlSchemaVAttributesComplex", 25528 "default/fixed value on an attribute use was " 25529 "not precomputed"); 25530 goto internal_error; 25531 } 25532 iattr->val = xmlSchemaCopyValue(iattr->val); 25533 if (iattr->val == NULL) { 25534 VERROR_INT("xmlSchemaVAttributesComplex", 25535 "calling xmlSchemaCopyValue()"); 25536 goto internal_error; 25537 } 25538 } 25539 /* 25540 * PSVI: Add the default attribute to the current element. 25541 * VAL TODO: Should we use the *normalized* value? This currently 25542 * uses the *initial* value. 25543 */ 25544 25545 if (defAttrOwnerElem) { 25546 xmlChar *normValue; 25547 const xmlChar *value; 25548 25549 value = iattr->value; 25550 /* 25551 * Normalize the value. 25552 */ 25553 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25554 iattr->value); 25555 if (normValue != NULL) 25556 value = BAD_CAST normValue; 25557 25558 if (iattr->nsName == NULL) { 25559 if (xmlNewProp(defAttrOwnerElem, 25560 iattr->localName, value) == NULL) { 25561 VERROR_INT("xmlSchemaVAttributesComplex", 25562 "calling xmlNewProp()"); 25563 if (normValue != NULL) 25564 xmlFree(normValue); 25565 goto internal_error; 25566 } 25567 } else { 25568 xmlNsPtr ns; 25569 25570 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25571 defAttrOwnerElem, iattr->nsName); 25572 if (ns == NULL) { 25573 xmlChar prefix[12]; 25574 int counter = 0; 25575 25576 /* 25577 * Create a namespace declaration on the validation 25578 * root node if no namespace declaration is in scope. 25579 */ 25580 do { 25581 snprintf((char *) prefix, 12, "p%d", counter++); 25582 ns = xmlSearchNs(defAttrOwnerElem->doc, 25583 defAttrOwnerElem, BAD_CAST prefix); 25584 if (counter > 1000) { 25585 VERROR_INT( 25586 "xmlSchemaVAttributesComplex", 25587 "could not compute a ns prefix for a " 25588 "default/fixed attribute"); 25589 if (normValue != NULL) 25590 xmlFree(normValue); 25591 goto internal_error; 25592 } 25593 } while (ns != NULL); 25594 ns = xmlNewNs(vctxt->validationRoot, 25595 iattr->nsName, BAD_CAST prefix); 25596 } 25597 /* 25598 * TODO: 25599 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25600 * If we have QNames: do we need to ensure there's a 25601 * prefix defined for the QName? 25602 */ 25603 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25604 } 25605 if (normValue != NULL) 25606 xmlFree(normValue); 25607 } 25608 /* 25609 * Go directly to IDC evaluation. 25610 */ 25611 goto eval_idcs; 25612 } 25613 /* 25614 * Validate the value. 25615 */ 25616 if (vctxt->value != NULL) { 25617 /* 25618 * Free last computed value; just for safety reasons. 25619 */ 25620 xmlSchemaFreeValue(vctxt->value); 25621 vctxt->value = NULL; 25622 } 25623 /* 25624 * Note that the attribute *use* can be unavailable, if 25625 * the attribute was a wild attribute. 25626 */ 25627 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25628 ((iattr->use != NULL) && 25629 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25630 fixed = 1; 25631 else 25632 fixed = 0; 25633 /* 25634 * SPEC (cvc-attribute) 25635 * (3) "The item's `normalized value` must be locally `valid` 25636 * with respect to that {type definition} as per 25637 * String Valid ($3.14.4)." 25638 * 25639 * VAL TODO: Do we already have the 25640 * "normalized attribute value" here? 25641 */ 25642 if (xpathRes || fixed) { 25643 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25644 /* 25645 * Request a computed value. 25646 */ 25647 res = xmlSchemaVCheckCVCSimpleType( 25648 ACTXT_CAST vctxt, 25649 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25650 1, 1, 0); 25651 } else { 25652 res = xmlSchemaVCheckCVCSimpleType( 25653 ACTXT_CAST vctxt, 25654 iattr->node, iattr->typeDef, iattr->value, NULL, 25655 1, 0, 0); 25656 } 25657 25658 if (res != 0) { 25659 if (res == -1) { 25660 VERROR_INT("xmlSchemaVAttributesComplex", 25661 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25662 goto internal_error; 25663 } 25664 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25665 /* 25666 * SPEC PSVI Assessment Outcome (Attribute) 25667 * [validity] = "invalid" 25668 */ 25669 goto eval_idcs; 25670 } 25671 25672 if (fixed) { 25673 /* 25674 * SPEC Attribute Locally Valid (Use) (cvc-au) 25675 * "For an attribute information item to be `valid` 25676 * with respect to an attribute use its *normalized* 25677 * value must match the *canonical* lexical 25678 * representation of the attribute use's {value 25679 * constraint}value, if it is present and fixed." 25680 * 25681 * VAL TODO: The requirement for the *canonical* value 25682 * will be removed in XML Schema 1.1. 25683 */ 25684 /* 25685 * SPEC Attribute Locally Valid (cvc-attribute) 25686 * (4) "The item's *actual* value must match the *value* of 25687 * the {value constraint}, if it is present and fixed." 25688 */ 25689 if (iattr->val == NULL) { 25690 /* VAL TODO: A value was not precomputed. */ 25691 TODO 25692 goto eval_idcs; 25693 } 25694 if ((iattr->use != NULL) && 25695 (iattr->use->defValue != NULL)) { 25696 if (iattr->use->defVal == NULL) { 25697 /* VAL TODO: A default value was not precomputed. */ 25698 TODO 25699 goto eval_idcs; 25700 } 25701 iattr->vcValue = iattr->use->defValue; 25702 /* 25703 if (xmlSchemaCompareValuesWhtsp(attr->val, 25704 (xmlSchemaWhitespaceValueType) ws, 25705 attr->use->defVal, 25706 (xmlSchemaWhitespaceValueType) ws) != 0) { 25707 */ 25708 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25709 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25710 } else { 25711 if (iattr->decl->defVal == NULL) { 25712 /* VAL TODO: A default value was not precomputed. */ 25713 TODO 25714 goto eval_idcs; 25715 } 25716 iattr->vcValue = iattr->decl->defValue; 25717 /* 25718 if (xmlSchemaCompareValuesWhtsp(attr->val, 25719 (xmlSchemaWhitespaceValueType) ws, 25720 attrDecl->defVal, 25721 (xmlSchemaWhitespaceValueType) ws) != 0) { 25722 */ 25723 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25724 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25725 } 25726 /* 25727 * [validity] = "valid" 25728 */ 25729 } 25730 eval_idcs: 25731 /* 25732 * Evaluate IDCs. 25733 */ 25734 if (xpathRes) { 25735 if (xmlSchemaXPathProcessHistory(vctxt, 25736 vctxt->depth +1) == -1) { 25737 VERROR_INT("xmlSchemaVAttributesComplex", 25738 "calling xmlSchemaXPathEvaluate()"); 25739 goto internal_error; 25740 } 25741 } else if (vctxt->xpathStates != NULL) 25742 xmlSchemaXPathPop(vctxt); 25743 } 25744 25745 /* 25746 * Report errors. 25747 */ 25748 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25749 iattr = vctxt->attrInfos[i]; 25750 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25751 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25752 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25753 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25754 continue; 25755 ACTIVATE_ATTRIBUTE(iattr); 25756 switch (iattr->state) { 25757 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25758 xmlChar *str = NULL; 25759 ACTIVATE_ELEM; 25760 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25761 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25762 "The attribute '%s' is required but missing", 25763 xmlSchemaFormatQName(&str, 25764 iattr->decl->targetNamespace, 25765 iattr->decl->name), 25766 NULL); 25767 FREE_AND_NULL(str) 25768 break; 25769 } 25770 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25771 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25772 "The type definition is absent"); 25773 break; 25774 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25775 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25776 XML_SCHEMAV_CVC_AU, NULL, NULL, 25777 "The value '%s' does not match the fixed " 25778 "value constraint '%s'", 25779 iattr->value, iattr->vcValue); 25780 break; 25781 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25782 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25783 "No matching global attribute declaration available, but " 25784 "demanded by the strict wildcard"); 25785 break; 25786 case XML_SCHEMAS_ATTR_UNKNOWN: 25787 if (iattr->metaType) 25788 break; 25789 /* 25790 * MAYBE VAL TODO: One might report different error messages 25791 * for the following errors. 25792 */ 25793 if (type->attributeWildcard == NULL) { 25794 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25795 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25796 } else { 25797 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25798 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25799 } 25800 break; 25801 default: 25802 break; 25803 } 25804 } 25805 25806 ACTIVATE_ELEM; 25807 return (0); 25808 internal_error: 25809 ACTIVATE_ELEM; 25810 return (-1); 25811 } 25812 25813 static int 25814 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25815 int *skip) 25816 { 25817 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25818 /* 25819 * The namespace of the element was already identified to be 25820 * matching the wildcard. 25821 */ 25822 if ((skip == NULL) || (wild == NULL) || 25823 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25824 VERROR_INT("xmlSchemaValidateElemWildcard", 25825 "bad arguments"); 25826 return (-1); 25827 } 25828 *skip = 0; 25829 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25830 /* 25831 * URGENT VAL TODO: Either we need to position the stream to the 25832 * next sibling, or walk the whole subtree. 25833 */ 25834 *skip = 1; 25835 return (0); 25836 } 25837 { 25838 xmlSchemaElementPtr decl = NULL; 25839 25840 decl = xmlSchemaGetElem(vctxt->schema, 25841 vctxt->inode->localName, vctxt->inode->nsName); 25842 if (decl != NULL) { 25843 vctxt->inode->decl = decl; 25844 return (0); 25845 } 25846 } 25847 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25848 /* VAL TODO: Change to proper error code. */ 25849 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25850 "No matching global element declaration available, but " 25851 "demanded by the strict wildcard"); 25852 return (vctxt->err); 25853 } 25854 if (vctxt->nbAttrInfos != 0) { 25855 xmlSchemaAttrInfoPtr iattr; 25856 /* 25857 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25858 * (1.2.1.2.1) - (1.2.1.2.3 ) 25859 * 25860 * Use the xsi:type attribute for the type definition. 25861 */ 25862 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25863 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25864 if (iattr != NULL) { 25865 if (xmlSchemaProcessXSIType(vctxt, iattr, 25866 &(vctxt->inode->typeDef), NULL) == -1) { 25867 VERROR_INT("xmlSchemaValidateElemWildcard", 25868 "calling xmlSchemaProcessXSIType() to " 25869 "process the attribute 'xsi:nil'"); 25870 return (-1); 25871 } 25872 /* 25873 * Don't return an error on purpose. 25874 */ 25875 return (0); 25876 } 25877 } 25878 /* 25879 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25880 * 25881 * Fallback to "anyType". 25882 */ 25883 vctxt->inode->typeDef = 25884 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25885 return (0); 25886 } 25887 25888 /* 25889 * xmlSchemaCheckCOSValidDefault: 25890 * 25891 * This will be called if: not nilled, no content and a default/fixed 25892 * value is provided. 25893 */ 25894 25895 static int 25896 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25897 const xmlChar *value, 25898 xmlSchemaValPtr *val) 25899 { 25900 int ret = 0; 25901 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25902 25903 /* 25904 * cos-valid-default: 25905 * Schema Component Constraint: Element Default Valid (Immediate) 25906 * For a string to be a valid default with respect to a type 25907 * definition the appropriate case among the following must be true: 25908 */ 25909 if WXS_IS_COMPLEX(inode->typeDef) { 25910 /* 25911 * Complex type. 25912 * 25913 * SPEC (2.1) "its {content type} must be a simple type definition 25914 * or mixed." 25915 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25916 * type}'s particle must be `emptiable` as defined by 25917 * Particle Emptiable ($3.9.6)." 25918 */ 25919 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25920 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25921 (! WXS_EMPTIABLE(inode->typeDef)))) { 25922 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25923 /* NOTE that this covers (2.2.2) as well. */ 25924 VERROR(ret, NULL, 25925 "For a string to be a valid default, the type definition " 25926 "must be a simple type or a complex type with simple content " 25927 "or mixed content and a particle emptiable"); 25928 return(ret); 25929 } 25930 } 25931 /* 25932 * 1 If the type definition is a simple type definition, then the string 25933 * must be `valid` with respect to that definition as defined by String 25934 * Valid ($3.14.4). 25935 * 25936 * AND 25937 * 25938 * 2.2.1 If the {content type} is a simple type definition, then the 25939 * string must be `valid` with respect to that simple type definition 25940 * as defined by String Valid ($3.14.4). 25941 */ 25942 if (WXS_IS_SIMPLE(inode->typeDef)) { 25943 25944 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25945 NULL, inode->typeDef, value, val, 1, 1, 0); 25946 25947 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25948 25949 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25950 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25951 } 25952 if (ret < 0) { 25953 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25954 "calling xmlSchemaVCheckCVCSimpleType()"); 25955 } 25956 return (ret); 25957 } 25958 25959 static void 25960 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 25961 const xmlChar * name ATTRIBUTE_UNUSED, 25962 xmlSchemaElementPtr item, 25963 xmlSchemaNodeInfoPtr inode) 25964 { 25965 inode->decl = item; 25966 #ifdef DEBUG_CONTENT 25967 { 25968 xmlChar *str = NULL; 25969 25970 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25971 xmlGenericError(xmlGenericErrorContext, 25972 "AUTOMATON callback for '%s' [declaration]\n", 25973 xmlSchemaFormatQName(&str, 25974 inode->localName, inode->nsName)); 25975 } else { 25976 xmlGenericError(xmlGenericErrorContext, 25977 "AUTOMATON callback for '%s' [wildcard]\n", 25978 xmlSchemaFormatQName(&str, 25979 inode->localName, inode->nsName)); 25980 25981 } 25982 FREE_AND_NULL(str) 25983 } 25984 #endif 25985 } 25986 25987 static int 25988 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 25989 { 25990 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 25991 if (vctxt->inode == NULL) { 25992 VERROR_INT("xmlSchemaValidatorPushElem", 25993 "calling xmlSchemaGetFreshElemInfo()"); 25994 return (-1); 25995 } 25996 vctxt->nbAttrInfos = 0; 25997 return (0); 25998 } 25999 26000 static int 26001 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 26002 xmlSchemaNodeInfoPtr inode, 26003 xmlSchemaTypePtr type, 26004 const xmlChar *value) 26005 { 26006 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 26007 return (xmlSchemaVCheckCVCSimpleType( 26008 ACTXT_CAST vctxt, NULL, 26009 type, value, &(inode->val), 1, 1, 0)); 26010 else 26011 return (xmlSchemaVCheckCVCSimpleType( 26012 ACTXT_CAST vctxt, NULL, 26013 type, value, NULL, 1, 0, 0)); 26014 } 26015 26016 26017 26018 /* 26019 * Process END of element. 26020 */ 26021 static int 26022 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 26023 { 26024 int ret = 0; 26025 xmlSchemaNodeInfoPtr inode = vctxt->inode; 26026 26027 if (vctxt->nbAttrInfos != 0) 26028 xmlSchemaClearAttrInfos(vctxt); 26029 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 26030 /* 26031 * This element was not expected; 26032 * we will not validate child elements of broken parents. 26033 * Skip validation of all content of the parent. 26034 */ 26035 vctxt->skipDepth = vctxt->depth -1; 26036 goto end_elem; 26037 } 26038 if ((inode->typeDef == NULL) || 26039 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 26040 /* 26041 * 1. the type definition might be missing if the element was 26042 * error prone 26043 * 2. it might be abstract. 26044 */ 26045 goto end_elem; 26046 } 26047 /* 26048 * Check the content model. 26049 */ 26050 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26051 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26052 26053 /* 26054 * Workaround for "anyType". 26055 */ 26056 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26057 goto character_content; 26058 26059 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26060 xmlChar *values[10]; 26061 int terminal, nbval = 10, nbneg; 26062 26063 if (inode->regexCtxt == NULL) { 26064 /* 26065 * Create the regex context. 26066 */ 26067 inode->regexCtxt = 26068 xmlRegNewExecCtxt(inode->typeDef->contModel, 26069 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26070 vctxt); 26071 if (inode->regexCtxt == NULL) { 26072 VERROR_INT("xmlSchemaValidatorPopElem", 26073 "failed to create a regex context"); 26074 goto internal_error; 26075 } 26076 #ifdef DEBUG_AUTOMATA 26077 xmlGenericError(xmlGenericErrorContext, 26078 "AUTOMATON create on '%s'\n", inode->localName); 26079 #endif 26080 } 26081 26082 /* 26083 * Do not check further content if the node has been nilled 26084 */ 26085 if (INODE_NILLED(inode)) { 26086 ret = 0; 26087 #ifdef DEBUG_AUTOMATA 26088 xmlGenericError(xmlGenericErrorContext, 26089 "AUTOMATON succeeded on nilled '%s'\n", 26090 inode->localName); 26091 #endif 26092 goto skip_nilled; 26093 } 26094 26095 /* 26096 * Get hold of the still expected content, since a further 26097 * call to xmlRegExecPushString() will loose this information. 26098 */ 26099 xmlRegExecNextValues(inode->regexCtxt, 26100 &nbval, &nbneg, &values[0], &terminal); 26101 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26102 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26103 /* 26104 * Still missing something. 26105 */ 26106 ret = 1; 26107 inode->flags |= 26108 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26109 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26110 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26111 "Missing child element(s)", 26112 nbval, nbneg, values); 26113 #ifdef DEBUG_AUTOMATA 26114 xmlGenericError(xmlGenericErrorContext, 26115 "AUTOMATON missing ERROR on '%s'\n", 26116 inode->localName); 26117 #endif 26118 } else { 26119 /* 26120 * Content model is satisfied. 26121 */ 26122 ret = 0; 26123 #ifdef DEBUG_AUTOMATA 26124 xmlGenericError(xmlGenericErrorContext, 26125 "AUTOMATON succeeded on '%s'\n", 26126 inode->localName); 26127 #endif 26128 } 26129 26130 } 26131 } 26132 26133 skip_nilled: 26134 26135 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26136 goto end_elem; 26137 26138 character_content: 26139 26140 if (vctxt->value != NULL) { 26141 xmlSchemaFreeValue(vctxt->value); 26142 vctxt->value = NULL; 26143 } 26144 /* 26145 * Check character content. 26146 */ 26147 if (inode->decl == NULL) { 26148 /* 26149 * Speedup if no declaration exists. 26150 */ 26151 if (WXS_IS_SIMPLE(inode->typeDef)) { 26152 ret = xmlSchemaVCheckINodeDataType(vctxt, 26153 inode, inode->typeDef, inode->value); 26154 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26155 ret = xmlSchemaVCheckINodeDataType(vctxt, 26156 inode, inode->typeDef->contentTypeDef, 26157 inode->value); 26158 } 26159 if (ret < 0) { 26160 VERROR_INT("xmlSchemaValidatorPopElem", 26161 "calling xmlSchemaVCheckCVCSimpleType()"); 26162 goto internal_error; 26163 } 26164 goto end_elem; 26165 } 26166 /* 26167 * cvc-elt (3.3.4) : 5 26168 * The appropriate case among the following must be true: 26169 */ 26170 /* 26171 * cvc-elt (3.3.4) : 5.1 26172 * If the declaration has a {value constraint}, 26173 * the item has neither element nor character [children] and 26174 * clause 3.2 has not applied, then all of the following must be true: 26175 */ 26176 if ((inode->decl->value != NULL) && 26177 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26178 (! INODE_NILLED(inode))) { 26179 /* 26180 * cvc-elt (3.3.4) : 5.1.1 26181 * If the `actual type definition` is a `local type definition` 26182 * then the canonical lexical representation of the {value constraint} 26183 * value must be a valid default for the `actual type definition` as 26184 * defined in Element Default Valid (Immediate) ($3.3.6). 26185 */ 26186 /* 26187 * NOTE: 'local' above means types acquired by xsi:type. 26188 * NOTE: Although the *canonical* value is stated, it is not 26189 * relevant if canonical or not. Additionally XML Schema 1.1 26190 * will removed this requirement as well. 26191 */ 26192 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26193 26194 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26195 inode->decl->value, &(inode->val)); 26196 if (ret != 0) { 26197 if (ret < 0) { 26198 VERROR_INT("xmlSchemaValidatorPopElem", 26199 "calling xmlSchemaCheckCOSValidDefault()"); 26200 goto internal_error; 26201 } 26202 goto end_elem; 26203 } 26204 /* 26205 * Stop here, to avoid redundant validation of the value 26206 * (see following). 26207 */ 26208 goto default_psvi; 26209 } 26210 /* 26211 * cvc-elt (3.3.4) : 5.1.2 26212 * The element information item with the canonical lexical 26213 * representation of the {value constraint} value used as its 26214 * `normalized value` must be `valid` with respect to the 26215 * `actual type definition` as defined by Element Locally Valid (Type) 26216 * ($3.3.4). 26217 */ 26218 if (WXS_IS_SIMPLE(inode->typeDef)) { 26219 ret = xmlSchemaVCheckINodeDataType(vctxt, 26220 inode, inode->typeDef, inode->decl->value); 26221 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26222 ret = xmlSchemaVCheckINodeDataType(vctxt, 26223 inode, inode->typeDef->contentTypeDef, 26224 inode->decl->value); 26225 } 26226 if (ret != 0) { 26227 if (ret < 0) { 26228 VERROR_INT("xmlSchemaValidatorPopElem", 26229 "calling xmlSchemaVCheckCVCSimpleType()"); 26230 goto internal_error; 26231 } 26232 goto end_elem; 26233 } 26234 26235 default_psvi: 26236 /* 26237 * PSVI: Create a text node on the instance element. 26238 */ 26239 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26240 (inode->node != NULL)) { 26241 xmlNodePtr textChild; 26242 xmlChar *normValue; 26243 /* 26244 * VAL TODO: Normalize the value. 26245 */ 26246 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26247 inode->decl->value); 26248 if (normValue != NULL) { 26249 textChild = xmlNewText(BAD_CAST normValue); 26250 xmlFree(normValue); 26251 } else 26252 textChild = xmlNewText(inode->decl->value); 26253 if (textChild == NULL) { 26254 VERROR_INT("xmlSchemaValidatorPopElem", 26255 "calling xmlNewText()"); 26256 goto internal_error; 26257 } else 26258 xmlAddChild(inode->node, textChild); 26259 } 26260 26261 } else if (! INODE_NILLED(inode)) { 26262 /* 26263 * 5.2.1 The element information item must be `valid` with respect 26264 * to the `actual type definition` as defined by Element Locally 26265 * Valid (Type) ($3.3.4). 26266 */ 26267 if (WXS_IS_SIMPLE(inode->typeDef)) { 26268 /* 26269 * SPEC (cvc-type) (3.1) 26270 * "If the type definition is a simple type definition, ..." 26271 * (3.1.3) "If clause 3.2 of Element Locally Valid 26272 * (Element) ($3.3.4) did not apply, then the `normalized value` 26273 * must be `valid` with respect to the type definition as defined 26274 * by String Valid ($3.14.4). 26275 */ 26276 ret = xmlSchemaVCheckINodeDataType(vctxt, 26277 inode, inode->typeDef, inode->value); 26278 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26279 /* 26280 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26281 * definition, then the element information item must be 26282 * `valid` with respect to the type definition as per 26283 * Element Locally Valid (Complex Type) ($3.4.4);" 26284 * 26285 * SPEC (cvc-complex-type) (2.2) 26286 * "If the {content type} is a simple type definition, ... 26287 * the `normalized value` of the element information item is 26288 * `valid` with respect to that simple type definition as 26289 * defined by String Valid ($3.14.4)." 26290 */ 26291 ret = xmlSchemaVCheckINodeDataType(vctxt, 26292 inode, inode->typeDef->contentTypeDef, inode->value); 26293 } 26294 if (ret != 0) { 26295 if (ret < 0) { 26296 VERROR_INT("xmlSchemaValidatorPopElem", 26297 "calling xmlSchemaVCheckCVCSimpleType()"); 26298 goto internal_error; 26299 } 26300 goto end_elem; 26301 } 26302 /* 26303 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26304 * not applied, all of the following must be true: 26305 */ 26306 if ((inode->decl->value != NULL) && 26307 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26308 26309 /* 26310 * TODO: We will need a computed value, when comparison is 26311 * done on computed values. 26312 */ 26313 /* 26314 * 5.2.2.1 The element information item must have no element 26315 * information item [children]. 26316 */ 26317 if (inode->flags & 26318 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26319 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26320 VERROR(ret, NULL, 26321 "The content must not containt element nodes since " 26322 "there is a fixed value constraint"); 26323 goto end_elem; 26324 } else { 26325 /* 26326 * 5.2.2.2 The appropriate case among the following must 26327 * be true: 26328 */ 26329 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26330 /* 26331 * 5.2.2.2.1 If the {content type} of the `actual type 26332 * definition` is mixed, then the *initial value* of the 26333 * item must match the canonical lexical representation 26334 * of the {value constraint} value. 26335 * 26336 * ... the *initial value* of an element information 26337 * item is the string composed of, in order, the 26338 * [character code] of each character information item in 26339 * the [children] of that element information item. 26340 */ 26341 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26342 /* 26343 * VAL TODO: Report invalid & expected values as well. 26344 * VAL TODO: Implement the canonical stuff. 26345 */ 26346 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26347 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26348 ret, NULL, NULL, 26349 "The initial value '%s' does not match the fixed " 26350 "value constraint '%s'", 26351 inode->value, inode->decl->value); 26352 goto end_elem; 26353 } 26354 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26355 /* 26356 * 5.2.2.2.2 If the {content type} of the `actual type 26357 * definition` is a simple type definition, then the 26358 * *actual value* of the item must match the canonical 26359 * lexical representation of the {value constraint} value. 26360 */ 26361 /* 26362 * VAL TODO: *actual value* is the normalized value, impl. 26363 * this. 26364 * VAL TODO: Report invalid & expected values as well. 26365 * VAL TODO: Implement a comparison with the computed values. 26366 */ 26367 if (! xmlStrEqual(inode->value, 26368 inode->decl->value)) { 26369 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26370 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26371 ret, NULL, NULL, 26372 "The actual value '%s' does not match the fixed " 26373 "value constraint '%s'", 26374 inode->value, 26375 inode->decl->value); 26376 goto end_elem; 26377 } 26378 } 26379 } 26380 } 26381 } 26382 26383 end_elem: 26384 if (vctxt->depth < 0) { 26385 /* TODO: raise error? */ 26386 return (0); 26387 } 26388 if (vctxt->depth == vctxt->skipDepth) 26389 vctxt->skipDepth = -1; 26390 /* 26391 * Evaluate the history of XPath state objects. 26392 */ 26393 if (inode->appliedXPath && 26394 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26395 goto internal_error; 26396 /* 26397 * MAYBE TODO: 26398 * SPEC (6) "The element information item must be `valid` with 26399 * respect to each of the {identity-constraint definitions} as per 26400 * Identity-constraint Satisfied ($3.11.4)." 26401 */ 26402 /* 26403 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26404 * need to be built in any case. 26405 * We will currently build IDC node-tables and bubble them only if 26406 * keyrefs do exist. 26407 */ 26408 26409 /* 26410 * Add the current IDC target-nodes to the IDC node-tables. 26411 */ 26412 if ((inode->idcMatchers != NULL) && 26413 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26414 { 26415 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26416 goto internal_error; 26417 } 26418 /* 26419 * Validate IDC keyrefs. 26420 */ 26421 if (vctxt->inode->hasKeyrefs) 26422 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26423 goto internal_error; 26424 /* 26425 * Merge/free the IDC table. 26426 */ 26427 if (inode->idcTable != NULL) { 26428 #ifdef DEBUG_IDC_NODE_TABLE 26429 xmlSchemaDebugDumpIDCTable(stdout, 26430 inode->nsName, 26431 inode->localName, 26432 inode->idcTable); 26433 #endif 26434 if ((vctxt->depth > 0) && 26435 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26436 { 26437 /* 26438 * Merge the IDC node table with the table of the parent node. 26439 */ 26440 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26441 goto internal_error; 26442 } 26443 } 26444 /* 26445 * Clear the current ielem. 26446 * VAL TODO: Don't free the PSVI IDC tables if they are 26447 * requested for the PSVI. 26448 */ 26449 xmlSchemaClearElemInfo(vctxt, inode); 26450 /* 26451 * Skip further processing if we are on the validation root. 26452 */ 26453 if (vctxt->depth == 0) { 26454 vctxt->depth--; 26455 vctxt->inode = NULL; 26456 return (0); 26457 } 26458 /* 26459 * Reset the keyrefDepth if needed. 26460 */ 26461 if (vctxt->aidcs != NULL) { 26462 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26463 do { 26464 if (aidc->keyrefDepth == vctxt->depth) { 26465 /* 26466 * A 'keyrefDepth' of a key/unique IDC matches the current 26467 * depth, this means that we are leaving the scope of the 26468 * top-most keyref IDC which refers to this IDC. 26469 */ 26470 aidc->keyrefDepth = -1; 26471 } 26472 aidc = aidc->next; 26473 } while (aidc != NULL); 26474 } 26475 vctxt->depth--; 26476 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26477 /* 26478 * VAL TODO: 7 If the element information item is the `validation root`, it must be 26479 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4). 26480 */ 26481 return (ret); 26482 26483 internal_error: 26484 vctxt->err = -1; 26485 return (-1); 26486 } 26487 26488 /* 26489 * 3.4.4 Complex Type Definition Validation Rules 26490 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26491 */ 26492 static int 26493 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26494 { 26495 xmlSchemaNodeInfoPtr pielem; 26496 xmlSchemaTypePtr ptype; 26497 int ret = 0; 26498 26499 if (vctxt->depth <= 0) { 26500 VERROR_INT("xmlSchemaValidateChildElem", 26501 "not intended for the validation root"); 26502 return (-1); 26503 } 26504 pielem = vctxt->elemInfos[vctxt->depth -1]; 26505 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26506 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26507 /* 26508 * Handle 'nilled' elements. 26509 */ 26510 if (INODE_NILLED(pielem)) { 26511 /* 26512 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26513 */ 26514 ACTIVATE_PARENT_ELEM; 26515 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26516 VERROR(ret, NULL, 26517 "Neither character nor element content is allowed, " 26518 "because the element was 'nilled'"); 26519 ACTIVATE_ELEM; 26520 goto unexpected_elem; 26521 } 26522 26523 ptype = pielem->typeDef; 26524 26525 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26526 /* 26527 * Workaround for "anyType": we have currently no content model 26528 * assigned for "anyType", so handle it explicitely. 26529 * "anyType" has an unbounded, lax "any" wildcard. 26530 */ 26531 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26532 vctxt->inode->localName, 26533 vctxt->inode->nsName); 26534 26535 if (vctxt->inode->decl == NULL) { 26536 xmlSchemaAttrInfoPtr iattr; 26537 /* 26538 * Process "xsi:type". 26539 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26540 */ 26541 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26542 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26543 if (iattr != NULL) { 26544 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26545 &(vctxt->inode->typeDef), NULL); 26546 if (ret != 0) { 26547 if (ret == -1) { 26548 VERROR_INT("xmlSchemaValidateChildElem", 26549 "calling xmlSchemaProcessXSIType() to " 26550 "process the attribute 'xsi:nil'"); 26551 return (-1); 26552 } 26553 return (ret); 26554 } 26555 } else { 26556 /* 26557 * Fallback to "anyType". 26558 * 26559 * SPEC (cvc-assess-elt) 26560 * "If the item cannot be `strictly assessed`, [...] 26561 * an element information item's schema validity may be laxly 26562 * assessed if its `context-determined declaration` is not 26563 * skip by `validating` with respect to the `ur-type 26564 * definition` as per Element Locally Valid (Type) ($3.3.4)." 26565 */ 26566 vctxt->inode->typeDef = 26567 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26568 } 26569 } 26570 return (0); 26571 } 26572 26573 switch (ptype->contentType) { 26574 case XML_SCHEMA_CONTENT_EMPTY: 26575 /* 26576 * SPEC (2.1) "If the {content type} is empty, then the 26577 * element information item has no character or element 26578 * information item [children]." 26579 */ 26580 ACTIVATE_PARENT_ELEM 26581 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26582 VERROR(ret, NULL, 26583 "Element content is not allowed, " 26584 "because the content type is empty"); 26585 ACTIVATE_ELEM 26586 goto unexpected_elem; 26587 break; 26588 26589 case XML_SCHEMA_CONTENT_MIXED: 26590 case XML_SCHEMA_CONTENT_ELEMENTS: { 26591 xmlRegExecCtxtPtr regexCtxt; 26592 xmlChar *values[10]; 26593 int terminal, nbval = 10, nbneg; 26594 26595 /* VAL TODO: Optimized "anyType" validation.*/ 26596 26597 if (ptype->contModel == NULL) { 26598 VERROR_INT("xmlSchemaValidateChildElem", 26599 "type has elem content but no content model"); 26600 return (-1); 26601 } 26602 /* 26603 * Safety belf for evaluation if the cont. model was already 26604 * examined to be invalid. 26605 */ 26606 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26607 VERROR_INT("xmlSchemaValidateChildElem", 26608 "validating elem, but elem content is already invalid"); 26609 return (-1); 26610 } 26611 26612 regexCtxt = pielem->regexCtxt; 26613 if (regexCtxt == NULL) { 26614 /* 26615 * Create the regex context. 26616 */ 26617 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26618 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26619 vctxt); 26620 if (regexCtxt == NULL) { 26621 VERROR_INT("xmlSchemaValidateChildElem", 26622 "failed to create a regex context"); 26623 return (-1); 26624 } 26625 pielem->regexCtxt = regexCtxt; 26626 #ifdef DEBUG_AUTOMATA 26627 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26628 pielem->localName); 26629 #endif 26630 } 26631 26632 /* 26633 * SPEC (2.4) "If the {content type} is element-only or mixed, 26634 * then the sequence of the element information item's 26635 * element information item [children], if any, taken in 26636 * order, is `valid` with respect to the {content type}'s 26637 * particle, as defined in Element Sequence Locally Valid 26638 * (Particle) ($3.9.4)." 26639 */ 26640 ret = xmlRegExecPushString2(regexCtxt, 26641 vctxt->inode->localName, 26642 vctxt->inode->nsName, 26643 vctxt->inode); 26644 #ifdef DEBUG_AUTOMATA 26645 if (ret < 0) 26646 xmlGenericError(xmlGenericErrorContext, 26647 "AUTOMATON push ERROR for '%s' on '%s'\n", 26648 vctxt->inode->localName, pielem->localName); 26649 else 26650 xmlGenericError(xmlGenericErrorContext, 26651 "AUTOMATON push OK for '%s' on '%s'\n", 26652 vctxt->inode->localName, pielem->localName); 26653 #endif 26654 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26655 VERROR_INT("xmlSchemaValidateChildElem", 26656 "calling xmlRegExecPushString2()"); 26657 return (-1); 26658 } 26659 if (ret < 0) { 26660 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26661 &values[0], &terminal); 26662 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26663 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26664 "This element is not expected", 26665 nbval, nbneg, values); 26666 ret = vctxt->err; 26667 goto unexpected_elem; 26668 } else 26669 ret = 0; 26670 } 26671 break; 26672 case XML_SCHEMA_CONTENT_SIMPLE: 26673 case XML_SCHEMA_CONTENT_BASIC: 26674 ACTIVATE_PARENT_ELEM 26675 if (WXS_IS_COMPLEX(ptype)) { 26676 /* 26677 * SPEC (cvc-complex-type) (2.2) 26678 * "If the {content type} is a simple type definition, then 26679 * the element information item has no element information 26680 * item [children], ..." 26681 */ 26682 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26683 VERROR(ret, NULL, "Element content is not allowed, " 26684 "because the content type is a simple type definition"); 26685 } else { 26686 /* 26687 * SPEC (cvc-type) (3.1.2) "The element information item must 26688 * have no element information item [children]." 26689 */ 26690 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26691 VERROR(ret, NULL, "Element content is not allowed, " 26692 "because the type definition is simple"); 26693 } 26694 ACTIVATE_ELEM 26695 ret = vctxt->err; 26696 goto unexpected_elem; 26697 break; 26698 26699 default: 26700 break; 26701 } 26702 return (ret); 26703 unexpected_elem: 26704 /* 26705 * Pop this element and set the skipDepth to skip 26706 * all further content of the parent element. 26707 */ 26708 vctxt->skipDepth = vctxt->depth; 26709 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26710 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26711 return (ret); 26712 } 26713 26714 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26715 #define XML_SCHEMA_PUSH_TEXT_CREATED 2 26716 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26717 26718 static int 26719 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26720 int nodeType, const xmlChar *value, int len, 26721 int mode, int *consumed) 26722 { 26723 /* 26724 * Unfortunately we have to duplicate the text sometimes. 26725 * OPTIMIZE: Maybe we could skip it, if: 26726 * 1. content type is simple 26727 * 2. whitespace is "collapse" 26728 * 3. it consists of whitespace only 26729 * 26730 * Process character content. 26731 */ 26732 if (consumed != NULL) 26733 *consumed = 0; 26734 if (INODE_NILLED(vctxt->inode)) { 26735 /* 26736 * SPEC cvc-elt (3.3.4 - 3.2.1) 26737 * "The element information item must have no character or 26738 * element information item [children]." 26739 */ 26740 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26741 "Neither character nor element content is allowed " 26742 "because the element is 'nilled'"); 26743 return (vctxt->err); 26744 } 26745 /* 26746 * SPEC (2.1) "If the {content type} is empty, then the 26747 * element information item has no character or element 26748 * information item [children]." 26749 */ 26750 if (vctxt->inode->typeDef->contentType == 26751 XML_SCHEMA_CONTENT_EMPTY) { 26752 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26753 "Character content is not allowed, " 26754 "because the content type is empty"); 26755 return (vctxt->err); 26756 } 26757 26758 if (vctxt->inode->typeDef->contentType == 26759 XML_SCHEMA_CONTENT_ELEMENTS) { 26760 if ((nodeType != XML_TEXT_NODE) || 26761 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26762 /* 26763 * SPEC cvc-complex-type (2.3) 26764 * "If the {content type} is element-only, then the 26765 * element information item has no character information 26766 * item [children] other than those whose [character 26767 * code] is defined as a white space in [XML 1.0 (Second 26768 * Edition)]." 26769 */ 26770 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26771 "Character content other than whitespace is not allowed " 26772 "because the content type is 'element-only'"); 26773 return (vctxt->err); 26774 } 26775 return (0); 26776 } 26777 26778 if ((value == NULL) || (value[0] == 0)) 26779 return (0); 26780 /* 26781 * Save the value. 26782 * NOTE that even if the content type is *mixed*, we need the 26783 * *initial value* for default/fixed value constraints. 26784 */ 26785 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26786 ((vctxt->inode->decl == NULL) || 26787 (vctxt->inode->decl->value == NULL))) 26788 return (0); 26789 26790 if (vctxt->inode->value == NULL) { 26791 /* 26792 * Set the value. 26793 */ 26794 switch (mode) { 26795 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26796 /* 26797 * When working on a tree. 26798 */ 26799 vctxt->inode->value = value; 26800 break; 26801 case XML_SCHEMA_PUSH_TEXT_CREATED: 26802 /* 26803 * When working with the reader. 26804 * The value will be freed by the element info. 26805 */ 26806 vctxt->inode->value = value; 26807 if (consumed != NULL) 26808 *consumed = 1; 26809 vctxt->inode->flags |= 26810 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26811 break; 26812 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26813 /* 26814 * When working with SAX. 26815 * The value will be freed by the element info. 26816 */ 26817 if (len != -1) 26818 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26819 else 26820 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26821 vctxt->inode->flags |= 26822 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26823 break; 26824 default: 26825 break; 26826 } 26827 } else { 26828 if (len < 0) 26829 len = xmlStrlen(value); 26830 /* 26831 * Concat the value. 26832 */ 26833 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26834 vctxt->inode->value = BAD_CAST xmlStrncat( 26835 (xmlChar *) vctxt->inode->value, value, len); 26836 } else { 26837 vctxt->inode->value = 26838 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26839 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26840 } 26841 } 26842 26843 return (0); 26844 } 26845 26846 static int 26847 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26848 { 26849 int ret = 0; 26850 26851 if ((vctxt->skipDepth != -1) && 26852 (vctxt->depth >= vctxt->skipDepth)) { 26853 VERROR_INT("xmlSchemaValidateElem", 26854 "in skip-state"); 26855 goto internal_error; 26856 } 26857 if (vctxt->xsiAssemble) { 26858 /* 26859 * We will stop validation if there was an error during 26860 * dynamic schema construction. 26861 * Note that we simply set @skipDepth to 0, this could 26862 * mean that a streaming document via SAX would be 26863 * still read to the end but it won't be validated any more. 26864 * TODO: If we are sure how to stop the validation at once 26865 * for all input scenarios, then this should be changed to 26866 * instantly stop the validation. 26867 */ 26868 ret = xmlSchemaAssembleByXSI(vctxt); 26869 if (ret != 0) { 26870 if (ret == -1) 26871 goto internal_error; 26872 vctxt->skipDepth = 0; 26873 return(ret); 26874 } 26875 /* 26876 * Augment the IDC definitions for the main schema and all imported ones 26877 * NOTE: main schema is the first in the imported list 26878 */ 26879 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 26880 } 26881 if (vctxt->depth > 0) { 26882 /* 26883 * Validate this element against the content model 26884 * of the parent. 26885 */ 26886 ret = xmlSchemaValidateChildElem(vctxt); 26887 if (ret != 0) { 26888 if (ret < 0) { 26889 VERROR_INT("xmlSchemaValidateElem", 26890 "calling xmlSchemaStreamValidateChildElement()"); 26891 goto internal_error; 26892 } 26893 goto exit; 26894 } 26895 if (vctxt->depth == vctxt->skipDepth) 26896 goto exit; 26897 if ((vctxt->inode->decl == NULL) && 26898 (vctxt->inode->typeDef == NULL)) { 26899 VERROR_INT("xmlSchemaValidateElem", 26900 "the child element was valid but neither the " 26901 "declaration nor the type was set"); 26902 goto internal_error; 26903 } 26904 } else { 26905 /* 26906 * Get the declaration of the validation root. 26907 */ 26908 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26909 vctxt->inode->localName, 26910 vctxt->inode->nsName); 26911 if (vctxt->inode->decl == NULL) { 26912 ret = XML_SCHEMAV_CVC_ELT_1; 26913 VERROR(ret, NULL, 26914 "No matching global declaration available " 26915 "for the validation root"); 26916 goto exit; 26917 } 26918 } 26919 26920 if (vctxt->inode->decl == NULL) 26921 goto type_validation; 26922 26923 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26924 int skip; 26925 /* 26926 * Wildcards. 26927 */ 26928 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26929 if (ret != 0) { 26930 if (ret < 0) { 26931 VERROR_INT("xmlSchemaValidateElem", 26932 "calling xmlSchemaValidateElemWildcard()"); 26933 goto internal_error; 26934 } 26935 goto exit; 26936 } 26937 if (skip) { 26938 vctxt->skipDepth = vctxt->depth; 26939 goto exit; 26940 } 26941 /* 26942 * The declaration might be set by the wildcard validation, 26943 * when the processContents is "lax" or "strict". 26944 */ 26945 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26946 /* 26947 * Clear the "decl" field to not confuse further processing. 26948 */ 26949 vctxt->inode->decl = NULL; 26950 goto type_validation; 26951 } 26952 } 26953 /* 26954 * Validate against the declaration. 26955 */ 26956 ret = xmlSchemaValidateElemDecl(vctxt); 26957 if (ret != 0) { 26958 if (ret < 0) { 26959 VERROR_INT("xmlSchemaValidateElem", 26960 "calling xmlSchemaValidateElemDecl()"); 26961 goto internal_error; 26962 } 26963 goto exit; 26964 } 26965 /* 26966 * Validate against the type definition. 26967 */ 26968 type_validation: 26969 26970 if (vctxt->inode->typeDef == NULL) { 26971 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26972 ret = XML_SCHEMAV_CVC_TYPE_1; 26973 VERROR(ret, NULL, 26974 "The type definition is absent"); 26975 goto exit; 26976 } 26977 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26978 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26979 ret = XML_SCHEMAV_CVC_TYPE_2; 26980 VERROR(ret, NULL, 26981 "The type definition is abstract"); 26982 goto exit; 26983 } 26984 /* 26985 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26986 * during validation against the declaration. This must be done 26987 * _before_ attribute validation. 26988 */ 26989 if (vctxt->xpathStates != NULL) { 26990 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 26991 vctxt->inode->appliedXPath = 1; 26992 if (ret == -1) { 26993 VERROR_INT("xmlSchemaValidateElem", 26994 "calling xmlSchemaXPathEvaluate()"); 26995 goto internal_error; 26996 } 26997 } 26998 /* 26999 * Validate attributes. 27000 */ 27001 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 27002 if ((vctxt->nbAttrInfos != 0) || 27003 (vctxt->inode->typeDef->attrUses != NULL)) { 27004 27005 ret = xmlSchemaVAttributesComplex(vctxt); 27006 } 27007 } else if (vctxt->nbAttrInfos != 0) { 27008 27009 ret = xmlSchemaVAttributesSimple(vctxt); 27010 } 27011 /* 27012 * Clear registered attributes. 27013 */ 27014 if (vctxt->nbAttrInfos != 0) 27015 xmlSchemaClearAttrInfos(vctxt); 27016 if (ret == -1) { 27017 VERROR_INT("xmlSchemaValidateElem", 27018 "calling attributes validation"); 27019 goto internal_error; 27020 } 27021 /* 27022 * Don't return an error if attributes are invalid on purpose. 27023 */ 27024 ret = 0; 27025 27026 exit: 27027 if (ret != 0) 27028 vctxt->skipDepth = vctxt->depth; 27029 return (ret); 27030 internal_error: 27031 return (-1); 27032 } 27033 27034 #ifdef XML_SCHEMA_READER_ENABLED 27035 static int 27036 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 27037 { 27038 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 27039 int depth, nodeType, ret = 0, consumed; 27040 xmlSchemaNodeInfoPtr ielem; 27041 27042 vctxt->depth = -1; 27043 ret = xmlTextReaderRead(vctxt->reader); 27044 /* 27045 * Move to the document element. 27046 */ 27047 while (ret == 1) { 27048 nodeType = xmlTextReaderNodeType(vctxt->reader); 27049 if (nodeType == XML_ELEMENT_NODE) 27050 goto root_found; 27051 ret = xmlTextReaderRead(vctxt->reader); 27052 } 27053 goto exit; 27054 27055 root_found: 27056 27057 do { 27058 depth = xmlTextReaderDepth(vctxt->reader); 27059 nodeType = xmlTextReaderNodeType(vctxt->reader); 27060 27061 if (nodeType == XML_ELEMENT_NODE) { 27062 27063 vctxt->depth++; 27064 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27065 VERROR_INT("xmlSchemaVReaderWalk", 27066 "calling xmlSchemaValidatorPushElem()"); 27067 goto internal_error; 27068 } 27069 ielem = vctxt->inode; 27070 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27071 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27072 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27073 /* 27074 * Is the element empty? 27075 */ 27076 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27077 if (ret == -1) { 27078 VERROR_INT("xmlSchemaVReaderWalk", 27079 "calling xmlTextReaderIsEmptyElement()"); 27080 goto internal_error; 27081 } 27082 if (ret) { 27083 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27084 } 27085 /* 27086 * Register attributes. 27087 */ 27088 vctxt->nbAttrInfos = 0; 27089 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27090 if (ret == -1) { 27091 VERROR_INT("xmlSchemaVReaderWalk", 27092 "calling xmlTextReaderMoveToFirstAttribute()"); 27093 goto internal_error; 27094 } 27095 if (ret == 1) { 27096 do { 27097 /* 27098 * VAL TODO: How do we know that the reader works on a 27099 * node tree, to be able to pass a node here? 27100 */ 27101 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27102 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27103 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27104 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27105 27106 VERROR_INT("xmlSchemaVReaderWalk", 27107 "calling xmlSchemaValidatorPushAttribute()"); 27108 goto internal_error; 27109 } 27110 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27111 if (ret == -1) { 27112 VERROR_INT("xmlSchemaVReaderWalk", 27113 "calling xmlTextReaderMoveToFirstAttribute()"); 27114 goto internal_error; 27115 } 27116 } while (ret == 1); 27117 /* 27118 * Back to element position. 27119 */ 27120 ret = xmlTextReaderMoveToElement(vctxt->reader); 27121 if (ret == -1) { 27122 VERROR_INT("xmlSchemaVReaderWalk", 27123 "calling xmlTextReaderMoveToElement()"); 27124 goto internal_error; 27125 } 27126 } 27127 /* 27128 * Validate the element. 27129 */ 27130 ret= xmlSchemaValidateElem(vctxt); 27131 if (ret != 0) { 27132 if (ret == -1) { 27133 VERROR_INT("xmlSchemaVReaderWalk", 27134 "calling xmlSchemaValidateElem()"); 27135 goto internal_error; 27136 } 27137 goto exit; 27138 } 27139 if (vctxt->depth == vctxt->skipDepth) { 27140 int curDepth; 27141 /* 27142 * Skip all content. 27143 */ 27144 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27145 ret = xmlTextReaderRead(vctxt->reader); 27146 curDepth = xmlTextReaderDepth(vctxt->reader); 27147 while ((ret == 1) && (curDepth != depth)) { 27148 ret = xmlTextReaderRead(vctxt->reader); 27149 curDepth = xmlTextReaderDepth(vctxt->reader); 27150 } 27151 if (ret < 0) { 27152 /* 27153 * VAL TODO: A reader error occured; what to do here? 27154 */ 27155 ret = 1; 27156 goto exit; 27157 } 27158 } 27159 goto leave_elem; 27160 } 27161 /* 27162 * READER VAL TODO: Is an END_ELEM really never called 27163 * if the elem is empty? 27164 */ 27165 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27166 goto leave_elem; 27167 } else if (nodeType == END_ELEM) { 27168 /* 27169 * Process END of element. 27170 */ 27171 leave_elem: 27172 ret = xmlSchemaValidatorPopElem(vctxt); 27173 if (ret != 0) { 27174 if (ret < 0) { 27175 VERROR_INT("xmlSchemaVReaderWalk", 27176 "calling xmlSchemaValidatorPopElem()"); 27177 goto internal_error; 27178 } 27179 goto exit; 27180 } 27181 if (vctxt->depth >= 0) 27182 ielem = vctxt->inode; 27183 else 27184 ielem = NULL; 27185 } else if ((nodeType == XML_TEXT_NODE) || 27186 (nodeType == XML_CDATA_SECTION_NODE) || 27187 (nodeType == WHTSP) || 27188 (nodeType == SIGN_WHTSP)) { 27189 /* 27190 * Process character content. 27191 */ 27192 xmlChar *value; 27193 27194 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27195 nodeType = XML_TEXT_NODE; 27196 27197 value = xmlTextReaderValue(vctxt->reader); 27198 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27199 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27200 if (! consumed) 27201 xmlFree(value); 27202 if (ret == -1) { 27203 VERROR_INT("xmlSchemaVReaderWalk", 27204 "calling xmlSchemaVPushText()"); 27205 goto internal_error; 27206 } 27207 } else if ((nodeType == XML_ENTITY_NODE) || 27208 (nodeType == XML_ENTITY_REF_NODE)) { 27209 /* 27210 * VAL TODO: What to do with entities? 27211 */ 27212 TODO 27213 } 27214 /* 27215 * Read next node. 27216 */ 27217 ret = xmlTextReaderRead(vctxt->reader); 27218 } while (ret == 1); 27219 27220 exit: 27221 return (ret); 27222 internal_error: 27223 return (-1); 27224 } 27225 #endif 27226 27227 /************************************************************************ 27228 * * 27229 * SAX validation handlers * 27230 * * 27231 ************************************************************************/ 27232 27233 /* 27234 * Process text content. 27235 */ 27236 static void 27237 xmlSchemaSAXHandleText(void *ctx, 27238 const xmlChar * ch, 27239 int len) 27240 { 27241 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27242 27243 if (vctxt->depth < 0) 27244 return; 27245 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27246 return; 27247 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27248 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27249 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27250 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27251 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27252 "calling xmlSchemaVPushText()"); 27253 vctxt->err = -1; 27254 xmlStopParser(vctxt->parserCtxt); 27255 } 27256 } 27257 27258 /* 27259 * Process CDATA content. 27260 */ 27261 static void 27262 xmlSchemaSAXHandleCDataSection(void *ctx, 27263 const xmlChar * ch, 27264 int len) 27265 { 27266 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27267 27268 if (vctxt->depth < 0) 27269 return; 27270 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27271 return; 27272 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27273 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27274 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27275 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27276 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27277 "calling xmlSchemaVPushText()"); 27278 vctxt->err = -1; 27279 xmlStopParser(vctxt->parserCtxt); 27280 } 27281 } 27282 27283 static void 27284 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27285 const xmlChar * name ATTRIBUTE_UNUSED) 27286 { 27287 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27288 27289 if (vctxt->depth < 0) 27290 return; 27291 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27292 return; 27293 /* SAX VAL TODO: What to do here? */ 27294 TODO 27295 } 27296 27297 static void 27298 xmlSchemaSAXHandleStartElementNs(void *ctx, 27299 const xmlChar * localname, 27300 const xmlChar * prefix ATTRIBUTE_UNUSED, 27301 const xmlChar * URI, 27302 int nb_namespaces, 27303 const xmlChar ** namespaces, 27304 int nb_attributes, 27305 int nb_defaulted ATTRIBUTE_UNUSED, 27306 const xmlChar ** attributes) 27307 { 27308 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27309 int ret; 27310 xmlSchemaNodeInfoPtr ielem; 27311 int i, j; 27312 27313 /* 27314 * SAX VAL TODO: What to do with nb_defaulted? 27315 */ 27316 /* 27317 * Skip elements if inside a "skip" wildcard or invalid. 27318 */ 27319 vctxt->depth++; 27320 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27321 return; 27322 /* 27323 * Push the element. 27324 */ 27325 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27326 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27327 "calling xmlSchemaValidatorPushElem()"); 27328 goto internal_error; 27329 } 27330 ielem = vctxt->inode; 27331 /* 27332 * TODO: Is this OK? 27333 */ 27334 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27335 ielem->localName = localname; 27336 ielem->nsName = URI; 27337 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27338 /* 27339 * Register namespaces on the elem info. 27340 */ 27341 if (nb_namespaces != 0) { 27342 /* 27343 * Although the parser builds its own namespace list, 27344 * we have no access to it, so we'll use an own one. 27345 */ 27346 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27347 /* 27348 * Store prefix and namespace name. 27349 */ 27350 if (ielem->nsBindings == NULL) { 27351 ielem->nsBindings = 27352 (const xmlChar **) xmlMalloc(10 * 27353 sizeof(const xmlChar *)); 27354 if (ielem->nsBindings == NULL) { 27355 xmlSchemaVErrMemory(vctxt, 27356 "allocating namespace bindings for SAX validation", 27357 NULL); 27358 goto internal_error; 27359 } 27360 ielem->nbNsBindings = 0; 27361 ielem->sizeNsBindings = 5; 27362 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27363 ielem->sizeNsBindings *= 2; 27364 ielem->nsBindings = 27365 (const xmlChar **) xmlRealloc( 27366 (void *) ielem->nsBindings, 27367 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27368 if (ielem->nsBindings == NULL) { 27369 xmlSchemaVErrMemory(vctxt, 27370 "re-allocating namespace bindings for SAX validation", 27371 NULL); 27372 goto internal_error; 27373 } 27374 } 27375 27376 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27377 if (namespaces[j+1][0] == 0) { 27378 /* 27379 * Handle xmlns="". 27380 */ 27381 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27382 } else 27383 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27384 namespaces[j+1]; 27385 ielem->nbNsBindings++; 27386 } 27387 } 27388 /* 27389 * Register attributes. 27390 * SAX VAL TODO: We are not adding namespace declaration 27391 * attributes yet. 27392 */ 27393 if (nb_attributes != 0) { 27394 xmlChar *value; 27395 27396 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27397 /* 27398 * Duplicate the value, changing any & to a literal ampersand. 27399 * 27400 * libxml2 differs from normal SAX here in that it escapes all ampersands 27401 * as & instead of delivering the raw converted string. Changing the 27402 * behavior at this point would break applications that use this API, so 27403 * we are forced to work around it. There is no danger of accidentally 27404 * decoding some entity other than & in this step because without 27405 * unescaped ampersands there can be no other entities in the string. 27406 */ 27407 value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3], 27408 attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0); 27409 /* 27410 * TODO: Set the node line. 27411 */ 27412 ret = xmlSchemaValidatorPushAttribute(vctxt, 27413 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27414 value, 1); 27415 if (ret == -1) { 27416 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27417 "calling xmlSchemaValidatorPushAttribute()"); 27418 goto internal_error; 27419 } 27420 } 27421 } 27422 /* 27423 * Validate the element. 27424 */ 27425 ret = xmlSchemaValidateElem(vctxt); 27426 if (ret != 0) { 27427 if (ret == -1) { 27428 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27429 "calling xmlSchemaValidateElem()"); 27430 goto internal_error; 27431 } 27432 goto exit; 27433 } 27434 27435 exit: 27436 return; 27437 internal_error: 27438 vctxt->err = -1; 27439 xmlStopParser(vctxt->parserCtxt); 27440 return; 27441 } 27442 27443 static void 27444 xmlSchemaSAXHandleEndElementNs(void *ctx, 27445 const xmlChar * localname ATTRIBUTE_UNUSED, 27446 const xmlChar * prefix ATTRIBUTE_UNUSED, 27447 const xmlChar * URI ATTRIBUTE_UNUSED) 27448 { 27449 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27450 int res; 27451 27452 /* 27453 * Skip elements if inside a "skip" wildcard or if invalid. 27454 */ 27455 if (vctxt->skipDepth != -1) { 27456 if (vctxt->depth > vctxt->skipDepth) { 27457 vctxt->depth--; 27458 return; 27459 } else 27460 vctxt->skipDepth = -1; 27461 } 27462 /* 27463 * SAX VAL TODO: Just a temporary check. 27464 */ 27465 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27466 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27467 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27468 "elem pop mismatch"); 27469 } 27470 res = xmlSchemaValidatorPopElem(vctxt); 27471 if (res != 0) { 27472 if (res < 0) { 27473 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27474 "calling xmlSchemaValidatorPopElem()"); 27475 goto internal_error; 27476 } 27477 goto exit; 27478 } 27479 exit: 27480 return; 27481 internal_error: 27482 vctxt->err = -1; 27483 xmlStopParser(vctxt->parserCtxt); 27484 return; 27485 } 27486 27487 /************************************************************************ 27488 * * 27489 * Validation interfaces * 27490 * * 27491 ************************************************************************/ 27492 27493 /** 27494 * xmlSchemaNewValidCtxt: 27495 * @schema: a precompiled XML Schemas 27496 * 27497 * Create an XML Schemas validation context based on the given schema. 27498 * 27499 * Returns the validation context or NULL in case of error 27500 */ 27501 xmlSchemaValidCtxtPtr 27502 xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27503 { 27504 xmlSchemaValidCtxtPtr ret; 27505 27506 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27507 if (ret == NULL) { 27508 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27509 return (NULL); 27510 } 27511 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27512 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27513 ret->dict = xmlDictCreate(); 27514 ret->nodeQNames = xmlSchemaItemListCreate(); 27515 ret->schema = schema; 27516 return (ret); 27517 } 27518 27519 /** 27520 * xmlSchemaValidateSetFilename: 27521 * @vctxt: the schema validation context 27522 * @filename: the file name 27523 * 27524 * Workaround to provide file error reporting information when this is 27525 * not provided by current APIs 27526 */ 27527 void 27528 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) { 27529 if (vctxt == NULL) 27530 return; 27531 if (vctxt->filename != NULL) 27532 xmlFree(vctxt->filename); 27533 if (filename != NULL) 27534 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename); 27535 else 27536 vctxt->filename = NULL; 27537 } 27538 27539 /** 27540 * xmlSchemaClearValidCtxt: 27541 * @vctxt: the schema validation context 27542 * 27543 * Free the resources associated to the schema validation context; 27544 * leaves some fields alive intended for reuse of the context. 27545 */ 27546 static void 27547 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27548 { 27549 if (vctxt == NULL) 27550 return; 27551 27552 /* 27553 * TODO: Should we clear the flags? 27554 * Might be problematic if one reuses the context 27555 * and assumes that the options remain the same. 27556 */ 27557 vctxt->flags = 0; 27558 vctxt->validationRoot = NULL; 27559 vctxt->doc = NULL; 27560 #ifdef LIBXML_READER_ENABLED 27561 vctxt->reader = NULL; 27562 #endif 27563 vctxt->hasKeyrefs = 0; 27564 27565 if (vctxt->value != NULL) { 27566 xmlSchemaFreeValue(vctxt->value); 27567 vctxt->value = NULL; 27568 } 27569 /* 27570 * Augmented IDC information. 27571 */ 27572 if (vctxt->aidcs != NULL) { 27573 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27574 do { 27575 next = cur->next; 27576 xmlFree(cur); 27577 cur = next; 27578 } while (cur != NULL); 27579 vctxt->aidcs = NULL; 27580 } 27581 if (vctxt->idcMatcherCache != NULL) { 27582 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27583 27584 while (matcher) { 27585 tmp = matcher; 27586 matcher = matcher->nextCached; 27587 xmlSchemaIDCFreeMatcherList(tmp); 27588 } 27589 vctxt->idcMatcherCache = NULL; 27590 } 27591 27592 27593 if (vctxt->idcNodes != NULL) { 27594 int i; 27595 xmlSchemaPSVIIDCNodePtr item; 27596 27597 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27598 item = vctxt->idcNodes[i]; 27599 xmlFree(item->keys); 27600 xmlFree(item); 27601 } 27602 xmlFree(vctxt->idcNodes); 27603 vctxt->idcNodes = NULL; 27604 vctxt->nbIdcNodes = 0; 27605 vctxt->sizeIdcNodes = 0; 27606 } 27607 /* 27608 * Note that we won't delete the XPath state pool here. 27609 */ 27610 if (vctxt->xpathStates != NULL) { 27611 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27612 vctxt->xpathStates = NULL; 27613 } 27614 /* 27615 * Attribute info. 27616 */ 27617 if (vctxt->nbAttrInfos != 0) { 27618 xmlSchemaClearAttrInfos(vctxt); 27619 } 27620 /* 27621 * Element info. 27622 */ 27623 if (vctxt->elemInfos != NULL) { 27624 int i; 27625 xmlSchemaNodeInfoPtr ei; 27626 27627 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27628 ei = vctxt->elemInfos[i]; 27629 if (ei == NULL) 27630 break; 27631 xmlSchemaClearElemInfo(vctxt, ei); 27632 } 27633 } 27634 xmlSchemaItemListClear(vctxt->nodeQNames); 27635 /* Recreate the dict. */ 27636 xmlDictFree(vctxt->dict); 27637 /* 27638 * TODO: Is is save to recreate it? Do we have a scenario 27639 * where the user provides the dict? 27640 */ 27641 vctxt->dict = xmlDictCreate(); 27642 27643 if (vctxt->filename != NULL) { 27644 xmlFree(vctxt->filename); 27645 vctxt->filename = NULL; 27646 } 27647 } 27648 27649 /** 27650 * xmlSchemaFreeValidCtxt: 27651 * @ctxt: the schema validation context 27652 * 27653 * Free the resources associated to the schema validation context 27654 */ 27655 void 27656 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27657 { 27658 if (ctxt == NULL) 27659 return; 27660 if (ctxt->value != NULL) 27661 xmlSchemaFreeValue(ctxt->value); 27662 if (ctxt->pctxt != NULL) 27663 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27664 if (ctxt->idcNodes != NULL) { 27665 int i; 27666 xmlSchemaPSVIIDCNodePtr item; 27667 27668 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27669 item = ctxt->idcNodes[i]; 27670 xmlFree(item->keys); 27671 xmlFree(item); 27672 } 27673 xmlFree(ctxt->idcNodes); 27674 } 27675 if (ctxt->idcKeys != NULL) { 27676 int i; 27677 for (i = 0; i < ctxt->nbIdcKeys; i++) 27678 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27679 xmlFree(ctxt->idcKeys); 27680 } 27681 27682 if (ctxt->xpathStates != NULL) { 27683 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27684 ctxt->xpathStates = NULL; 27685 } 27686 if (ctxt->xpathStatePool != NULL) { 27687 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27688 ctxt->xpathStatePool = NULL; 27689 } 27690 27691 /* 27692 * Augmented IDC information. 27693 */ 27694 if (ctxt->aidcs != NULL) { 27695 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27696 do { 27697 next = cur->next; 27698 xmlFree(cur); 27699 cur = next; 27700 } while (cur != NULL); 27701 } 27702 if (ctxt->attrInfos != NULL) { 27703 int i; 27704 xmlSchemaAttrInfoPtr attr; 27705 27706 /* Just a paranoid call to the cleanup. */ 27707 if (ctxt->nbAttrInfos != 0) 27708 xmlSchemaClearAttrInfos(ctxt); 27709 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27710 attr = ctxt->attrInfos[i]; 27711 xmlFree(attr); 27712 } 27713 xmlFree(ctxt->attrInfos); 27714 } 27715 if (ctxt->elemInfos != NULL) { 27716 int i; 27717 xmlSchemaNodeInfoPtr ei; 27718 27719 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27720 ei = ctxt->elemInfos[i]; 27721 if (ei == NULL) 27722 break; 27723 xmlSchemaClearElemInfo(ctxt, ei); 27724 xmlFree(ei); 27725 } 27726 xmlFree(ctxt->elemInfos); 27727 } 27728 if (ctxt->nodeQNames != NULL) 27729 xmlSchemaItemListFree(ctxt->nodeQNames); 27730 if (ctxt->dict != NULL) 27731 xmlDictFree(ctxt->dict); 27732 if (ctxt->filename != NULL) 27733 xmlFree(ctxt->filename); 27734 xmlFree(ctxt); 27735 } 27736 27737 /** 27738 * xmlSchemaIsValid: 27739 * @ctxt: the schema validation context 27740 * 27741 * Check if any error was detected during validation. 27742 * 27743 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27744 * of internal error. 27745 */ 27746 int 27747 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27748 { 27749 if (ctxt == NULL) 27750 return(-1); 27751 return(ctxt->err == 0); 27752 } 27753 27754 /** 27755 * xmlSchemaSetValidErrors: 27756 * @ctxt: a schema validation context 27757 * @err: the error function 27758 * @warn: the warning function 27759 * @ctx: the functions context 27760 * 27761 * Set the error and warning callback informations 27762 */ 27763 void 27764 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27765 xmlSchemaValidityErrorFunc err, 27766 xmlSchemaValidityWarningFunc warn, void *ctx) 27767 { 27768 if (ctxt == NULL) 27769 return; 27770 ctxt->error = err; 27771 ctxt->warning = warn; 27772 ctxt->errCtxt = ctx; 27773 if (ctxt->pctxt != NULL) 27774 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27775 } 27776 27777 /** 27778 * xmlSchemaSetValidStructuredErrors: 27779 * @ctxt: a schema validation context 27780 * @serror: the structured error function 27781 * @ctx: the functions context 27782 * 27783 * Set the structured error callback 27784 */ 27785 void 27786 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27787 xmlStructuredErrorFunc serror, void *ctx) 27788 { 27789 if (ctxt == NULL) 27790 return; 27791 ctxt->serror = serror; 27792 ctxt->error = NULL; 27793 ctxt->warning = NULL; 27794 ctxt->errCtxt = ctx; 27795 if (ctxt->pctxt != NULL) 27796 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27797 } 27798 27799 /** 27800 * xmlSchemaGetValidErrors: 27801 * @ctxt: a XML-Schema validation context 27802 * @err: the error function result 27803 * @warn: the warning function result 27804 * @ctx: the functions context result 27805 * 27806 * Get the error and warning callback informations 27807 * 27808 * Returns -1 in case of error and 0 otherwise 27809 */ 27810 int 27811 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27812 xmlSchemaValidityErrorFunc * err, 27813 xmlSchemaValidityWarningFunc * warn, void **ctx) 27814 { 27815 if (ctxt == NULL) 27816 return (-1); 27817 if (err != NULL) 27818 *err = ctxt->error; 27819 if (warn != NULL) 27820 *warn = ctxt->warning; 27821 if (ctx != NULL) 27822 *ctx = ctxt->errCtxt; 27823 return (0); 27824 } 27825 27826 27827 /** 27828 * xmlSchemaSetValidOptions: 27829 * @ctxt: a schema validation context 27830 * @options: a combination of xmlSchemaValidOption 27831 * 27832 * Sets the options to be used during the validation. 27833 * 27834 * Returns 0 in case of success, -1 in case of an 27835 * API error. 27836 */ 27837 int 27838 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27839 int options) 27840 27841 { 27842 int i; 27843 27844 if (ctxt == NULL) 27845 return (-1); 27846 /* 27847 * WARNING: Change the start value if adding to the 27848 * xmlSchemaValidOption. 27849 * TODO: Is there an other, more easy to maintain, 27850 * way? 27851 */ 27852 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27853 if (options & 1<<i) 27854 return (-1); 27855 } 27856 ctxt->options = options; 27857 return (0); 27858 } 27859 27860 /** 27861 * xmlSchemaValidCtxtGetOptions: 27862 * @ctxt: a schema validation context 27863 * 27864 * Get the validation context options. 27865 * 27866 * Returns the option combination or -1 on error. 27867 */ 27868 int 27869 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27870 27871 { 27872 if (ctxt == NULL) 27873 return (-1); 27874 else 27875 return (ctxt->options); 27876 } 27877 27878 static int 27879 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27880 { 27881 xmlAttrPtr attr; 27882 int ret = 0; 27883 xmlSchemaNodeInfoPtr ielem = NULL; 27884 xmlNodePtr node, valRoot; 27885 const xmlChar *nsName; 27886 27887 /* DOC VAL TODO: Move this to the start function. */ 27888 if (vctxt->validationRoot != NULL) 27889 valRoot = vctxt->validationRoot; 27890 else 27891 valRoot = xmlDocGetRootElement(vctxt->doc); 27892 if (valRoot == NULL) { 27893 /* VAL TODO: Error code? */ 27894 VERROR(1, NULL, "The document has no document element"); 27895 return (1); 27896 } 27897 vctxt->depth = -1; 27898 vctxt->validationRoot = valRoot; 27899 node = valRoot; 27900 while (node != NULL) { 27901 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27902 goto next_sibling; 27903 if (node->type == XML_ELEMENT_NODE) { 27904 27905 /* 27906 * Init the node-info. 27907 */ 27908 vctxt->depth++; 27909 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27910 goto internal_error; 27911 ielem = vctxt->inode; 27912 ielem->node = node; 27913 ielem->nodeLine = node->line; 27914 ielem->localName = node->name; 27915 if (node->ns != NULL) 27916 ielem->nsName = node->ns->href; 27917 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27918 /* 27919 * Register attributes. 27920 * DOC VAL TODO: We do not register namespace declaration 27921 * attributes yet. 27922 */ 27923 vctxt->nbAttrInfos = 0; 27924 if (node->properties != NULL) { 27925 attr = node->properties; 27926 do { 27927 if (attr->ns != NULL) 27928 nsName = attr->ns->href; 27929 else 27930 nsName = NULL; 27931 ret = xmlSchemaValidatorPushAttribute(vctxt, 27932 (xmlNodePtr) attr, 27933 /* 27934 * Note that we give it the line number of the 27935 * parent element. 27936 */ 27937 ielem->nodeLine, 27938 attr->name, nsName, 0, 27939 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27940 if (ret == -1) { 27941 VERROR_INT("xmlSchemaDocWalk", 27942 "calling xmlSchemaValidatorPushAttribute()"); 27943 goto internal_error; 27944 } 27945 attr = attr->next; 27946 } while (attr); 27947 } 27948 /* 27949 * Validate the element. 27950 */ 27951 ret = xmlSchemaValidateElem(vctxt); 27952 if (ret != 0) { 27953 if (ret == -1) { 27954 VERROR_INT("xmlSchemaDocWalk", 27955 "calling xmlSchemaValidateElem()"); 27956 goto internal_error; 27957 } 27958 /* 27959 * Don't stop validation; just skip the content 27960 * of this element. 27961 */ 27962 goto leave_node; 27963 } 27964 if ((vctxt->skipDepth != -1) && 27965 (vctxt->depth >= vctxt->skipDepth)) 27966 goto leave_node; 27967 } else if ((node->type == XML_TEXT_NODE) || 27968 (node->type == XML_CDATA_SECTION_NODE)) { 27969 /* 27970 * Process character content. 27971 */ 27972 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 27973 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27974 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 27975 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 27976 if (ret < 0) { 27977 VERROR_INT("xmlSchemaVDocWalk", 27978 "calling xmlSchemaVPushText()"); 27979 goto internal_error; 27980 } 27981 /* 27982 * DOC VAL TODO: Should we skip further validation of the 27983 * element content here? 27984 */ 27985 } else if ((node->type == XML_ENTITY_NODE) || 27986 (node->type == XML_ENTITY_REF_NODE)) { 27987 /* 27988 * DOC VAL TODO: What to do with entities? 27989 */ 27990 VERROR_INT("xmlSchemaVDocWalk", 27991 "there is at least one entity reference in the node-tree " 27992 "currently being validated. Processing of entities with " 27993 "this XML Schema processor is not supported (yet). Please " 27994 "substitute entities before validation."); 27995 goto internal_error; 27996 } else { 27997 goto leave_node; 27998 /* 27999 * DOC VAL TODO: XInclude nodes, etc. 28000 */ 28001 } 28002 /* 28003 * Walk the doc. 28004 */ 28005 if (node->children != NULL) { 28006 node = node->children; 28007 continue; 28008 } 28009 leave_node: 28010 if (node->type == XML_ELEMENT_NODE) { 28011 /* 28012 * Leaving the scope of an element. 28013 */ 28014 if (node != vctxt->inode->node) { 28015 VERROR_INT("xmlSchemaVDocWalk", 28016 "element position mismatch"); 28017 goto internal_error; 28018 } 28019 ret = xmlSchemaValidatorPopElem(vctxt); 28020 if (ret != 0) { 28021 if (ret < 0) { 28022 VERROR_INT("xmlSchemaVDocWalk", 28023 "calling xmlSchemaValidatorPopElem()"); 28024 goto internal_error; 28025 } 28026 } 28027 if (node == valRoot) 28028 goto exit; 28029 } 28030 next_sibling: 28031 if (node->next != NULL) 28032 node = node->next; 28033 else { 28034 node = node->parent; 28035 goto leave_node; 28036 } 28037 } 28038 28039 exit: 28040 return (ret); 28041 internal_error: 28042 return (-1); 28043 } 28044 28045 static int 28046 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 28047 /* 28048 * Some initialization. 28049 */ 28050 vctxt->err = 0; 28051 vctxt->nberrors = 0; 28052 vctxt->depth = -1; 28053 vctxt->skipDepth = -1; 28054 vctxt->xsiAssemble = 0; 28055 vctxt->hasKeyrefs = 0; 28056 #ifdef ENABLE_IDC_NODE_TABLES_TEST 28057 vctxt->createIDCNodeTables = 1; 28058 #else 28059 vctxt->createIDCNodeTables = 0; 28060 #endif 28061 /* 28062 * Create a schema + parser if necessary. 28063 */ 28064 if (vctxt->schema == NULL) { 28065 xmlSchemaParserCtxtPtr pctxt; 28066 28067 vctxt->xsiAssemble = 1; 28068 /* 28069 * If not schema was given then we will create a schema 28070 * dynamically using XSI schema locations. 28071 * 28072 * Create the schema parser context. 28073 */ 28074 if ((vctxt->pctxt == NULL) && 28075 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 28076 return (-1); 28077 pctxt = vctxt->pctxt; 28078 pctxt->xsiAssemble = 1; 28079 /* 28080 * Create the schema. 28081 */ 28082 vctxt->schema = xmlSchemaNewSchema(pctxt); 28083 if (vctxt->schema == NULL) 28084 return (-1); 28085 /* 28086 * Create the schema construction context. 28087 */ 28088 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 28089 if (pctxt->constructor == NULL) 28090 return(-1); 28091 pctxt->constructor->mainSchema = vctxt->schema; 28092 /* 28093 * Take ownership of the constructor to be able to free it. 28094 */ 28095 pctxt->ownsConstructor = 1; 28096 } 28097 /* 28098 * Augment the IDC definitions for the main schema and all imported ones 28099 * NOTE: main schema if the first in the imported list 28100 */ 28101 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 28102 28103 return(0); 28104 } 28105 28106 static void 28107 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28108 if (vctxt->xsiAssemble) { 28109 if (vctxt->schema != NULL) { 28110 xmlSchemaFree(vctxt->schema); 28111 vctxt->schema = NULL; 28112 } 28113 } 28114 xmlSchemaClearValidCtxt(vctxt); 28115 } 28116 28117 static int 28118 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28119 { 28120 int ret = 0; 28121 28122 if (xmlSchemaPreRun(vctxt) < 0) 28123 return(-1); 28124 28125 if (vctxt->doc != NULL) { 28126 /* 28127 * Tree validation. 28128 */ 28129 ret = xmlSchemaVDocWalk(vctxt); 28130 #ifdef LIBXML_READER_ENABLED 28131 } else if (vctxt->reader != NULL) { 28132 /* 28133 * XML Reader validation. 28134 */ 28135 #ifdef XML_SCHEMA_READER_ENABLED 28136 ret = xmlSchemaVReaderWalk(vctxt); 28137 #endif 28138 #endif 28139 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28140 /* 28141 * SAX validation. 28142 */ 28143 ret = xmlParseDocument(vctxt->parserCtxt); 28144 } else { 28145 VERROR_INT("xmlSchemaVStart", 28146 "no instance to validate"); 28147 ret = -1; 28148 } 28149 28150 xmlSchemaPostRun(vctxt); 28151 if (ret == 0) 28152 ret = vctxt->err; 28153 return (ret); 28154 } 28155 28156 /** 28157 * xmlSchemaValidateOneElement: 28158 * @ctxt: a schema validation context 28159 * @elem: an element node 28160 * 28161 * Validate a branch of a tree, starting with the given @elem. 28162 * 28163 * Returns 0 if the element and its subtree is valid, a positive error 28164 * code number otherwise and -1 in case of an internal or API error. 28165 */ 28166 int 28167 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28168 { 28169 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28170 return (-1); 28171 28172 if (ctxt->schema == NULL) 28173 return (-1); 28174 28175 ctxt->doc = elem->doc; 28176 ctxt->node = elem; 28177 ctxt->validationRoot = elem; 28178 return(xmlSchemaVStart(ctxt)); 28179 } 28180 28181 /** 28182 * xmlSchemaValidateDoc: 28183 * @ctxt: a schema validation context 28184 * @doc: a parsed document tree 28185 * 28186 * Validate a document tree in memory. 28187 * 28188 * Returns 0 if the document is schemas valid, a positive error code 28189 * number otherwise and -1 in case of internal or API error. 28190 */ 28191 int 28192 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28193 { 28194 if ((ctxt == NULL) || (doc == NULL)) 28195 return (-1); 28196 28197 ctxt->doc = doc; 28198 ctxt->node = xmlDocGetRootElement(doc); 28199 if (ctxt->node == NULL) { 28200 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28201 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28202 (xmlNodePtr) doc, NULL, 28203 "The document has no document element", NULL, NULL); 28204 return (ctxt->err); 28205 } 28206 ctxt->validationRoot = ctxt->node; 28207 return (xmlSchemaVStart(ctxt)); 28208 } 28209 28210 28211 /************************************************************************ 28212 * * 28213 * Function and data for SAX streaming API * 28214 * * 28215 ************************************************************************/ 28216 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28217 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28218 28219 struct _xmlSchemaSplitSAXData { 28220 xmlSAXHandlerPtr user_sax; 28221 void *user_data; 28222 xmlSchemaValidCtxtPtr ctxt; 28223 xmlSAXHandlerPtr schemas_sax; 28224 }; 28225 28226 #define XML_SAX_PLUG_MAGIC 0xdc43ba21 28227 28228 struct _xmlSchemaSAXPlug { 28229 unsigned int magic; 28230 28231 /* the original callbacks informations */ 28232 xmlSAXHandlerPtr *user_sax_ptr; 28233 xmlSAXHandlerPtr user_sax; 28234 void **user_data_ptr; 28235 void *user_data; 28236 28237 /* the block plugged back and validation informations */ 28238 xmlSAXHandler schemas_sax; 28239 xmlSchemaValidCtxtPtr ctxt; 28240 }; 28241 28242 /* All those functions just bounces to the user provided SAX handlers */ 28243 static void 28244 internalSubsetSplit(void *ctx, const xmlChar *name, 28245 const xmlChar *ExternalID, const xmlChar *SystemID) 28246 { 28247 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28248 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28249 (ctxt->user_sax->internalSubset != NULL)) 28250 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28251 SystemID); 28252 } 28253 28254 static int 28255 isStandaloneSplit(void *ctx) 28256 { 28257 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28258 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28259 (ctxt->user_sax->isStandalone != NULL)) 28260 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28261 return(0); 28262 } 28263 28264 static int 28265 hasInternalSubsetSplit(void *ctx) 28266 { 28267 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28268 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28269 (ctxt->user_sax->hasInternalSubset != NULL)) 28270 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28271 return(0); 28272 } 28273 28274 static int 28275 hasExternalSubsetSplit(void *ctx) 28276 { 28277 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28278 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28279 (ctxt->user_sax->hasExternalSubset != NULL)) 28280 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28281 return(0); 28282 } 28283 28284 static void 28285 externalSubsetSplit(void *ctx, const xmlChar *name, 28286 const xmlChar *ExternalID, const xmlChar *SystemID) 28287 { 28288 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28289 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28290 (ctxt->user_sax->externalSubset != NULL)) 28291 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28292 SystemID); 28293 } 28294 28295 static xmlParserInputPtr 28296 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28297 { 28298 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28299 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28300 (ctxt->user_sax->resolveEntity != NULL)) 28301 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28302 systemId)); 28303 return(NULL); 28304 } 28305 28306 static xmlEntityPtr 28307 getEntitySplit(void *ctx, const xmlChar *name) 28308 { 28309 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28310 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28311 (ctxt->user_sax->getEntity != NULL)) 28312 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28313 return(NULL); 28314 } 28315 28316 static xmlEntityPtr 28317 getParameterEntitySplit(void *ctx, const xmlChar *name) 28318 { 28319 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28320 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28321 (ctxt->user_sax->getParameterEntity != NULL)) 28322 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28323 return(NULL); 28324 } 28325 28326 28327 static void 28328 entityDeclSplit(void *ctx, const xmlChar *name, int type, 28329 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28330 { 28331 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28332 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28333 (ctxt->user_sax->entityDecl != NULL)) 28334 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28335 systemId, content); 28336 } 28337 28338 static void 28339 attributeDeclSplit(void *ctx, const xmlChar * elem, 28340 const xmlChar * name, int type, int def, 28341 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28342 { 28343 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28344 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28345 (ctxt->user_sax->attributeDecl != NULL)) { 28346 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28347 def, defaultValue, tree); 28348 } else { 28349 xmlFreeEnumeration(tree); 28350 } 28351 } 28352 28353 static void 28354 elementDeclSplit(void *ctx, const xmlChar *name, int type, 28355 xmlElementContentPtr content) 28356 { 28357 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28358 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28359 (ctxt->user_sax->elementDecl != NULL)) 28360 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28361 } 28362 28363 static void 28364 notationDeclSplit(void *ctx, const xmlChar *name, 28365 const xmlChar *publicId, const xmlChar *systemId) 28366 { 28367 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28368 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28369 (ctxt->user_sax->notationDecl != NULL)) 28370 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28371 systemId); 28372 } 28373 28374 static void 28375 unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28376 const xmlChar *publicId, const xmlChar *systemId, 28377 const xmlChar *notationName) 28378 { 28379 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28380 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28381 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28382 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28383 systemId, notationName); 28384 } 28385 28386 static void 28387 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28388 { 28389 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28390 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28391 (ctxt->user_sax->setDocumentLocator != NULL)) 28392 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28393 } 28394 28395 static void 28396 startDocumentSplit(void *ctx) 28397 { 28398 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28399 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28400 (ctxt->user_sax->startDocument != NULL)) 28401 ctxt->user_sax->startDocument(ctxt->user_data); 28402 } 28403 28404 static void 28405 endDocumentSplit(void *ctx) 28406 { 28407 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28408 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28409 (ctxt->user_sax->endDocument != NULL)) 28410 ctxt->user_sax->endDocument(ctxt->user_data); 28411 } 28412 28413 static void 28414 processingInstructionSplit(void *ctx, const xmlChar *target, 28415 const xmlChar *data) 28416 { 28417 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28418 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28419 (ctxt->user_sax->processingInstruction != NULL)) 28420 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28421 } 28422 28423 static void 28424 commentSplit(void *ctx, const xmlChar *value) 28425 { 28426 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28427 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28428 (ctxt->user_sax->comment != NULL)) 28429 ctxt->user_sax->comment(ctxt->user_data, value); 28430 } 28431 28432 /* 28433 * Varargs error callbacks to the user application, harder ... 28434 */ 28435 28436 static void XMLCDECL 28437 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28438 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28439 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28440 (ctxt->user_sax->warning != NULL)) { 28441 TODO 28442 } 28443 } 28444 static void XMLCDECL 28445 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28446 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28447 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28448 (ctxt->user_sax->error != NULL)) { 28449 TODO 28450 } 28451 } 28452 static void XMLCDECL 28453 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28454 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28455 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28456 (ctxt->user_sax->fatalError != NULL)) { 28457 TODO 28458 } 28459 } 28460 28461 /* 28462 * Those are function where both the user handler and the schemas handler 28463 * need to be called. 28464 */ 28465 static void 28466 charactersSplit(void *ctx, const xmlChar *ch, int len) 28467 { 28468 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28469 if (ctxt == NULL) 28470 return; 28471 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28472 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28473 if (ctxt->ctxt != NULL) 28474 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28475 } 28476 28477 static void 28478 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28479 { 28480 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28481 if (ctxt == NULL) 28482 return; 28483 if ((ctxt->user_sax != NULL) && 28484 (ctxt->user_sax->ignorableWhitespace != NULL)) 28485 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28486 if (ctxt->ctxt != NULL) 28487 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28488 } 28489 28490 static void 28491 cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28492 { 28493 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28494 if (ctxt == NULL) 28495 return; 28496 if ((ctxt->user_sax != NULL) && 28497 (ctxt->user_sax->cdataBlock != NULL)) 28498 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28499 if (ctxt->ctxt != NULL) 28500 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28501 } 28502 28503 static void 28504 referenceSplit(void *ctx, const xmlChar *name) 28505 { 28506 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28507 if (ctxt == NULL) 28508 return; 28509 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28510 (ctxt->user_sax->reference != NULL)) 28511 ctxt->user_sax->reference(ctxt->user_data, name); 28512 if (ctxt->ctxt != NULL) 28513 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28514 } 28515 28516 static void 28517 startElementNsSplit(void *ctx, const xmlChar * localname, 28518 const xmlChar * prefix, const xmlChar * URI, 28519 int nb_namespaces, const xmlChar ** namespaces, 28520 int nb_attributes, int nb_defaulted, 28521 const xmlChar ** attributes) { 28522 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28523 if (ctxt == NULL) 28524 return; 28525 if ((ctxt->user_sax != NULL) && 28526 (ctxt->user_sax->startElementNs != NULL)) 28527 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28528 URI, nb_namespaces, namespaces, 28529 nb_attributes, nb_defaulted, 28530 attributes); 28531 if (ctxt->ctxt != NULL) 28532 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28533 URI, nb_namespaces, namespaces, 28534 nb_attributes, nb_defaulted, 28535 attributes); 28536 } 28537 28538 static void 28539 endElementNsSplit(void *ctx, const xmlChar * localname, 28540 const xmlChar * prefix, const xmlChar * URI) { 28541 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28542 if (ctxt == NULL) 28543 return; 28544 if ((ctxt->user_sax != NULL) && 28545 (ctxt->user_sax->endElementNs != NULL)) 28546 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28547 if (ctxt->ctxt != NULL) 28548 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28549 } 28550 28551 /** 28552 * xmlSchemaSAXPlug: 28553 * @ctxt: a schema validation context 28554 * @sax: a pointer to the original xmlSAXHandlerPtr 28555 * @user_data: a pointer to the original SAX user data pointer 28556 * 28557 * Plug a SAX based validation layer in a SAX parsing event flow. 28558 * The original @saxptr and @dataptr data are replaced by new pointers 28559 * but the calls to the original will be maintained. 28560 * 28561 * Returns a pointer to a data structure needed to unplug the validation layer 28562 * or NULL in case of errors. 28563 */ 28564 xmlSchemaSAXPlugPtr 28565 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28566 xmlSAXHandlerPtr *sax, void **user_data) 28567 { 28568 xmlSchemaSAXPlugPtr ret; 28569 xmlSAXHandlerPtr old_sax; 28570 28571 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28572 return(NULL); 28573 28574 /* 28575 * We only allow to plug into SAX2 event streams 28576 */ 28577 old_sax = *sax; 28578 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28579 return(NULL); 28580 if ((old_sax != NULL) && 28581 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28582 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28583 return(NULL); 28584 28585 /* 28586 * everything seems right allocate the local data needed for that layer 28587 */ 28588 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28589 if (ret == NULL) { 28590 return(NULL); 28591 } 28592 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28593 ret->magic = XML_SAX_PLUG_MAGIC; 28594 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28595 ret->ctxt = ctxt; 28596 ret->user_sax_ptr = sax; 28597 ret->user_sax = old_sax; 28598 if (old_sax == NULL) { 28599 /* 28600 * go direct, no need for the split block and functions. 28601 */ 28602 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28603 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28604 /* 28605 * Note that we use the same text-function for both, to prevent 28606 * the parser from testing for ignorable whitespace. 28607 */ 28608 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28609 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28610 28611 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28612 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28613 28614 ret->user_data = ctxt; 28615 *user_data = ctxt; 28616 } else { 28617 /* 28618 * for each callback unused by Schemas initialize it to the Split 28619 * routine only if non NULL in the user block, this can speed up 28620 * things at the SAX level. 28621 */ 28622 if (old_sax->internalSubset != NULL) 28623 ret->schemas_sax.internalSubset = internalSubsetSplit; 28624 if (old_sax->isStandalone != NULL) 28625 ret->schemas_sax.isStandalone = isStandaloneSplit; 28626 if (old_sax->hasInternalSubset != NULL) 28627 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28628 if (old_sax->hasExternalSubset != NULL) 28629 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28630 if (old_sax->resolveEntity != NULL) 28631 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28632 if (old_sax->getEntity != NULL) 28633 ret->schemas_sax.getEntity = getEntitySplit; 28634 if (old_sax->entityDecl != NULL) 28635 ret->schemas_sax.entityDecl = entityDeclSplit; 28636 if (old_sax->notationDecl != NULL) 28637 ret->schemas_sax.notationDecl = notationDeclSplit; 28638 if (old_sax->attributeDecl != NULL) 28639 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28640 if (old_sax->elementDecl != NULL) 28641 ret->schemas_sax.elementDecl = elementDeclSplit; 28642 if (old_sax->unparsedEntityDecl != NULL) 28643 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28644 if (old_sax->setDocumentLocator != NULL) 28645 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28646 if (old_sax->startDocument != NULL) 28647 ret->schemas_sax.startDocument = startDocumentSplit; 28648 if (old_sax->endDocument != NULL) 28649 ret->schemas_sax.endDocument = endDocumentSplit; 28650 if (old_sax->processingInstruction != NULL) 28651 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28652 if (old_sax->comment != NULL) 28653 ret->schemas_sax.comment = commentSplit; 28654 if (old_sax->warning != NULL) 28655 ret->schemas_sax.warning = warningSplit; 28656 if (old_sax->error != NULL) 28657 ret->schemas_sax.error = errorSplit; 28658 if (old_sax->fatalError != NULL) 28659 ret->schemas_sax.fatalError = fatalErrorSplit; 28660 if (old_sax->getParameterEntity != NULL) 28661 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28662 if (old_sax->externalSubset != NULL) 28663 ret->schemas_sax.externalSubset = externalSubsetSplit; 28664 28665 /* 28666 * the 6 schemas callback have to go to the splitter functions 28667 * Note that we use the same text-function for ignorableWhitespace 28668 * if possible, to prevent the parser from testing for ignorable 28669 * whitespace. 28670 */ 28671 ret->schemas_sax.characters = charactersSplit; 28672 if ((old_sax->ignorableWhitespace != NULL) && 28673 (old_sax->ignorableWhitespace != old_sax->characters)) 28674 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28675 else 28676 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28677 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28678 ret->schemas_sax.reference = referenceSplit; 28679 ret->schemas_sax.startElementNs = startElementNsSplit; 28680 ret->schemas_sax.endElementNs = endElementNsSplit; 28681 28682 ret->user_data_ptr = user_data; 28683 ret->user_data = *user_data; 28684 *user_data = ret; 28685 } 28686 28687 /* 28688 * plug the pointers back. 28689 */ 28690 *sax = &(ret->schemas_sax); 28691 ctxt->sax = *sax; 28692 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28693 xmlSchemaPreRun(ctxt); 28694 return(ret); 28695 } 28696 28697 /** 28698 * xmlSchemaSAXUnplug: 28699 * @plug: a data structure returned by xmlSchemaSAXPlug 28700 * 28701 * Unplug a SAX based validation layer in a SAX parsing event flow. 28702 * The original pointers used in the call are restored. 28703 * 28704 * Returns 0 in case of success and -1 in case of failure. 28705 */ 28706 int 28707 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28708 { 28709 xmlSAXHandlerPtr *sax; 28710 void **user_data; 28711 28712 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28713 return(-1); 28714 plug->magic = 0; 28715 28716 xmlSchemaPostRun(plug->ctxt); 28717 /* restore the data */ 28718 sax = plug->user_sax_ptr; 28719 *sax = plug->user_sax; 28720 if (plug->user_sax != NULL) { 28721 user_data = plug->user_data_ptr; 28722 *user_data = plug->user_data; 28723 } 28724 28725 /* free and return */ 28726 xmlFree(plug); 28727 return(0); 28728 } 28729 28730 /** 28731 * xmlSchemaValidateSetLocator: 28732 * @vctxt: a schema validation context 28733 * @f: the locator function pointer 28734 * @ctxt: the locator context 28735 * 28736 * Allows to set a locator function to the validation context, 28737 * which will be used to provide file and line information since 28738 * those are not provided as part of the SAX validation flow 28739 * Setting @f to NULL disable the locator. 28740 */ 28741 28742 void 28743 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt, 28744 xmlSchemaValidityLocatorFunc f, 28745 void *ctxt) 28746 { 28747 if (vctxt == NULL) return; 28748 vctxt->locFunc = f; 28749 vctxt->locCtxt = ctxt; 28750 } 28751 28752 /** 28753 * xmlSchemaValidateStreamLocator: 28754 * @ctx: the xmlTextReaderPtr used 28755 * @file: returned file information 28756 * @line: returned line information 28757 * 28758 * Internal locator function for the readers 28759 * 28760 * Returns 0 in case the Schema validation could be (des)activated and 28761 * -1 in case of error. 28762 */ 28763 static int 28764 xmlSchemaValidateStreamLocator(void *ctx, const char **file, 28765 unsigned long *line) { 28766 xmlParserCtxtPtr ctxt; 28767 28768 if ((ctx == NULL) || ((file == NULL) && (line == NULL))) 28769 return(-1); 28770 28771 if (file != NULL) 28772 *file = NULL; 28773 if (line != NULL) 28774 *line = 0; 28775 28776 ctxt = (xmlParserCtxtPtr) ctx; 28777 if (ctxt->input != NULL) { 28778 if (file != NULL) 28779 *file = ctxt->input->filename; 28780 if (line != NULL) 28781 *line = ctxt->input->line; 28782 return(0); 28783 } 28784 return(-1); 28785 } 28786 28787 /** 28788 * xmlSchemaValidateStream: 28789 * @ctxt: a schema validation context 28790 * @input: the input to use for reading the data 28791 * @enc: an optional encoding information 28792 * @sax: a SAX handler for the resulting events 28793 * @user_data: the context to provide to the SAX handler. 28794 * 28795 * Validate an input based on a flow of SAX event from the parser 28796 * and forward the events to the @sax handler with the provided @user_data 28797 * the user provided @sax handler must be a SAX2 one. 28798 * 28799 * Returns 0 if the document is schemas valid, a positive error code 28800 * number otherwise and -1 in case of internal or API error. 28801 */ 28802 int 28803 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28804 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28805 xmlSAXHandlerPtr sax, void *user_data) 28806 { 28807 xmlSchemaSAXPlugPtr plug = NULL; 28808 xmlSAXHandlerPtr old_sax = NULL; 28809 xmlParserCtxtPtr pctxt = NULL; 28810 xmlParserInputPtr inputStream = NULL; 28811 int ret; 28812 28813 if ((ctxt == NULL) || (input == NULL)) 28814 return (-1); 28815 28816 /* 28817 * prepare the parser 28818 */ 28819 pctxt = xmlNewParserCtxt(); 28820 if (pctxt == NULL) 28821 return (-1); 28822 old_sax = pctxt->sax; 28823 pctxt->sax = sax; 28824 pctxt->userData = user_data; 28825 #if 0 28826 if (options) 28827 xmlCtxtUseOptions(pctxt, options); 28828 #endif 28829 pctxt->linenumbers = 1; 28830 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt); 28831 28832 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28833 if (inputStream == NULL) { 28834 ret = -1; 28835 goto done; 28836 } 28837 inputPush(pctxt, inputStream); 28838 ctxt->parserCtxt = pctxt; 28839 ctxt->input = input; 28840 28841 /* 28842 * Plug the validation and launch the parsing 28843 */ 28844 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28845 if (plug == NULL) { 28846 ret = -1; 28847 goto done; 28848 } 28849 ctxt->input = input; 28850 ctxt->enc = enc; 28851 ctxt->sax = pctxt->sax; 28852 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28853 ret = xmlSchemaVStart(ctxt); 28854 28855 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28856 ret = ctxt->parserCtxt->errNo; 28857 if (ret == 0) 28858 ret = 1; 28859 } 28860 28861 done: 28862 ctxt->parserCtxt = NULL; 28863 ctxt->sax = NULL; 28864 ctxt->input = NULL; 28865 if (plug != NULL) { 28866 xmlSchemaSAXUnplug(plug); 28867 } 28868 /* cleanup */ 28869 if (pctxt != NULL) { 28870 pctxt->sax = old_sax; 28871 xmlFreeParserCtxt(pctxt); 28872 } 28873 return (ret); 28874 } 28875 28876 /** 28877 * xmlSchemaValidateFile: 28878 * @ctxt: a schema validation context 28879 * @filename: the URI of the instance 28880 * @options: a future set of options, currently unused 28881 * 28882 * Do a schemas validation of the given resource, it will use the 28883 * SAX streamable validation internally. 28884 * 28885 * Returns 0 if the document is valid, a positive error code 28886 * number otherwise and -1 in case of an internal or API error. 28887 */ 28888 int 28889 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28890 const char * filename, 28891 int options ATTRIBUTE_UNUSED) 28892 { 28893 int ret; 28894 xmlParserInputBufferPtr input; 28895 28896 if ((ctxt == NULL) || (filename == NULL)) 28897 return (-1); 28898 28899 input = xmlParserInputBufferCreateFilename(filename, 28900 XML_CHAR_ENCODING_NONE); 28901 if (input == NULL) 28902 return (-1); 28903 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28904 NULL, NULL); 28905 return (ret); 28906 } 28907 28908 /** 28909 * xmlSchemaValidCtxtGetParserCtxt: 28910 * @ctxt: a schema validation context 28911 * 28912 * allow access to the parser context of the schema validation context 28913 * 28914 * Returns the parser context of the schema validation context or NULL 28915 * in case of error. 28916 */ 28917 xmlParserCtxtPtr 28918 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28919 { 28920 if (ctxt == NULL) 28921 return(NULL); 28922 return (ctxt->parserCtxt); 28923 } 28924 28925 #define bottom_xmlschemas 28926 #include "elfgcchack.h" 28927 #endif /* LIBXML_SCHEMAS_ENABLED */ 28928