1 /* 2 * schemas.c : implementation of the XML Schema handling and 3 * schema validity checking 4 * 5 * See Copyright for the status of this software. 6 * 7 * Daniel Veillard <veillard (at) redhat.com> 8 */ 9 10 /* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - if we don't intend to use the schema for schemas, we 16 * need to validate all schema attributes (ref, type, name) 17 * against their types. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 48 /* To avoid EBCDIC trouble when parsing on zOS */ 49 #if defined(__MVS__) 50 #pragma convert("ISO8859-1") 51 #endif 52 53 #define IN_LIBXML 54 #include "libxml.h" 55 56 #ifdef LIBXML_SCHEMAS_ENABLED 57 58 #include <string.h> 59 #include <libxml/xmlmemory.h> 60 #include <libxml/parser.h> 61 #include <libxml/parserInternals.h> 62 #include <libxml/hash.h> 63 #include <libxml/uri.h> 64 #include <libxml/xmlschemas.h> 65 #include <libxml/schemasInternals.h> 66 #include <libxml/xmlschemastypes.h> 67 #include <libxml/xmlautomata.h> 68 #include <libxml/xmlregexp.h> 69 #include <libxml/dict.h> 70 #include <libxml/encoding.h> 71 #include <libxml/xmlIO.h> 72 #ifdef LIBXML_PATTERN_ENABLED 73 #include <libxml/pattern.h> 74 #endif 75 #ifdef LIBXML_READER_ENABLED 76 #include <libxml/xmlreader.h> 77 #endif 78 79 /* #define DEBUG 1 */ 80 81 /* #define DEBUG_CONTENT 1 */ 82 83 /* #define DEBUG_TYPE 1 */ 84 85 /* #define DEBUG_CONTENT_REGEXP 1 */ 86 87 /* #define DEBUG_AUTOMATA 1 */ 88 89 /* #define DEBUG_IDC */ 90 91 /* #define DEBUG_IDC_NODE_TABLE */ 92 93 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 94 95 #ifdef DEBUG_IDC 96 #ifndef DEBUG_IDC_NODE_TABLE 97 #define DEBUG_IDC_NODE_TABLE 98 #endif 99 #endif 100 101 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 102 103 #define ENABLE_REDEFINE 104 105 /* #define ENABLE_NAMED_LOCALS */ 106 107 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 108 109 #define DUMP_CONTENT_MODEL 110 111 #ifdef LIBXML_READER_ENABLED 112 /* #define XML_SCHEMA_READER_ENABLED */ 113 #endif 114 115 #define UNBOUNDED (1 << 30) 116 #define TODO \ 117 xmlGenericError(xmlGenericErrorContext, \ 118 "Unimplemented block at %s:%d\n", \ 119 __FILE__, __LINE__); 120 121 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 122 123 /* 124 * The XML Schemas namespaces 125 */ 126 static const xmlChar *xmlSchemaNs = (const xmlChar *) 127 "http://www.w3.org/2001/XMLSchema"; 128 129 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 130 "http://www.w3.org/2001/XMLSchema-instance"; 131 132 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 133 "http://www.w3.org/2000/xmlns/"; 134 135 /* 136 * Come casting macros. 137 */ 138 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 139 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 140 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 141 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 142 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 143 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 144 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 145 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 146 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 147 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 148 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 149 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 150 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 151 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 152 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 153 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 154 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 155 156 /* 157 * Macros to query common properties of components. 158 */ 159 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 160 161 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 162 /* 163 * Macros for element declarations. 164 */ 165 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 166 167 #define WXS_SUBST_HEAD(item) (item)->refDecl 168 /* 169 * Macros for attribute declarations. 170 */ 171 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 172 /* 173 * Macros for attribute uses. 174 */ 175 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl 176 177 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 178 179 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 180 181 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 182 /* 183 * Macros for attribute groups. 184 */ 185 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 186 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 187 /* 188 * Macros for particles. 189 */ 190 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 191 192 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 193 194 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 195 196 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 197 /* 198 * Macros for model groups definitions. 199 */ 200 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 201 /* 202 * Macros for model groups. 203 */ 204 #define WXS_IS_MODEL_GROUP(i) \ 205 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 206 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 207 ((i)->type == XML_SCHEMA_TYPE_ALL)) 208 209 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 210 /* 211 * Macros for schema buckets. 212 */ 213 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 214 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 215 216 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 217 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 218 219 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 220 221 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 222 /* 223 * Macros for complex/simple types. 224 */ 225 #define WXS_IS_ANYTYPE(i) \ 226 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 227 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 228 229 #define WXS_IS_COMPLEX(i) \ 230 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 231 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 232 233 #define WXS_IS_SIMPLE(item) \ 234 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 235 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 236 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 237 238 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 239 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 240 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 241 242 #define WXS_IS_RESTRICTION(t) \ 243 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 244 245 #define WXS_IS_EXTENSION(t) \ 246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 247 248 #define WXS_IS_TYPE_NOT_FIXED(i) \ 249 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 250 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 251 252 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 253 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 254 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 255 256 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 257 258 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 259 /* 260 * Macros for exclusively for complex types. 261 */ 262 #define WXS_HAS_COMPLEX_CONTENT(item) \ 263 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 264 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 265 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 266 267 #define WXS_HAS_SIMPLE_CONTENT(item) \ 268 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 269 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 270 271 #define WXS_HAS_MIXED_CONTENT(item) \ 272 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 273 274 #define WXS_EMPTIABLE(t) \ 275 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 276 277 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 278 279 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 280 281 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 282 /* 283 * Macros for exclusively for simple types. 284 */ 285 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 286 287 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 288 289 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 290 291 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 292 /* 293 * Misc parser context macros. 294 */ 295 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 296 297 #define WXS_HAS_BUCKETS(ctx) \ 298 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 299 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 300 301 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 302 303 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 304 305 #define WXS_SCHEMA(ctx) (ctx)->schema 306 307 #define WXS_ADD_LOCAL(ctx, item) \ 308 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 309 310 #define WXS_ADD_GLOBAL(ctx, item) \ 311 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 312 313 #define WXS_ADD_PENDING(ctx, item) \ 314 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 315 /* 316 * xmlSchemaItemList macros. 317 */ 318 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 319 /* 320 * Misc macros. 321 */ 322 #define IS_SCHEMA(node, type) \ 323 ((node != NULL) && (node->ns != NULL) && \ 324 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 325 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 326 327 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 328 329 /* 330 * Since we put the default/fixed values into the dict, we can 331 * use pointer comparison for those values. 332 * REMOVED: (xmlStrEqual((v1), (v2))) 333 */ 334 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 335 336 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 337 338 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 339 340 #define HFAILURE if (res == -1) goto exit_failure; 341 342 #define HERROR if (res != 0) goto exit_error; 343 344 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 345 /* 346 * Some flags used for various schema constraints. 347 */ 348 #define SUBSET_RESTRICTION 1<<0 349 #define SUBSET_EXTENSION 1<<1 350 #define SUBSET_SUBSTITUTION 1<<2 351 #define SUBSET_LIST 1<<3 352 #define SUBSET_UNION 1<<4 353 354 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 355 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 356 357 typedef struct _xmlSchemaItemList xmlSchemaItemList; 358 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 359 struct _xmlSchemaItemList { 360 void **items; /* used for dynamic addition of schemata */ 361 int nbItems; /* used for dynamic addition of schemata */ 362 int sizeItems; /* used for dynamic addition of schemata */ 363 }; 364 365 #define XML_SCHEMA_CTXT_PARSER 1 366 #define XML_SCHEMA_CTXT_VALIDATOR 2 367 368 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 369 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 370 struct _xmlSchemaAbstractCtxt { 371 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 372 void *dummy; /* Fix alignment issues */ 373 }; 374 375 typedef struct _xmlSchemaBucket xmlSchemaBucket; 376 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 377 378 #define XML_SCHEMA_SCHEMA_MAIN 0 379 #define XML_SCHEMA_SCHEMA_IMPORT 1 380 #define XML_SCHEMA_SCHEMA_INCLUDE 2 381 #define XML_SCHEMA_SCHEMA_REDEFINE 3 382 383 /** 384 * xmlSchemaSchemaRelation: 385 * 386 * Used to create a graph of schema relationships. 387 */ 388 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 389 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 390 struct _xmlSchemaSchemaRelation { 391 xmlSchemaSchemaRelationPtr next; 392 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 393 const xmlChar *importNamespace; 394 xmlSchemaBucketPtr bucket; 395 }; 396 397 #define XML_SCHEMA_BUCKET_MARKED 1<<0 398 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 399 400 struct _xmlSchemaBucket { 401 int type; 402 int flags; 403 const xmlChar *schemaLocation; 404 const xmlChar *origTargetNamespace; 405 const xmlChar *targetNamespace; 406 xmlDocPtr doc; 407 xmlSchemaSchemaRelationPtr relations; 408 int located; 409 int parsed; 410 int imported; 411 int preserveDoc; 412 xmlSchemaItemListPtr globals; /* Global components. */ 413 xmlSchemaItemListPtr locals; /* Local components. */ 414 }; 415 416 /** 417 * xmlSchemaImport: 418 * (extends xmlSchemaBucket) 419 * 420 * Reflects a schema. Holds some information 421 * about the schema and its toplevel components. Duplicate 422 * toplevel components are not checked at this level. 423 */ 424 typedef struct _xmlSchemaImport xmlSchemaImport; 425 typedef xmlSchemaImport *xmlSchemaImportPtr; 426 struct _xmlSchemaImport { 427 int type; /* Main OR import OR include. */ 428 int flags; 429 const xmlChar *schemaLocation; /* The URI of the schema document. */ 430 /* For chameleon includes, @origTargetNamespace will be NULL */ 431 const xmlChar *origTargetNamespace; 432 /* 433 * For chameleon includes, @targetNamespace will be the 434 * targetNamespace of the including schema. 435 */ 436 const xmlChar *targetNamespace; 437 xmlDocPtr doc; /* The schema node-tree. */ 438 /* @relations will hold any included/imported/redefined schemas. */ 439 xmlSchemaSchemaRelationPtr relations; 440 int located; 441 int parsed; 442 int imported; 443 int preserveDoc; 444 xmlSchemaItemListPtr globals; 445 xmlSchemaItemListPtr locals; 446 /* The imported schema. */ 447 xmlSchemaPtr schema; 448 }; 449 450 /* 451 * (extends xmlSchemaBucket) 452 */ 453 typedef struct _xmlSchemaInclude xmlSchemaInclude; 454 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 455 struct _xmlSchemaInclude { 456 int type; 457 int flags; 458 const xmlChar *schemaLocation; 459 const xmlChar *origTargetNamespace; 460 const xmlChar *targetNamespace; 461 xmlDocPtr doc; 462 xmlSchemaSchemaRelationPtr relations; 463 int located; 464 int parsed; 465 int imported; 466 int preserveDoc; 467 xmlSchemaItemListPtr globals; /* Global components. */ 468 xmlSchemaItemListPtr locals; /* Local components. */ 469 470 /* The owning main or import schema bucket. */ 471 xmlSchemaImportPtr ownerImport; 472 }; 473 474 /** 475 * xmlSchemaBasicItem: 476 * 477 * The abstract base type for schema components. 478 */ 479 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 480 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 481 struct _xmlSchemaBasicItem { 482 xmlSchemaTypeType type; 483 void *dummy; /* Fix alignment issues */ 484 }; 485 486 /** 487 * xmlSchemaAnnotItem: 488 * 489 * The abstract base type for annotated schema components. 490 * (Extends xmlSchemaBasicItem) 491 */ 492 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 493 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 494 struct _xmlSchemaAnnotItem { 495 xmlSchemaTypeType type; 496 xmlSchemaAnnotPtr annot; 497 }; 498 499 /** 500 * xmlSchemaTreeItem: 501 * 502 * The abstract base type for tree-like structured schema components. 503 * (Extends xmlSchemaAnnotItem) 504 */ 505 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 506 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 507 struct _xmlSchemaTreeItem { 508 xmlSchemaTypeType type; 509 xmlSchemaAnnotPtr annot; 510 xmlSchemaTreeItemPtr next; 511 xmlSchemaTreeItemPtr children; 512 }; 513 514 515 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 516 /** 517 * xmlSchemaAttributeUsePtr: 518 * 519 * The abstract base type for tree-like structured schema components. 520 * (Extends xmlSchemaTreeItem) 521 */ 522 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 523 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 524 struct _xmlSchemaAttributeUse { 525 xmlSchemaTypeType type; 526 xmlSchemaAnnotPtr annot; 527 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 528 /* 529 * The attr. decl. OR a QName-ref. to an attr. decl. OR 530 * a QName-ref. to an attribute group definition. 531 */ 532 xmlSchemaAttributePtr attrDecl; 533 534 int flags; 535 xmlNodePtr node; 536 int occurs; /* required, optional */ 537 const xmlChar * defValue; 538 xmlSchemaValPtr defVal; 539 }; 540 541 /** 542 * xmlSchemaAttributeUseProhibPtr: 543 * 544 * A helper component to reflect attribute prohibitions. 545 * (Extends xmlSchemaBasicItem) 546 */ 547 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 548 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 549 struct _xmlSchemaAttributeUseProhib { 550 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 551 xmlNodePtr node; 552 const xmlChar *name; 553 const xmlChar *targetNamespace; 554 int isRef; 555 }; 556 557 /** 558 * xmlSchemaRedef: 559 */ 560 typedef struct _xmlSchemaRedef xmlSchemaRedef; 561 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 562 struct _xmlSchemaRedef { 563 xmlSchemaRedefPtr next; 564 xmlSchemaBasicItemPtr item; /* The redefining component. */ 565 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 566 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 567 const xmlChar *refName; /* The name of the to-be-redefined component. */ 568 const xmlChar *refTargetNs; /* The target namespace of the 569 to-be-redefined comp. */ 570 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 571 }; 572 573 /** 574 * xmlSchemaConstructionCtxt: 575 */ 576 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 577 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 578 struct _xmlSchemaConstructionCtxt { 579 xmlSchemaPtr mainSchema; /* The main schema. */ 580 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 581 xmlDictPtr dict; 582 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 583 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 584 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 585 xmlSchemaItemListPtr pending; /* All Components of all schemas that 586 need to be fixed. */ 587 xmlHashTablePtr substGroups; 588 xmlSchemaRedefPtr redefs; 589 xmlSchemaRedefPtr lastRedef; 590 }; 591 592 #define XML_SCHEMAS_PARSE_ERROR 1 593 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 594 595 struct _xmlSchemaParserCtxt { 596 int type; 597 void *errCtxt; /* user specific error context */ 598 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 599 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 600 int err; 601 int nberrors; 602 xmlStructuredErrorFunc serror; 603 604 xmlSchemaConstructionCtxtPtr constructor; 605 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 606 607 /* xmlSchemaPtr topschema; */ 608 /* xmlHashTablePtr namespaces; */ 609 610 xmlSchemaPtr schema; /* The main schema in use */ 611 int counter; 612 613 const xmlChar *URL; 614 xmlDocPtr doc; 615 int preserve; /* Whether the doc should be freed */ 616 617 const char *buffer; 618 int size; 619 620 /* 621 * Used to build complex element content models 622 */ 623 xmlAutomataPtr am; 624 xmlAutomataStatePtr start; 625 xmlAutomataStatePtr end; 626 xmlAutomataStatePtr state; 627 628 xmlDictPtr dict; /* dictionary for interned string names */ 629 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 630 int options; 631 xmlSchemaValidCtxtPtr vctxt; 632 int isS4S; 633 int isRedefine; 634 int xsiAssemble; 635 int stop; /* If the parser should stop; i.e. a critical error. */ 636 const xmlChar *targetNamespace; 637 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 638 639 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 640 int redefCounter; /* Used for redefinitions. */ 641 xmlSchemaItemListPtr attrProhibs; 642 }; 643 644 /** 645 * xmlSchemaQNameRef: 646 * 647 * A component reference item (not a schema component) 648 * (Extends xmlSchemaBasicItem) 649 */ 650 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 651 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 652 struct _xmlSchemaQNameRef { 653 xmlSchemaTypeType type; 654 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 655 xmlSchemaTypeType itemType; 656 const xmlChar *name; 657 const xmlChar *targetNamespace; 658 xmlNodePtr node; 659 }; 660 661 /** 662 * xmlSchemaParticle: 663 * 664 * A particle component. 665 * (Extends xmlSchemaTreeItem) 666 */ 667 typedef struct _xmlSchemaParticle xmlSchemaParticle; 668 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 669 struct _xmlSchemaParticle { 670 xmlSchemaTypeType type; 671 xmlSchemaAnnotPtr annot; 672 xmlSchemaTreeItemPtr next; /* next particle */ 673 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 674 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 675 etc.) */ 676 int minOccurs; 677 int maxOccurs; 678 xmlNodePtr node; 679 }; 680 681 /** 682 * xmlSchemaModelGroup: 683 * 684 * A model group component. 685 * (Extends xmlSchemaTreeItem) 686 */ 687 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 688 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 689 struct _xmlSchemaModelGroup { 690 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 691 xmlSchemaAnnotPtr annot; 692 xmlSchemaTreeItemPtr next; /* not used */ 693 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 694 xmlNodePtr node; 695 }; 696 697 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 698 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 699 /** 700 * xmlSchemaModelGroupDef: 701 * 702 * A model group definition component. 703 * (Extends xmlSchemaTreeItem) 704 */ 705 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 706 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 707 struct _xmlSchemaModelGroupDef { 708 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 709 xmlSchemaAnnotPtr annot; 710 xmlSchemaTreeItemPtr next; /* not used */ 711 xmlSchemaTreeItemPtr children; /* the "model group" */ 712 const xmlChar *name; 713 const xmlChar *targetNamespace; 714 xmlNodePtr node; 715 int flags; 716 }; 717 718 typedef struct _xmlSchemaIDC xmlSchemaIDC; 719 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 720 721 /** 722 * xmlSchemaIDCSelect: 723 * 724 * The identity-constraint "field" and "selector" item, holding the 725 * XPath expression. 726 */ 727 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 728 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 729 struct _xmlSchemaIDCSelect { 730 xmlSchemaIDCSelectPtr next; 731 xmlSchemaIDCPtr idc; 732 int index; /* an index position if significant for IDC key-sequences */ 733 const xmlChar *xpath; /* the XPath expression */ 734 void *xpathComp; /* the compiled XPath expression */ 735 }; 736 737 /** 738 * xmlSchemaIDC: 739 * 740 * The identity-constraint definition component. 741 * (Extends xmlSchemaAnnotItem) 742 */ 743 744 struct _xmlSchemaIDC { 745 xmlSchemaTypeType type; 746 xmlSchemaAnnotPtr annot; 747 xmlSchemaIDCPtr next; 748 xmlNodePtr node; 749 const xmlChar *name; 750 const xmlChar *targetNamespace; 751 xmlSchemaIDCSelectPtr selector; 752 xmlSchemaIDCSelectPtr fields; 753 int nbFields; 754 xmlSchemaQNameRefPtr ref; 755 }; 756 757 /** 758 * xmlSchemaIDCAug: 759 * 760 * The augmented IDC information used for validation. 761 */ 762 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 763 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 764 struct _xmlSchemaIDCAug { 765 xmlSchemaIDCAugPtr next; /* next in a list */ 766 xmlSchemaIDCPtr def; /* the IDC definition */ 767 int keyrefDepth; /* the lowest tree level to which IDC 768 tables need to be bubbled upwards */ 769 }; 770 771 /** 772 * xmlSchemaPSVIIDCKeySequence: 773 * 774 * The key sequence of a node table item. 775 */ 776 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 777 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 778 struct _xmlSchemaPSVIIDCKey { 779 xmlSchemaTypePtr type; 780 xmlSchemaValPtr val; 781 }; 782 783 /** 784 * xmlSchemaPSVIIDCNode: 785 * 786 * The node table item of a node table. 787 */ 788 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 789 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 790 struct _xmlSchemaPSVIIDCNode { 791 xmlNodePtr node; 792 xmlSchemaPSVIIDCKeyPtr *keys; 793 int nodeLine; 794 int nodeQNameID; 795 796 }; 797 798 /** 799 * xmlSchemaPSVIIDCBinding: 800 * 801 * The identity-constraint binding item of the [identity-constraint table]. 802 */ 803 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 804 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 805 struct _xmlSchemaPSVIIDCBinding { 806 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 807 xmlSchemaIDCPtr definition; /* the IDC definition */ 808 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 809 int nbNodes; /* number of entries in the node table */ 810 int sizeNodes; /* size of the node table */ 811 xmlSchemaItemListPtr dupls; 812 }; 813 814 815 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 816 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 817 818 #define XPATH_STATE_OBJ_MATCHES -2 819 #define XPATH_STATE_OBJ_BLOCKED -3 820 821 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 822 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 823 824 /** 825 * xmlSchemaIDCStateObj: 826 * 827 * The state object used to evaluate XPath expressions. 828 */ 829 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 830 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 831 struct _xmlSchemaIDCStateObj { 832 int type; 833 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 834 int depth; /* depth of creation */ 835 int *history; /* list of (depth, state-id) tuples */ 836 int nbHistory; 837 int sizeHistory; 838 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 839 matcher */ 840 xmlSchemaIDCSelectPtr sel; 841 void *xpathCtxt; 842 }; 843 844 #define IDC_MATCHER 0 845 846 /** 847 * xmlSchemaIDCMatcher: 848 * 849 * Used to evaluate IDC selectors (and fields). 850 */ 851 struct _xmlSchemaIDCMatcher { 852 int type; 853 int depth; /* the tree depth at creation time */ 854 xmlSchemaIDCMatcherPtr next; /* next in the list */ 855 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 856 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 857 int idcType; 858 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 859 elements */ 860 int sizeKeySeqs; 861 xmlSchemaItemListPtr targets; /* list of target-node 862 (xmlSchemaPSVIIDCNodePtr) entries */ 863 }; 864 865 /* 866 * Element info flags. 867 */ 868 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 869 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 870 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 871 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 872 873 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 874 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 875 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 876 877 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 878 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 879 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 880 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 881 882 /** 883 * xmlSchemaNodeInfo: 884 * 885 * Holds information of an element node. 886 */ 887 struct _xmlSchemaNodeInfo { 888 int nodeType; 889 xmlNodePtr node; 890 int nodeLine; 891 const xmlChar *localName; 892 const xmlChar *nsName; 893 const xmlChar *value; 894 xmlSchemaValPtr val; /* the pre-computed value if any */ 895 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 896 897 int flags; /* combination of node info flags */ 898 899 int valNeeded; 900 int normVal; 901 902 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 903 int depth; 904 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 905 for the scope element*/ 906 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 907 element */ 908 xmlRegExecCtxtPtr regexCtxt; 909 910 const xmlChar **nsBindings; /* Namespace bindings on this element */ 911 int nbNsBindings; 912 int sizeNsBindings; 913 914 int hasKeyrefs; 915 int appliedXPath; /* Indicates that an XPath has been applied. */ 916 }; 917 918 #define XML_SCHEMAS_ATTR_UNKNOWN 1 919 #define XML_SCHEMAS_ATTR_ASSESSED 2 920 #define XML_SCHEMAS_ATTR_PROHIBITED 3 921 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 922 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 923 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 924 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 925 #define XML_SCHEMAS_ATTR_DEFAULT 8 926 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 927 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 928 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 929 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 930 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 931 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 932 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 933 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 934 #define XML_SCHEMAS_ATTR_META 17 935 /* 936 * @metaType values of xmlSchemaAttrInfo. 937 */ 938 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 939 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 940 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 941 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 942 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 943 944 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 945 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 946 struct _xmlSchemaAttrInfo { 947 int nodeType; 948 xmlNodePtr node; 949 int nodeLine; 950 const xmlChar *localName; 951 const xmlChar *nsName; 952 const xmlChar *value; 953 xmlSchemaValPtr val; /* the pre-computed value if any */ 954 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 955 int flags; /* combination of node info flags */ 956 957 xmlSchemaAttributePtr decl; /* the attribute declaration */ 958 xmlSchemaAttributeUsePtr use; /* the attribute use */ 959 int state; 960 int metaType; 961 const xmlChar *vcValue; /* the value constraint value */ 962 xmlSchemaNodeInfoPtr parent; 963 }; 964 965 966 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 967 /** 968 * xmlSchemaValidCtxt: 969 * 970 * A Schemas validation context 971 */ 972 struct _xmlSchemaValidCtxt { 973 int type; 974 void *errCtxt; /* user specific data block */ 975 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 976 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 977 xmlStructuredErrorFunc serror; 978 979 xmlSchemaPtr schema; /* The schema in use */ 980 xmlDocPtr doc; 981 xmlParserInputBufferPtr input; 982 xmlCharEncoding enc; 983 xmlSAXHandlerPtr sax; 984 xmlParserCtxtPtr parserCtxt; 985 void *user_data; /* TODO: What is this for? */ 986 char *filename; 987 988 int err; 989 int nberrors; 990 991 xmlNodePtr node; 992 xmlNodePtr cur; 993 /* xmlSchemaTypePtr type; */ 994 995 xmlRegExecCtxtPtr regexp; 996 xmlSchemaValPtr value; 997 998 int valueWS; 999 int options; 1000 xmlNodePtr validationRoot; 1001 xmlSchemaParserCtxtPtr pctxt; 1002 int xsiAssemble; 1003 1004 int depth; 1005 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 1006 int sizeElemInfos; 1007 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1008 1009 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1010 1011 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1012 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1013 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1014 1015 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1016 int nbIdcNodes; 1017 int sizeIdcNodes; 1018 1019 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1020 int nbIdcKeys; 1021 int sizeIdcKeys; 1022 1023 int flags; 1024 1025 xmlDictPtr dict; 1026 1027 #ifdef LIBXML_READER_ENABLED 1028 xmlTextReaderPtr reader; 1029 #endif 1030 1031 xmlSchemaAttrInfoPtr *attrInfos; 1032 int nbAttrInfos; 1033 int sizeAttrInfos; 1034 1035 int skipDepth; 1036 xmlSchemaItemListPtr nodeQNames; 1037 int hasKeyrefs; 1038 int createIDCNodeTables; 1039 int psviExposeIDCNodeTables; 1040 1041 /* Locator for error reporting in streaming mode */ 1042 xmlSchemaValidityLocatorFunc locFunc; 1043 void *locCtxt; 1044 }; 1045 1046 /** 1047 * xmlSchemaSubstGroup: 1048 * 1049 * 1050 */ 1051 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1052 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1053 struct _xmlSchemaSubstGroup { 1054 xmlSchemaElementPtr head; 1055 xmlSchemaItemListPtr members; 1056 }; 1057 1058 /************************************************************************ 1059 * * 1060 * Some predeclarations * 1061 * * 1062 ************************************************************************/ 1063 1064 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1065 xmlSchemaPtr schema, 1066 xmlNodePtr node); 1067 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1068 xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070 static int 1071 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1072 xmlSchemaAbstractCtxtPtr ctxt); 1073 static const xmlChar * 1074 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1075 static int 1076 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1077 xmlNodePtr node); 1078 static int 1079 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1080 xmlSchemaParserCtxtPtr ctxt); 1081 static void 1082 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1083 static xmlSchemaWhitespaceValueType 1084 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1085 static xmlSchemaTreeItemPtr 1086 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1087 xmlNodePtr node, xmlSchemaTypeType type, 1088 int withParticle); 1089 static const xmlChar * 1090 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1091 static xmlSchemaTypeLinkPtr 1092 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1093 static void 1094 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1095 const char *funcName, 1096 const char *message) LIBXML_ATTR_FORMAT(3,0); 1097 static int 1098 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1099 xmlSchemaTypePtr type, 1100 xmlSchemaTypePtr baseType, 1101 int subset); 1102 static void 1103 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1104 xmlSchemaParserCtxtPtr ctxt); 1105 static void 1106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1107 static xmlSchemaQNameRefPtr 1108 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1109 xmlSchemaPtr schema, 1110 xmlNodePtr node); 1111 1112 /************************************************************************ 1113 * * 1114 * Helper functions * 1115 * * 1116 ************************************************************************/ 1117 1118 /** 1119 * xmlSchemaItemTypeToStr: 1120 * @type: the type of the schema item 1121 * 1122 * Returns the component name of a schema item. 1123 */ 1124 static const xmlChar * 1125 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1126 { 1127 switch (type) { 1128 case XML_SCHEMA_TYPE_BASIC: 1129 return(BAD_CAST "simple type definition"); 1130 case XML_SCHEMA_TYPE_SIMPLE: 1131 return(BAD_CAST "simple type definition"); 1132 case XML_SCHEMA_TYPE_COMPLEX: 1133 return(BAD_CAST "complex type definition"); 1134 case XML_SCHEMA_TYPE_ELEMENT: 1135 return(BAD_CAST "element declaration"); 1136 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1137 return(BAD_CAST "attribute use"); 1138 case XML_SCHEMA_TYPE_ATTRIBUTE: 1139 return(BAD_CAST "attribute declaration"); 1140 case XML_SCHEMA_TYPE_GROUP: 1141 return(BAD_CAST "model group definition"); 1142 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1143 return(BAD_CAST "attribute group definition"); 1144 case XML_SCHEMA_TYPE_NOTATION: 1145 return(BAD_CAST "notation declaration"); 1146 case XML_SCHEMA_TYPE_SEQUENCE: 1147 return(BAD_CAST "model group (sequence)"); 1148 case XML_SCHEMA_TYPE_CHOICE: 1149 return(BAD_CAST "model group (choice)"); 1150 case XML_SCHEMA_TYPE_ALL: 1151 return(BAD_CAST "model group (all)"); 1152 case XML_SCHEMA_TYPE_PARTICLE: 1153 return(BAD_CAST "particle"); 1154 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1155 return(BAD_CAST "unique identity-constraint"); 1156 /* return(BAD_CAST "IDC (unique)"); */ 1157 case XML_SCHEMA_TYPE_IDC_KEY: 1158 return(BAD_CAST "key identity-constraint"); 1159 /* return(BAD_CAST "IDC (key)"); */ 1160 case XML_SCHEMA_TYPE_IDC_KEYREF: 1161 return(BAD_CAST "keyref identity-constraint"); 1162 /* return(BAD_CAST "IDC (keyref)"); */ 1163 case XML_SCHEMA_TYPE_ANY: 1164 return(BAD_CAST "wildcard (any)"); 1165 case XML_SCHEMA_EXTRA_QNAMEREF: 1166 return(BAD_CAST "[helper component] QName reference"); 1167 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1168 return(BAD_CAST "[helper component] attribute use prohibition"); 1169 default: 1170 return(BAD_CAST "Not a schema component"); 1171 } 1172 } 1173 1174 /** 1175 * xmlSchemaGetComponentTypeStr: 1176 * @type: the type of the schema item 1177 * 1178 * Returns the component name of a schema item. 1179 */ 1180 static const xmlChar * 1181 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1182 { 1183 switch (item->type) { 1184 case XML_SCHEMA_TYPE_BASIC: 1185 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1186 return(BAD_CAST "complex type definition"); 1187 else 1188 return(BAD_CAST "simple type definition"); 1189 default: 1190 return(xmlSchemaItemTypeToStr(item->type)); 1191 } 1192 } 1193 1194 /** 1195 * xmlSchemaGetComponentNode: 1196 * @item: a schema component 1197 * 1198 * Returns node associated with the schema component. 1199 * NOTE that such a node need not be available; plus, a component's 1200 * node need not to reflect the component directly, since there is no 1201 * one-to-one relationship between the XML Schema representation and 1202 * the component representation. 1203 */ 1204 static xmlNodePtr 1205 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1206 { 1207 switch (item->type) { 1208 case XML_SCHEMA_TYPE_ELEMENT: 1209 return (((xmlSchemaElementPtr) item)->node); 1210 case XML_SCHEMA_TYPE_ATTRIBUTE: 1211 return (((xmlSchemaAttributePtr) item)->node); 1212 case XML_SCHEMA_TYPE_COMPLEX: 1213 case XML_SCHEMA_TYPE_SIMPLE: 1214 return (((xmlSchemaTypePtr) item)->node); 1215 case XML_SCHEMA_TYPE_ANY: 1216 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1217 return (((xmlSchemaWildcardPtr) item)->node); 1218 case XML_SCHEMA_TYPE_PARTICLE: 1219 return (((xmlSchemaParticlePtr) item)->node); 1220 case XML_SCHEMA_TYPE_SEQUENCE: 1221 case XML_SCHEMA_TYPE_CHOICE: 1222 case XML_SCHEMA_TYPE_ALL: 1223 return (((xmlSchemaModelGroupPtr) item)->node); 1224 case XML_SCHEMA_TYPE_GROUP: 1225 return (((xmlSchemaModelGroupDefPtr) item)->node); 1226 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1227 return (((xmlSchemaAttributeGroupPtr) item)->node); 1228 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1229 case XML_SCHEMA_TYPE_IDC_KEY: 1230 case XML_SCHEMA_TYPE_IDC_KEYREF: 1231 return (((xmlSchemaIDCPtr) item)->node); 1232 case XML_SCHEMA_EXTRA_QNAMEREF: 1233 return(((xmlSchemaQNameRefPtr) item)->node); 1234 /* TODO: What to do with NOTATIONs? 1235 case XML_SCHEMA_TYPE_NOTATION: 1236 return (((xmlSchemaNotationPtr) item)->node); 1237 */ 1238 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1239 return (((xmlSchemaAttributeUsePtr) item)->node); 1240 default: 1241 return (NULL); 1242 } 1243 } 1244 1245 #if 0 1246 /** 1247 * xmlSchemaGetNextComponent: 1248 * @item: a schema component 1249 * 1250 * Returns the next sibling of the schema component. 1251 */ 1252 static xmlSchemaBasicItemPtr 1253 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1254 { 1255 switch (item->type) { 1256 case XML_SCHEMA_TYPE_ELEMENT: 1257 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1258 case XML_SCHEMA_TYPE_ATTRIBUTE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1260 case XML_SCHEMA_TYPE_COMPLEX: 1261 case XML_SCHEMA_TYPE_SIMPLE: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1263 case XML_SCHEMA_TYPE_ANY: 1264 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_PARTICLE: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1268 case XML_SCHEMA_TYPE_SEQUENCE: 1269 case XML_SCHEMA_TYPE_CHOICE: 1270 case XML_SCHEMA_TYPE_ALL: 1271 return (NULL); 1272 case XML_SCHEMA_TYPE_GROUP: 1273 return (NULL); 1274 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1275 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1276 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1277 case XML_SCHEMA_TYPE_IDC_KEY: 1278 case XML_SCHEMA_TYPE_IDC_KEYREF: 1279 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1280 default: 1281 return (NULL); 1282 } 1283 } 1284 #endif 1285 1286 1287 /** 1288 * xmlSchemaFormatQName: 1289 * @buf: the string buffer 1290 * @namespaceName: the namespace name 1291 * @localName: the local name 1292 * 1293 * Returns the given QName in the format "{namespaceName}localName" or 1294 * just "localName" if @namespaceName is NULL. 1295 * 1296 * Returns the localName if @namespaceName is NULL, a formatted 1297 * string otherwise. 1298 */ 1299 static const xmlChar* 1300 xmlSchemaFormatQName(xmlChar **buf, 1301 const xmlChar *namespaceName, 1302 const xmlChar *localName) 1303 { 1304 FREE_AND_NULL(*buf) 1305 if (namespaceName != NULL) { 1306 *buf = xmlStrdup(BAD_CAST "{"); 1307 *buf = xmlStrcat(*buf, namespaceName); 1308 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1309 } 1310 if (localName != NULL) { 1311 if (namespaceName == NULL) 1312 return(localName); 1313 *buf = xmlStrcat(*buf, localName); 1314 } else { 1315 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1316 } 1317 return ((const xmlChar *) *buf); 1318 } 1319 1320 static const xmlChar* 1321 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1322 { 1323 if (ns != NULL) 1324 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1325 else 1326 return (xmlSchemaFormatQName(buf, NULL, localName)); 1327 } 1328 1329 static const xmlChar * 1330 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1331 { 1332 switch (item->type) { 1333 case XML_SCHEMA_TYPE_ELEMENT: 1334 return (((xmlSchemaElementPtr) item)->name); 1335 case XML_SCHEMA_TYPE_ATTRIBUTE: 1336 return (((xmlSchemaAttributePtr) item)->name); 1337 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1338 return (((xmlSchemaAttributeGroupPtr) item)->name); 1339 case XML_SCHEMA_TYPE_BASIC: 1340 case XML_SCHEMA_TYPE_SIMPLE: 1341 case XML_SCHEMA_TYPE_COMPLEX: 1342 return (((xmlSchemaTypePtr) item)->name); 1343 case XML_SCHEMA_TYPE_GROUP: 1344 return (((xmlSchemaModelGroupDefPtr) item)->name); 1345 case XML_SCHEMA_TYPE_IDC_KEY: 1346 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1347 case XML_SCHEMA_TYPE_IDC_KEYREF: 1348 return (((xmlSchemaIDCPtr) item)->name); 1349 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1350 if (WXS_ATTRUSE_DECL(item) != NULL) { 1351 return(xmlSchemaGetComponentName( 1352 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1353 } else 1354 return(NULL); 1355 case XML_SCHEMA_EXTRA_QNAMEREF: 1356 return (((xmlSchemaQNameRefPtr) item)->name); 1357 case XML_SCHEMA_TYPE_NOTATION: 1358 return (((xmlSchemaNotationPtr) item)->name); 1359 default: 1360 /* 1361 * Other components cannot have names. 1362 */ 1363 break; 1364 } 1365 return (NULL); 1366 } 1367 1368 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1369 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1370 /* 1371 static const xmlChar * 1372 xmlSchemaGetQNameRefName(void *ref) 1373 { 1374 return(((xmlSchemaQNameRefPtr) ref)->name); 1375 } 1376 1377 static const xmlChar * 1378 xmlSchemaGetQNameRefTargetNs(void *ref) 1379 { 1380 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1381 } 1382 */ 1383 1384 static const xmlChar * 1385 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1386 { 1387 switch (item->type) { 1388 case XML_SCHEMA_TYPE_ELEMENT: 1389 return (((xmlSchemaElementPtr) item)->targetNamespace); 1390 case XML_SCHEMA_TYPE_ATTRIBUTE: 1391 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1393 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1394 case XML_SCHEMA_TYPE_BASIC: 1395 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1396 case XML_SCHEMA_TYPE_SIMPLE: 1397 case XML_SCHEMA_TYPE_COMPLEX: 1398 return (((xmlSchemaTypePtr) item)->targetNamespace); 1399 case XML_SCHEMA_TYPE_GROUP: 1400 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_IDC_KEY: 1402 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1403 case XML_SCHEMA_TYPE_IDC_KEYREF: 1404 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1405 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1406 if (WXS_ATTRUSE_DECL(item) != NULL) { 1407 return(xmlSchemaGetComponentTargetNs( 1408 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1409 } 1410 /* TODO: Will returning NULL break something? */ 1411 break; 1412 case XML_SCHEMA_EXTRA_QNAMEREF: 1413 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1414 case XML_SCHEMA_TYPE_NOTATION: 1415 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1416 default: 1417 /* 1418 * Other components cannot have names. 1419 */ 1420 break; 1421 } 1422 return (NULL); 1423 } 1424 1425 static const xmlChar* 1426 xmlSchemaGetComponentQName(xmlChar **buf, 1427 void *item) 1428 { 1429 return (xmlSchemaFormatQName(buf, 1430 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1431 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1432 } 1433 1434 static const xmlChar* 1435 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1436 { 1437 xmlChar *str = NULL; 1438 1439 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1440 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1441 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1442 (xmlSchemaBasicItemPtr) item)); 1443 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1444 FREE_AND_NULL(str); 1445 return(*buf); 1446 } 1447 1448 static const xmlChar* 1449 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1450 { 1451 return(xmlSchemaGetComponentDesignation(buf, idc)); 1452 } 1453 1454 /** 1455 * xmlSchemaWildcardPCToString: 1456 * @pc: the type of processContents 1457 * 1458 * Returns a string representation of the type of 1459 * processContents. 1460 */ 1461 static const xmlChar * 1462 xmlSchemaWildcardPCToString(int pc) 1463 { 1464 switch (pc) { 1465 case XML_SCHEMAS_ANY_SKIP: 1466 return (BAD_CAST "skip"); 1467 case XML_SCHEMAS_ANY_LAX: 1468 return (BAD_CAST "lax"); 1469 case XML_SCHEMAS_ANY_STRICT: 1470 return (BAD_CAST "strict"); 1471 default: 1472 return (BAD_CAST "invalid process contents"); 1473 } 1474 } 1475 1476 /** 1477 * xmlSchemaGetCanonValueWhtspExt: 1478 * @val: the precomputed value 1479 * @retValue: the returned value 1480 * @ws: the whitespace type of the value 1481 * 1482 * Get a the canonical representation of the value. 1483 * The caller has to free the returned retValue. 1484 * 1485 * Returns 0 if the value could be built and -1 in case of 1486 * API errors or if the value type is not supported yet. 1487 */ 1488 static int 1489 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1490 xmlSchemaWhitespaceValueType ws, 1491 xmlChar **retValue) 1492 { 1493 int list; 1494 xmlSchemaValType valType; 1495 const xmlChar *value, *value2 = NULL; 1496 1497 1498 if ((retValue == NULL) || (val == NULL)) 1499 return (-1); 1500 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1501 *retValue = NULL; 1502 do { 1503 value = NULL; 1504 valType = xmlSchemaGetValType(val); 1505 switch (valType) { 1506 case XML_SCHEMAS_STRING: 1507 case XML_SCHEMAS_NORMSTRING: 1508 case XML_SCHEMAS_ANYSIMPLETYPE: 1509 value = xmlSchemaValueGetAsString(val); 1510 if (value != NULL) { 1511 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1512 value2 = xmlSchemaCollapseString(value); 1513 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1514 value2 = xmlSchemaWhiteSpaceReplace(value); 1515 if (value2 != NULL) 1516 value = value2; 1517 } 1518 break; 1519 default: 1520 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1521 if (value2 != NULL) 1522 xmlFree((xmlChar *) value2); 1523 goto internal_error; 1524 } 1525 value = value2; 1526 } 1527 if (*retValue == NULL) 1528 if (value == NULL) { 1529 if (! list) 1530 *retValue = xmlStrdup(BAD_CAST ""); 1531 } else 1532 *retValue = xmlStrdup(value); 1533 else if (value != NULL) { 1534 /* List. */ 1535 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1536 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1537 } 1538 FREE_AND_NULL(value2) 1539 val = xmlSchemaValueGetNext(val); 1540 } while (val != NULL); 1541 1542 return (0); 1543 internal_error: 1544 if (*retValue != NULL) 1545 xmlFree((xmlChar *) (*retValue)); 1546 if (value2 != NULL) 1547 xmlFree((xmlChar *) value2); 1548 return (-1); 1549 } 1550 1551 /** 1552 * xmlSchemaFormatItemForReport: 1553 * @buf: the string buffer 1554 * @itemDes: the designation of the item 1555 * @itemName: the name of the item 1556 * @item: the item as an object 1557 * @itemNode: the node of the item 1558 * @local: the local name 1559 * @parsing: if the function is used during the parse 1560 * 1561 * Returns a representation of the given item used 1562 * for error reports. 1563 * 1564 * The following order is used to build the resulting 1565 * designation if the arguments are not NULL: 1566 * 1a. If itemDes not NULL -> itemDes 1567 * 1b. If (itemDes not NULL) and (itemName not NULL) 1568 * -> itemDes + itemName 1569 * 2. If the preceding was NULL and (item not NULL) -> item 1570 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1571 * 1572 * If the itemNode is an attribute node, the name of the attribute 1573 * will be appended to the result. 1574 * 1575 * Returns the formatted string and sets @buf to the resulting value. 1576 */ 1577 static xmlChar* 1578 xmlSchemaFormatItemForReport(xmlChar **buf, 1579 const xmlChar *itemDes, 1580 xmlSchemaBasicItemPtr item, 1581 xmlNodePtr itemNode) 1582 { 1583 xmlChar *str = NULL; 1584 int named = 1; 1585 1586 if (*buf != NULL) { 1587 xmlFree(*buf); 1588 *buf = NULL; 1589 } 1590 1591 if (itemDes != NULL) { 1592 *buf = xmlStrdup(itemDes); 1593 } else if (item != NULL) { 1594 switch (item->type) { 1595 case XML_SCHEMA_TYPE_BASIC: { 1596 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1597 1598 if (WXS_IS_ATOMIC(type)) 1599 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1600 else if (WXS_IS_LIST(type)) 1601 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1602 else if (WXS_IS_UNION(type)) 1603 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1604 else 1605 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1606 *buf = xmlStrcat(*buf, type->name); 1607 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1608 } 1609 break; 1610 case XML_SCHEMA_TYPE_SIMPLE: { 1611 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1612 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrdup(BAD_CAST""); 1615 } else { 1616 *buf = xmlStrdup(BAD_CAST "local "); 1617 } 1618 if (WXS_IS_ATOMIC(type)) 1619 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1620 else if (WXS_IS_LIST(type)) 1621 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1622 else if (WXS_IS_UNION(type)) 1623 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1624 else 1625 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1626 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1627 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1628 *buf = xmlStrcat(*buf, type->name); 1629 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1630 } 1631 } 1632 break; 1633 case XML_SCHEMA_TYPE_COMPLEX: { 1634 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1635 1636 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1637 *buf = xmlStrdup(BAD_CAST ""); 1638 else 1639 *buf = xmlStrdup(BAD_CAST "local "); 1640 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1641 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1642 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1643 *buf = xmlStrcat(*buf, type->name); 1644 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1645 } 1646 } 1647 break; 1648 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1649 xmlSchemaAttributeUsePtr ause; 1650 1651 ause = WXS_ATTR_USE_CAST item; 1652 *buf = xmlStrdup(BAD_CAST "attribute use "); 1653 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1654 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1655 *buf = xmlStrcat(*buf, 1656 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1657 FREE_AND_NULL(str) 1658 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1659 } else { 1660 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1661 } 1662 } 1663 break; 1664 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1665 xmlSchemaAttributePtr attr; 1666 1667 attr = (xmlSchemaAttributePtr) item; 1668 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1669 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1670 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1671 attr->targetNamespace, attr->name)); 1672 FREE_AND_NULL(str) 1673 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1674 } 1675 break; 1676 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1677 xmlSchemaGetComponentDesignation(buf, item); 1678 break; 1679 case XML_SCHEMA_TYPE_ELEMENT: { 1680 xmlSchemaElementPtr elem; 1681 1682 elem = (xmlSchemaElementPtr) item; 1683 *buf = xmlStrdup(BAD_CAST "element decl."); 1684 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1685 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1686 elem->targetNamespace, elem->name)); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 } 1689 break; 1690 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1691 case XML_SCHEMA_TYPE_IDC_KEY: 1692 case XML_SCHEMA_TYPE_IDC_KEYREF: 1693 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1694 *buf = xmlStrdup(BAD_CAST "unique '"); 1695 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1696 *buf = xmlStrdup(BAD_CAST "key '"); 1697 else 1698 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1699 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1700 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1701 break; 1702 case XML_SCHEMA_TYPE_ANY: 1703 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1704 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1705 ((xmlSchemaWildcardPtr) item)->processContents)); 1706 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1707 break; 1708 case XML_SCHEMA_FACET_MININCLUSIVE: 1709 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1710 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1711 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1712 case XML_SCHEMA_FACET_TOTALDIGITS: 1713 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1714 case XML_SCHEMA_FACET_PATTERN: 1715 case XML_SCHEMA_FACET_ENUMERATION: 1716 case XML_SCHEMA_FACET_WHITESPACE: 1717 case XML_SCHEMA_FACET_LENGTH: 1718 case XML_SCHEMA_FACET_MAXLENGTH: 1719 case XML_SCHEMA_FACET_MINLENGTH: 1720 *buf = xmlStrdup(BAD_CAST "facet '"); 1721 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1722 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1723 break; 1724 case XML_SCHEMA_TYPE_GROUP: { 1725 *buf = xmlStrdup(BAD_CAST "model group def."); 1726 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1727 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1728 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1729 FREE_AND_NULL(str) 1730 } 1731 break; 1732 case XML_SCHEMA_TYPE_SEQUENCE: 1733 case XML_SCHEMA_TYPE_CHOICE: 1734 case XML_SCHEMA_TYPE_ALL: 1735 case XML_SCHEMA_TYPE_PARTICLE: 1736 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1737 break; 1738 case XML_SCHEMA_TYPE_NOTATION: { 1739 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1740 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1741 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1742 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1743 FREE_AND_NULL(str); 1744 } 1745 /* Falls through. */ 1746 default: 1747 named = 0; 1748 } 1749 } else 1750 named = 0; 1751 1752 if ((named == 0) && (itemNode != NULL)) { 1753 xmlNodePtr elem; 1754 1755 if (itemNode->type == XML_ATTRIBUTE_NODE) 1756 elem = itemNode->parent; 1757 else 1758 elem = itemNode; 1759 *buf = xmlStrdup(BAD_CAST "Element '"); 1760 if (elem->ns != NULL) { 1761 *buf = xmlStrcat(*buf, 1762 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1763 FREE_AND_NULL(str) 1764 } else 1765 *buf = xmlStrcat(*buf, elem->name); 1766 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1767 1768 } 1769 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1770 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1771 if (itemNode->ns != NULL) { 1772 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1773 itemNode->ns->href, itemNode->name)); 1774 FREE_AND_NULL(str) 1775 } else 1776 *buf = xmlStrcat(*buf, itemNode->name); 1777 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1778 } 1779 FREE_AND_NULL(str) 1780 1781 return (xmlEscapeFormatString(buf)); 1782 } 1783 1784 /** 1785 * xmlSchemaFormatFacetEnumSet: 1786 * @buf: the string buffer 1787 * @type: the type holding the enumeration facets 1788 * 1789 * Builds a string consisting of all enumeration elements. 1790 * 1791 * Returns a string of all enumeration elements. 1792 */ 1793 static const xmlChar * 1794 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1795 xmlChar **buf, xmlSchemaTypePtr type) 1796 { 1797 xmlSchemaFacetPtr facet; 1798 xmlSchemaWhitespaceValueType ws; 1799 xmlChar *value = NULL; 1800 int res, found = 0; 1801 1802 if (*buf != NULL) 1803 xmlFree(*buf); 1804 *buf = NULL; 1805 1806 do { 1807 /* 1808 * Use the whitespace type of the base type. 1809 */ 1810 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1811 for (facet = type->facets; facet != NULL; facet = facet->next) { 1812 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1813 continue; 1814 found = 1; 1815 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1816 ws, &value); 1817 if (res == -1) { 1818 xmlSchemaInternalErr(actxt, 1819 "xmlSchemaFormatFacetEnumSet", 1820 "compute the canonical lexical representation"); 1821 if (*buf != NULL) 1822 xmlFree(*buf); 1823 *buf = NULL; 1824 return (NULL); 1825 } 1826 if (*buf == NULL) 1827 *buf = xmlStrdup(BAD_CAST "'"); 1828 else 1829 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1830 *buf = xmlStrcat(*buf, BAD_CAST value); 1831 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1832 if (value != NULL) { 1833 xmlFree((xmlChar *)value); 1834 value = NULL; 1835 } 1836 } 1837 /* 1838 * The enumeration facet of a type restricts the enumeration 1839 * facet of the ancestor type; i.e., such restricted enumerations 1840 * do not belong to the set of the given type. Thus we break 1841 * on the first found enumeration. 1842 */ 1843 if (found) 1844 break; 1845 type = type->baseType; 1846 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1847 1848 return ((const xmlChar *) *buf); 1849 } 1850 1851 /************************************************************************ 1852 * * 1853 * Error functions * 1854 * * 1855 ************************************************************************/ 1856 1857 #if 0 1858 static void 1859 xmlSchemaErrMemory(const char *msg) 1860 { 1861 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1862 msg); 1863 } 1864 #endif 1865 1866 static void 1867 xmlSchemaPSimpleErr(const char *msg) 1868 { 1869 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1870 msg); 1871 } 1872 1873 /** 1874 * xmlSchemaPErrMemory: 1875 * @node: a context node 1876 * @extra: extra informations 1877 * 1878 * Handle an out of memory condition 1879 */ 1880 static void 1881 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1882 const char *extra, xmlNodePtr node) 1883 { 1884 if (ctxt != NULL) 1885 ctxt->nberrors++; 1886 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1887 extra); 1888 } 1889 1890 /** 1891 * xmlSchemaPErr: 1892 * @ctxt: the parsing context 1893 * @node: the context node 1894 * @error: the error code 1895 * @msg: the error message 1896 * @str1: extra data 1897 * @str2: extra data 1898 * 1899 * Handle a parser error 1900 */ 1901 static void LIBXML_ATTR_FORMAT(4,0) 1902 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1903 const char *msg, const xmlChar * str1, const xmlChar * str2) 1904 { 1905 xmlGenericErrorFunc channel = NULL; 1906 xmlStructuredErrorFunc schannel = NULL; 1907 void *data = NULL; 1908 1909 if (ctxt != NULL) { 1910 ctxt->nberrors++; 1911 ctxt->err = error; 1912 channel = ctxt->error; 1913 data = ctxt->errCtxt; 1914 schannel = ctxt->serror; 1915 } 1916 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1917 error, XML_ERR_ERROR, NULL, 0, 1918 (const char *) str1, (const char *) str2, NULL, 0, 0, 1919 msg, str1, str2); 1920 } 1921 1922 /** 1923 * xmlSchemaPErr2: 1924 * @ctxt: the parsing context 1925 * @node: the context node 1926 * @node: the current child 1927 * @error: the error code 1928 * @msg: the error message 1929 * @str1: extra data 1930 * @str2: extra data 1931 * 1932 * Handle a parser error 1933 */ 1934 static void LIBXML_ATTR_FORMAT(5,0) 1935 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1936 xmlNodePtr child, int error, 1937 const char *msg, const xmlChar * str1, const xmlChar * str2) 1938 { 1939 if (child != NULL) 1940 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1941 else 1942 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1943 } 1944 1945 1946 /** 1947 * xmlSchemaPErrExt: 1948 * @ctxt: the parsing context 1949 * @node: the context node 1950 * @error: the error code 1951 * @strData1: extra data 1952 * @strData2: extra data 1953 * @strData3: extra data 1954 * @msg: the message 1955 * @str1: extra parameter for the message display 1956 * @str2: extra parameter for the message display 1957 * @str3: extra parameter for the message display 1958 * @str4: extra parameter for the message display 1959 * @str5: extra parameter for the message display 1960 * 1961 * Handle a parser error 1962 */ 1963 static void LIBXML_ATTR_FORMAT(7,0) 1964 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1965 const xmlChar * strData1, const xmlChar * strData2, 1966 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1967 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1968 const xmlChar * str5) 1969 { 1970 1971 xmlGenericErrorFunc channel = NULL; 1972 xmlStructuredErrorFunc schannel = NULL; 1973 void *data = NULL; 1974 1975 if (ctxt != NULL) { 1976 ctxt->nberrors++; 1977 ctxt->err = error; 1978 channel = ctxt->error; 1979 data = ctxt->errCtxt; 1980 schannel = ctxt->serror; 1981 } 1982 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1983 error, XML_ERR_ERROR, NULL, 0, 1984 (const char *) strData1, (const char *) strData2, 1985 (const char *) strData3, 0, 0, msg, str1, str2, 1986 str3, str4, str5); 1987 } 1988 1989 /************************************************************************ 1990 * * 1991 * Allround error functions * 1992 * * 1993 ************************************************************************/ 1994 1995 /** 1996 * xmlSchemaVTypeErrMemory: 1997 * @node: a context node 1998 * @extra: extra informations 1999 * 2000 * Handle an out of memory condition 2001 */ 2002 static void 2003 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 2004 const char *extra, xmlNodePtr node) 2005 { 2006 if (ctxt != NULL) { 2007 ctxt->nberrors++; 2008 ctxt->err = XML_SCHEMAV_INTERNAL; 2009 } 2010 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2011 extra); 2012 } 2013 2014 static void LIBXML_ATTR_FORMAT(2,0) 2015 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2016 const char *msg, const xmlChar *str) 2017 { 2018 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2019 msg, (const char *) str); 2020 } 2021 2022 #define WXS_ERROR_TYPE_ERROR 1 2023 #define WXS_ERROR_TYPE_WARNING 2 2024 /** 2025 * xmlSchemaErr4Line: 2026 * @ctxt: the validation context 2027 * @errorLevel: the error level 2028 * @error: the error code 2029 * @node: the context node 2030 * @line: the line number 2031 * @msg: the error message 2032 * @str1: extra data 2033 * @str2: extra data 2034 * @str3: extra data 2035 * @str4: extra data 2036 * 2037 * Handle a validation error 2038 */ 2039 static void LIBXML_ATTR_FORMAT(6,0) 2040 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2041 xmlErrorLevel errorLevel, 2042 int error, xmlNodePtr node, int line, const char *msg, 2043 const xmlChar *str1, const xmlChar *str2, 2044 const xmlChar *str3, const xmlChar *str4) 2045 { 2046 xmlStructuredErrorFunc schannel = NULL; 2047 xmlGenericErrorFunc channel = NULL; 2048 void *data = NULL; 2049 2050 if (ctxt != NULL) { 2051 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2052 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2053 const char *file = NULL; 2054 int col = 0; 2055 if (errorLevel != XML_ERR_WARNING) { 2056 vctxt->nberrors++; 2057 vctxt->err = error; 2058 channel = vctxt->error; 2059 } else { 2060 channel = vctxt->warning; 2061 } 2062 schannel = vctxt->serror; 2063 data = vctxt->errCtxt; 2064 2065 /* 2066 * Error node. If we specify a line number, then 2067 * do not channel any node to the error function. 2068 */ 2069 if (line == 0) { 2070 if ((node == NULL) && 2071 (vctxt->depth >= 0) && 2072 (vctxt->inode != NULL)) { 2073 node = vctxt->inode->node; 2074 } 2075 /* 2076 * Get filename and line if no node-tree. 2077 */ 2078 if ((node == NULL) && 2079 (vctxt->parserCtxt != NULL) && 2080 (vctxt->parserCtxt->input != NULL)) { 2081 file = vctxt->parserCtxt->input->filename; 2082 line = vctxt->parserCtxt->input->line; 2083 col = vctxt->parserCtxt->input->col; 2084 } 2085 } else { 2086 /* 2087 * Override the given node's (if any) position 2088 * and channel only the given line number. 2089 */ 2090 node = NULL; 2091 /* 2092 * Get filename. 2093 */ 2094 if (vctxt->doc != NULL) 2095 file = (const char *) vctxt->doc->URL; 2096 else if ((vctxt->parserCtxt != NULL) && 2097 (vctxt->parserCtxt->input != NULL)) 2098 file = vctxt->parserCtxt->input->filename; 2099 } 2100 if (vctxt->locFunc != NULL) { 2101 if ((file == NULL) || (line == 0)) { 2102 unsigned long l; 2103 const char *f; 2104 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2105 if (file == NULL) 2106 file = f; 2107 if (line == 0) 2108 line = (int) l; 2109 } 2110 } 2111 if ((file == NULL) && (vctxt->filename != NULL)) 2112 file = vctxt->filename; 2113 2114 __xmlRaiseError(schannel, channel, data, ctxt, 2115 node, XML_FROM_SCHEMASV, 2116 error, errorLevel, file, line, 2117 (const char *) str1, (const char *) str2, 2118 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2119 2120 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2121 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2122 if (errorLevel != XML_ERR_WARNING) { 2123 pctxt->nberrors++; 2124 pctxt->err = error; 2125 channel = pctxt->error; 2126 } else { 2127 channel = pctxt->warning; 2128 } 2129 schannel = pctxt->serror; 2130 data = pctxt->errCtxt; 2131 __xmlRaiseError(schannel, channel, data, ctxt, 2132 node, XML_FROM_SCHEMASP, error, 2133 errorLevel, NULL, 0, 2134 (const char *) str1, (const char *) str2, 2135 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2136 } else { 2137 TODO 2138 } 2139 } 2140 } 2141 2142 /** 2143 * xmlSchemaErr3: 2144 * @ctxt: the validation context 2145 * @node: the context node 2146 * @error: the error code 2147 * @msg: the error message 2148 * @str1: extra data 2149 * @str2: extra data 2150 * @str3: extra data 2151 * 2152 * Handle a validation error 2153 */ 2154 static void LIBXML_ATTR_FORMAT(4,0) 2155 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2156 int error, xmlNodePtr node, const char *msg, 2157 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2158 { 2159 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2160 msg, str1, str2, str3, NULL); 2161 } 2162 2163 static void LIBXML_ATTR_FORMAT(4,0) 2164 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2165 int error, xmlNodePtr node, const char *msg, 2166 const xmlChar *str1, const xmlChar *str2, 2167 const xmlChar *str3, const xmlChar *str4) 2168 { 2169 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2170 msg, str1, str2, str3, str4); 2171 } 2172 2173 static void LIBXML_ATTR_FORMAT(4,0) 2174 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2175 int error, xmlNodePtr node, const char *msg, 2176 const xmlChar *str1, const xmlChar *str2) 2177 { 2178 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2179 } 2180 2181 static xmlChar * 2182 xmlSchemaFormatNodeForError(xmlChar ** msg, 2183 xmlSchemaAbstractCtxtPtr actxt, 2184 xmlNodePtr node) 2185 { 2186 xmlChar *str = NULL; 2187 2188 *msg = NULL; 2189 if ((node != NULL) && 2190 (node->type != XML_ELEMENT_NODE) && 2191 (node->type != XML_ATTRIBUTE_NODE)) 2192 { 2193 /* 2194 * Don't try to format other nodes than element and 2195 * attribute nodes. 2196 * Play safe and return an empty string. 2197 */ 2198 *msg = xmlStrdup(BAD_CAST ""); 2199 return(*msg); 2200 } 2201 if (node != NULL) { 2202 /* 2203 * Work on tree nodes. 2204 */ 2205 if (node->type == XML_ATTRIBUTE_NODE) { 2206 xmlNodePtr elem = node->parent; 2207 2208 *msg = xmlStrdup(BAD_CAST "Element '"); 2209 if (elem->ns != NULL) 2210 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2211 elem->ns->href, elem->name)); 2212 else 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 NULL, elem->name)); 2215 FREE_AND_NULL(str); 2216 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2217 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2218 } else { 2219 *msg = xmlStrdup(BAD_CAST "Element '"); 2220 } 2221 if (node->ns != NULL) 2222 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2223 node->ns->href, node->name)); 2224 else 2225 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2226 NULL, node->name)); 2227 FREE_AND_NULL(str); 2228 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2229 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2230 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2231 /* 2232 * Work on node infos. 2233 */ 2234 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2235 xmlSchemaNodeInfoPtr ielem = 2236 vctxt->elemInfos[vctxt->depth]; 2237 2238 *msg = xmlStrdup(BAD_CAST "Element '"); 2239 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2240 ielem->nsName, ielem->localName)); 2241 FREE_AND_NULL(str); 2242 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2243 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2244 } else { 2245 *msg = xmlStrdup(BAD_CAST "Element '"); 2246 } 2247 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2248 vctxt->inode->nsName, vctxt->inode->localName)); 2249 FREE_AND_NULL(str); 2250 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2251 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2252 /* 2253 * Hmm, no node while parsing? 2254 * Return an empty string, in case NULL will break something. 2255 */ 2256 *msg = xmlStrdup(BAD_CAST ""); 2257 } else { 2258 TODO 2259 return (NULL); 2260 } 2261 2262 /* 2263 * xmlSchemaFormatItemForReport() also returns an escaped format 2264 * string, so do this before calling it below (in the future). 2265 */ 2266 xmlEscapeFormatString(msg); 2267 2268 /* 2269 * VAL TODO: The output of the given schema component is currently 2270 * disabled. 2271 */ 2272 #if 0 2273 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2274 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2275 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2276 NULL, type, NULL, 0)); 2277 FREE_AND_NULL(str) 2278 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2279 } 2280 #endif 2281 return (*msg); 2282 } 2283 2284 static void LIBXML_ATTR_FORMAT(3,0) 2285 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2286 const char *funcName, 2287 const char *message, 2288 const xmlChar *str1, 2289 const xmlChar *str2) 2290 { 2291 xmlChar *msg = NULL; 2292 2293 if (actxt == NULL) 2294 return; 2295 msg = xmlStrdup(BAD_CAST "Internal error: %s, "); 2296 msg = xmlStrcat(msg, BAD_CAST message); 2297 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2298 2299 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2300 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, 2301 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2302 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2303 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, 2304 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2305 2306 FREE_AND_NULL(msg) 2307 } 2308 2309 static void LIBXML_ATTR_FORMAT(3,0) 2310 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2311 const char *funcName, 2312 const char *message) 2313 { 2314 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2315 } 2316 2317 #if 0 2318 static void LIBXML_ATTR_FORMAT(3,0) 2319 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2320 const char *funcName, 2321 const char *message, 2322 const xmlChar *str1, 2323 const xmlChar *str2) 2324 { 2325 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2326 str1, str2); 2327 } 2328 #endif 2329 2330 static void LIBXML_ATTR_FORMAT(5,0) 2331 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2332 xmlParserErrors error, 2333 xmlNodePtr node, 2334 xmlSchemaBasicItemPtr item, 2335 const char *message, 2336 const xmlChar *str1, const xmlChar *str2, 2337 const xmlChar *str3, const xmlChar *str4) 2338 { 2339 xmlChar *msg = NULL; 2340 2341 if ((node == NULL) && (item != NULL) && 2342 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2343 node = WXS_ITEM_NODE(item); 2344 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2345 msg = xmlStrcat(msg, BAD_CAST ": "); 2346 } else 2347 xmlSchemaFormatNodeForError(&msg, actxt, node); 2348 msg = xmlStrcat(msg, (const xmlChar *) message); 2349 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2350 xmlSchemaErr4(actxt, error, node, 2351 (const char *) msg, str1, str2, str3, str4); 2352 FREE_AND_NULL(msg) 2353 } 2354 2355 static void LIBXML_ATTR_FORMAT(5,0) 2356 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2357 xmlParserErrors error, 2358 xmlNodePtr node, 2359 xmlSchemaBasicItemPtr item, 2360 const char *message, 2361 const xmlChar *str1, 2362 const xmlChar *str2) 2363 { 2364 xmlSchemaCustomErr4(actxt, error, node, item, 2365 message, str1, str2, NULL, NULL); 2366 } 2367 2368 2369 2370 static void LIBXML_ATTR_FORMAT(5,0) 2371 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2372 xmlParserErrors error, 2373 xmlNodePtr node, 2374 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2375 const char *message, 2376 const xmlChar *str1, 2377 const xmlChar *str2, 2378 const xmlChar *str3) 2379 { 2380 xmlChar *msg = NULL; 2381 2382 xmlSchemaFormatNodeForError(&msg, actxt, node); 2383 msg = xmlStrcat(msg, (const xmlChar *) message); 2384 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2385 2386 /* URGENT TODO: Set the error code to something sane. */ 2387 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2388 (const char *) msg, str1, str2, str3, NULL); 2389 2390 FREE_AND_NULL(msg) 2391 } 2392 2393 2394 2395 static void LIBXML_ATTR_FORMAT(5,0) 2396 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2397 xmlParserErrors error, 2398 xmlSchemaPSVIIDCNodePtr idcNode, 2399 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2400 const char *message, 2401 const xmlChar *str1, 2402 const xmlChar *str2) 2403 { 2404 xmlChar *msg = NULL, *qname = NULL; 2405 2406 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2407 msg = xmlStrcat(msg, (const xmlChar *) message); 2408 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2409 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2410 error, NULL, idcNode->nodeLine, (const char *) msg, 2411 xmlSchemaFormatQName(&qname, 2412 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2413 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2414 str1, str2, NULL); 2415 FREE_AND_NULL(qname); 2416 FREE_AND_NULL(msg); 2417 } 2418 2419 static int 2420 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2421 xmlNodePtr node) 2422 { 2423 if (node != NULL) 2424 return (node->type); 2425 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2426 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2427 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2428 return (-1); 2429 } 2430 2431 static int 2432 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2433 { 2434 switch (item->type) { 2435 case XML_SCHEMA_TYPE_COMPLEX: 2436 case XML_SCHEMA_TYPE_SIMPLE: 2437 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2438 return(1); 2439 break; 2440 case XML_SCHEMA_TYPE_GROUP: 2441 return (1); 2442 case XML_SCHEMA_TYPE_ELEMENT: 2443 if ( ((xmlSchemaElementPtr) item)->flags & 2444 XML_SCHEMAS_ELEM_GLOBAL) 2445 return(1); 2446 break; 2447 case XML_SCHEMA_TYPE_ATTRIBUTE: 2448 if ( ((xmlSchemaAttributePtr) item)->flags & 2449 XML_SCHEMAS_ATTR_GLOBAL) 2450 return(1); 2451 break; 2452 /* Note that attribute groups are always global. */ 2453 default: 2454 return(1); 2455 } 2456 return (0); 2457 } 2458 2459 static void 2460 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2461 xmlParserErrors error, 2462 xmlNodePtr node, 2463 const xmlChar *value, 2464 xmlSchemaTypePtr type, 2465 int displayValue) 2466 { 2467 xmlChar *msg = NULL; 2468 2469 xmlSchemaFormatNodeForError(&msg, actxt, node); 2470 2471 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2472 XML_ATTRIBUTE_NODE)) 2473 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2474 else 2475 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2476 "value of "); 2477 2478 if (! xmlSchemaIsGlobalItem(type)) 2479 msg = xmlStrcat(msg, BAD_CAST "the local "); 2480 else 2481 msg = xmlStrcat(msg, BAD_CAST "the "); 2482 2483 if (WXS_IS_ATOMIC(type)) 2484 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2485 else if (WXS_IS_LIST(type)) 2486 msg = xmlStrcat(msg, BAD_CAST "list type"); 2487 else if (WXS_IS_UNION(type)) 2488 msg = xmlStrcat(msg, BAD_CAST "union type"); 2489 2490 if (xmlSchemaIsGlobalItem(type)) { 2491 xmlChar *str = NULL; 2492 msg = xmlStrcat(msg, BAD_CAST " '"); 2493 if (type->builtInType != 0) { 2494 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2495 str = xmlStrdup(type->name); 2496 } else { 2497 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 2498 if (!str) 2499 str = xmlStrdup(qName); 2500 } 2501 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2502 msg = xmlStrcat(msg, BAD_CAST "'"); 2503 FREE_AND_NULL(str); 2504 } 2505 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2506 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2507 XML_ATTRIBUTE_NODE)) 2508 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2509 else 2510 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2511 FREE_AND_NULL(msg) 2512 } 2513 2514 static const xmlChar * 2515 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2516 xmlSchemaNodeInfoPtr ni, 2517 xmlNodePtr node) 2518 { 2519 if (node != NULL) { 2520 if (node->ns != NULL) 2521 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2522 else 2523 return (xmlSchemaFormatQName(str, NULL, node->name)); 2524 } else if (ni != NULL) 2525 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2526 return (NULL); 2527 } 2528 2529 static void 2530 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2531 xmlParserErrors error, 2532 xmlSchemaAttrInfoPtr ni, 2533 xmlNodePtr node) 2534 { 2535 xmlChar *msg = NULL, *str = NULL; 2536 2537 xmlSchemaFormatNodeForError(&msg, actxt, node); 2538 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2539 xmlSchemaErr(actxt, error, node, (const char *) msg, 2540 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2541 NULL); 2542 FREE_AND_NULL(str) 2543 FREE_AND_NULL(msg) 2544 } 2545 2546 static void LIBXML_ATTR_FORMAT(5,0) 2547 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2548 xmlParserErrors error, 2549 xmlNodePtr node, 2550 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2551 const char *message, 2552 int nbval, 2553 int nbneg, 2554 xmlChar **values) 2555 { 2556 xmlChar *str = NULL, *msg = NULL; 2557 xmlChar *localName, *nsName; 2558 const xmlChar *cur, *end; 2559 int i; 2560 2561 xmlSchemaFormatNodeForError(&msg, actxt, node); 2562 msg = xmlStrcat(msg, (const xmlChar *) message); 2563 msg = xmlStrcat(msg, BAD_CAST "."); 2564 /* 2565 * Note that is does not make sense to report that we have a 2566 * wildcard here, since the wildcard might be unfolded into 2567 * multiple transitions. 2568 */ 2569 if (nbval + nbneg > 0) { 2570 if (nbval + nbneg > 1) { 2571 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2572 } else 2573 str = xmlStrdup(BAD_CAST " Expected is ( "); 2574 nsName = NULL; 2575 2576 for (i = 0; i < nbval + nbneg; i++) { 2577 cur = values[i]; 2578 if (cur == NULL) 2579 continue; 2580 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2581 (cur[3] == ' ')) { 2582 cur += 4; 2583 str = xmlStrcat(str, BAD_CAST "##other"); 2584 } 2585 /* 2586 * Get the local name. 2587 */ 2588 localName = NULL; 2589 2590 end = cur; 2591 if (*end == '*') { 2592 localName = xmlStrdup(BAD_CAST "*"); 2593 end++; 2594 } else { 2595 while ((*end != 0) && (*end != '|')) 2596 end++; 2597 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2598 } 2599 if (*end != 0) { 2600 end++; 2601 /* 2602 * Skip "*|*" if they come with negated expressions, since 2603 * they represent the same negated wildcard. 2604 */ 2605 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2606 /* 2607 * Get the namespace name. 2608 */ 2609 cur = end; 2610 if (*end == '*') { 2611 nsName = xmlStrdup(BAD_CAST "{*}"); 2612 } else { 2613 while (*end != 0) 2614 end++; 2615 2616 if (i >= nbval) 2617 nsName = xmlStrdup(BAD_CAST "{##other:"); 2618 else 2619 nsName = xmlStrdup(BAD_CAST "{"); 2620 2621 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2622 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2623 } 2624 str = xmlStrcat(str, BAD_CAST nsName); 2625 FREE_AND_NULL(nsName) 2626 } else { 2627 FREE_AND_NULL(localName); 2628 continue; 2629 } 2630 } 2631 str = xmlStrcat(str, BAD_CAST localName); 2632 FREE_AND_NULL(localName); 2633 2634 if (i < nbval + nbneg -1) 2635 str = xmlStrcat(str, BAD_CAST ", "); 2636 } 2637 str = xmlStrcat(str, BAD_CAST " ).\n"); 2638 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2639 FREE_AND_NULL(str) 2640 } else 2641 msg = xmlStrcat(msg, BAD_CAST "\n"); 2642 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2643 xmlFree(msg); 2644 } 2645 2646 static void LIBXML_ATTR_FORMAT(8,0) 2647 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2648 xmlParserErrors error, 2649 xmlNodePtr node, 2650 const xmlChar *value, 2651 unsigned long length, 2652 xmlSchemaTypePtr type, 2653 xmlSchemaFacetPtr facet, 2654 const char *message, 2655 const xmlChar *str1, 2656 const xmlChar *str2) 2657 { 2658 xmlChar *str = NULL, *msg = NULL; 2659 xmlSchemaTypeType facetType; 2660 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2661 2662 xmlSchemaFormatNodeForError(&msg, actxt, node); 2663 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2664 facetType = XML_SCHEMA_FACET_ENUMERATION; 2665 /* 2666 * If enumerations are validated, one must not expect the 2667 * facet to be given. 2668 */ 2669 } else 2670 facetType = facet->type; 2671 msg = xmlStrcat(msg, BAD_CAST "["); 2672 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2673 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2674 msg = xmlStrcat(msg, BAD_CAST "'] "); 2675 if (message == NULL) { 2676 /* 2677 * Use a default message. 2678 */ 2679 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2680 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2681 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2682 2683 char len[25], actLen[25]; 2684 2685 /* FIXME, TODO: What is the max expected string length of the 2686 * this value? 2687 */ 2688 if (nodeType == XML_ATTRIBUTE_NODE) 2689 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2690 else 2691 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2692 2693 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2694 snprintf(actLen, 24, "%lu", length); 2695 2696 if (facetType == XML_SCHEMA_FACET_LENGTH) 2697 msg = xmlStrcat(msg, 2698 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2699 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2700 msg = xmlStrcat(msg, 2701 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2702 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2703 msg = xmlStrcat(msg, 2704 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2705 2706 if (nodeType == XML_ATTRIBUTE_NODE) 2707 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2708 value, (const xmlChar *) actLen, (const xmlChar *) len); 2709 else 2710 xmlSchemaErr(actxt, error, node, (const char *) msg, 2711 (const xmlChar *) actLen, (const xmlChar *) len); 2712 2713 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2714 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2715 "of the set {%s}.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2717 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2718 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2719 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2720 "by the pattern '%s'.\n"); 2721 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2722 facet->value); 2723 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2724 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2725 "minimum value allowed ('%s').\n"); 2726 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2727 facet->value); 2728 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2729 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2730 "maximum value allowed ('%s').\n"); 2731 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2732 facet->value); 2733 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2734 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2735 "'%s'.\n"); 2736 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2737 facet->value); 2738 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2739 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2740 "'%s'.\n"); 2741 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2742 facet->value); 2743 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2744 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2745 "digits than are allowed ('%s').\n"); 2746 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2747 facet->value); 2748 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2749 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2750 "digits than are allowed ('%s').\n"); 2751 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2752 facet->value); 2753 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2754 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2755 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2756 } else { 2757 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2758 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2759 } 2760 } else { 2761 msg = xmlStrcat(msg, (const xmlChar *) message); 2762 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2763 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2764 } 2765 FREE_AND_NULL(str) 2766 xmlFree(msg); 2767 } 2768 2769 #define VERROR(err, type, msg) \ 2770 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2771 2772 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2773 2774 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2775 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2776 2777 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2778 2779 2780 /** 2781 * xmlSchemaPMissingAttrErr: 2782 * @ctxt: the schema validation context 2783 * @ownerDes: the designation of the owner 2784 * @ownerName: the name of the owner 2785 * @ownerItem: the owner as a schema object 2786 * @ownerElem: the owner as an element node 2787 * @node: the parent element node of the missing attribute node 2788 * @type: the corresponding type of the attribute node 2789 * 2790 * Reports an illegal attribute. 2791 */ 2792 static void 2793 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2794 xmlParserErrors error, 2795 xmlSchemaBasicItemPtr ownerItem, 2796 xmlNodePtr ownerElem, 2797 const char *name, 2798 const char *message) 2799 { 2800 xmlChar *des = NULL; 2801 2802 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2803 2804 if (message != NULL) 2805 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2806 else 2807 xmlSchemaPErr(ctxt, ownerElem, error, 2808 "%s: The attribute '%s' is required but missing.\n", 2809 BAD_CAST des, BAD_CAST name); 2810 FREE_AND_NULL(des); 2811 } 2812 2813 2814 /** 2815 * xmlSchemaPResCompAttrErr: 2816 * @ctxt: the schema validation context 2817 * @error: the error code 2818 * @ownerDes: the designation of the owner 2819 * @ownerItem: the owner as a schema object 2820 * @ownerElem: the owner as an element node 2821 * @name: the name of the attribute holding the QName 2822 * @refName: the referenced local name 2823 * @refURI: the referenced namespace URI 2824 * @message: optional message 2825 * 2826 * Used to report QName attribute values that failed to resolve 2827 * to schema components. 2828 */ 2829 static void 2830 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2831 xmlParserErrors error, 2832 xmlSchemaBasicItemPtr ownerItem, 2833 xmlNodePtr ownerElem, 2834 const char *name, 2835 const xmlChar *refName, 2836 const xmlChar *refURI, 2837 xmlSchemaTypeType refType, 2838 const char *refTypeStr) 2839 { 2840 xmlChar *des = NULL, *strA = NULL; 2841 2842 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2843 if (refTypeStr == NULL) 2844 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2845 xmlSchemaPErrExt(ctxt, ownerElem, error, 2846 NULL, NULL, NULL, 2847 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2848 "%s.\n", BAD_CAST des, BAD_CAST name, 2849 xmlSchemaFormatQName(&strA, refURI, refName), 2850 BAD_CAST refTypeStr, NULL); 2851 FREE_AND_NULL(des) 2852 FREE_AND_NULL(strA) 2853 } 2854 2855 /** 2856 * xmlSchemaPCustomAttrErr: 2857 * @ctxt: the schema parser context 2858 * @error: the error code 2859 * @ownerDes: the designation of the owner 2860 * @ownerItem: the owner as a schema object 2861 * @attr: the illegal attribute node 2862 * 2863 * Reports an illegal attribute during the parse. 2864 */ 2865 static void 2866 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2867 xmlParserErrors error, 2868 xmlChar **ownerDes, 2869 xmlSchemaBasicItemPtr ownerItem, 2870 xmlAttrPtr attr, 2871 const char *msg) 2872 { 2873 xmlChar *des = NULL; 2874 2875 if (ownerDes == NULL) 2876 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2877 else if (*ownerDes == NULL) { 2878 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2879 des = *ownerDes; 2880 } else 2881 des = *ownerDes; 2882 if (attr == NULL) { 2883 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2884 "%s, attribute '%s': %s.\n", 2885 BAD_CAST des, (const xmlChar *) "Unknown", 2886 (const xmlChar *) msg, NULL, NULL); 2887 } else { 2888 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2889 "%s, attribute '%s': %s.\n", 2890 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2891 } 2892 if (ownerDes == NULL) 2893 FREE_AND_NULL(des); 2894 } 2895 2896 /** 2897 * xmlSchemaPIllegalAttrErr: 2898 * @ctxt: the schema parser context 2899 * @error: the error code 2900 * @ownerDes: the designation of the attribute's owner 2901 * @ownerItem: the attribute's owner item 2902 * @attr: the illegal attribute node 2903 * 2904 * Reports an illegal attribute during the parse. 2905 */ 2906 static void 2907 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2908 xmlParserErrors error, 2909 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2910 xmlAttrPtr attr) 2911 { 2912 xmlChar *strA = NULL, *strB = NULL; 2913 2914 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2915 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2916 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2917 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2918 NULL, NULL); 2919 FREE_AND_NULL(strA); 2920 FREE_AND_NULL(strB); 2921 } 2922 2923 /** 2924 * xmlSchemaPCustomErr: 2925 * @ctxt: the schema parser context 2926 * @error: the error code 2927 * @itemDes: the designation of the schema item 2928 * @item: the schema item 2929 * @itemElem: the node of the schema item 2930 * @message: the error message 2931 * @str1: an optional param for the error message 2932 * @str2: an optional param for the error message 2933 * @str3: an optional param for the error message 2934 * 2935 * Reports an error during parsing. 2936 */ 2937 static void LIBXML_ATTR_FORMAT(5,0) 2938 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2939 xmlParserErrors error, 2940 xmlSchemaBasicItemPtr item, 2941 xmlNodePtr itemElem, 2942 const char *message, 2943 const xmlChar *str1, 2944 const xmlChar *str2, 2945 const xmlChar *str3) 2946 { 2947 xmlChar *des = NULL, *msg = NULL; 2948 2949 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2950 msg = xmlStrdup(BAD_CAST "%s: "); 2951 msg = xmlStrcat(msg, (const xmlChar *) message); 2952 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2953 if ((itemElem == NULL) && (item != NULL)) 2954 itemElem = WXS_ITEM_NODE(item); 2955 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2956 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2957 FREE_AND_NULL(des); 2958 FREE_AND_NULL(msg); 2959 } 2960 2961 /** 2962 * xmlSchemaPCustomErr: 2963 * @ctxt: the schema parser context 2964 * @error: the error code 2965 * @itemDes: the designation of the schema item 2966 * @item: the schema item 2967 * @itemElem: the node of the schema item 2968 * @message: the error message 2969 * @str1: the optional param for the error message 2970 * 2971 * Reports an error during parsing. 2972 */ 2973 static void LIBXML_ATTR_FORMAT(5,0) 2974 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2975 xmlParserErrors error, 2976 xmlSchemaBasicItemPtr item, 2977 xmlNodePtr itemElem, 2978 const char *message, 2979 const xmlChar *str1) 2980 { 2981 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2982 str1, NULL, NULL); 2983 } 2984 2985 /** 2986 * xmlSchemaPAttrUseErr: 2987 * @ctxt: the schema parser context 2988 * @error: the error code 2989 * @itemDes: the designation of the schema type 2990 * @item: the schema type 2991 * @itemElem: the node of the schema type 2992 * @attr: the invalid schema attribute 2993 * @message: the error message 2994 * @str1: the optional param for the error message 2995 * 2996 * Reports an attribute use error during parsing. 2997 */ 2998 static void LIBXML_ATTR_FORMAT(6,0) 2999 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 3000 xmlParserErrors error, 3001 xmlNodePtr node, 3002 xmlSchemaBasicItemPtr ownerItem, 3003 const xmlSchemaAttributeUsePtr attruse, 3004 const char *message, 3005 const xmlChar *str1, const xmlChar *str2, 3006 const xmlChar *str3,const xmlChar *str4) 3007 { 3008 xmlChar *str = NULL, *msg = NULL; 3009 3010 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 3011 msg = xmlStrcat(msg, BAD_CAST ", "); 3012 msg = xmlStrcat(msg, 3013 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 3014 WXS_BASIC_CAST attruse, NULL)); 3015 FREE_AND_NULL(str); 3016 msg = xmlStrcat(msg, BAD_CAST ": "); 3017 msg = xmlStrcat(msg, (const xmlChar *) message); 3018 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3019 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3020 (const char *) msg, str1, str2, str3, str4); 3021 xmlFree(msg); 3022 } 3023 3024 /** 3025 * xmlSchemaPIllegalFacetAtomicErr: 3026 * @ctxt: the schema parser context 3027 * @error: the error code 3028 * @type: the schema type 3029 * @baseType: the base type of type 3030 * @facet: the illegal facet 3031 * 3032 * Reports an illegal facet for atomic simple types. 3033 */ 3034 static void 3035 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3036 xmlParserErrors error, 3037 xmlSchemaTypePtr type, 3038 xmlSchemaTypePtr baseType, 3039 xmlSchemaFacetPtr facet) 3040 { 3041 xmlChar *des = NULL, *strT = NULL; 3042 3043 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3044 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3045 "%s: The facet '%s' is not allowed on types derived from the " 3046 "type %s.\n", 3047 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3048 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3049 NULL, NULL); 3050 FREE_AND_NULL(des); 3051 FREE_AND_NULL(strT); 3052 } 3053 3054 /** 3055 * xmlSchemaPIllegalFacetListUnionErr: 3056 * @ctxt: the schema parser context 3057 * @error: the error code 3058 * @itemDes: the designation of the schema item involved 3059 * @item: the schema item involved 3060 * @facet: the illegal facet 3061 * 3062 * Reports an illegal facet for <list> and <union>. 3063 */ 3064 static void 3065 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3066 xmlParserErrors error, 3067 xmlSchemaTypePtr type, 3068 xmlSchemaFacetPtr facet) 3069 { 3070 xmlChar *des = NULL; 3071 3072 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3073 type->node); 3074 xmlSchemaPErr(ctxt, type->node, error, 3075 "%s: The facet '%s' is not allowed.\n", 3076 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3077 FREE_AND_NULL(des); 3078 } 3079 3080 /** 3081 * xmlSchemaPMutualExclAttrErr: 3082 * @ctxt: the schema validation context 3083 * @error: the error code 3084 * @elemDes: the designation of the parent element node 3085 * @attr: the bad attribute node 3086 * @type: the corresponding type of the attribute node 3087 * 3088 * Reports an illegal attribute. 3089 */ 3090 static void 3091 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3092 xmlParserErrors error, 3093 xmlSchemaBasicItemPtr ownerItem, 3094 xmlAttrPtr attr, 3095 const char *name1, 3096 const char *name2) 3097 { 3098 xmlChar *des = NULL; 3099 3100 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3101 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3102 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3103 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3104 FREE_AND_NULL(des); 3105 } 3106 3107 /** 3108 * xmlSchemaPSimpleTypeErr: 3109 * @ctxt: the schema validation context 3110 * @error: the error code 3111 * @type: the type specifier 3112 * @ownerDes: the designation of the owner 3113 * @ownerItem: the schema object if existent 3114 * @node: the validated node 3115 * @value: the validated value 3116 * 3117 * Reports a simple type validation error. 3118 * TODO: Should this report the value of an element as well? 3119 */ 3120 static void LIBXML_ATTR_FORMAT(8,0) 3121 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3122 xmlParserErrors error, 3123 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3124 xmlNodePtr node, 3125 xmlSchemaTypePtr type, 3126 const char *expected, 3127 const xmlChar *value, 3128 const char *message, 3129 const xmlChar *str1, 3130 const xmlChar *str2) 3131 { 3132 xmlChar *msg = NULL; 3133 3134 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3135 if (message == NULL) { 3136 /* 3137 * Use default messages. 3138 */ 3139 if (type != NULL) { 3140 if (node->type == XML_ATTRIBUTE_NODE) 3141 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3142 else 3143 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3144 "valid value of "); 3145 if (! xmlSchemaIsGlobalItem(type)) 3146 msg = xmlStrcat(msg, BAD_CAST "the local "); 3147 else 3148 msg = xmlStrcat(msg, BAD_CAST "the "); 3149 3150 if (WXS_IS_ATOMIC(type)) 3151 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3152 else if (WXS_IS_LIST(type)) 3153 msg = xmlStrcat(msg, BAD_CAST "list type"); 3154 else if (WXS_IS_UNION(type)) 3155 msg = xmlStrcat(msg, BAD_CAST "union type"); 3156 3157 if (xmlSchemaIsGlobalItem(type)) { 3158 xmlChar *str = NULL; 3159 msg = xmlStrcat(msg, BAD_CAST " '"); 3160 if (type->builtInType != 0) { 3161 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3162 str = xmlStrdup(type->name); 3163 } else { 3164 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 3165 if (!str) 3166 str = xmlStrdup(qName); 3167 } 3168 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 3169 msg = xmlStrcat(msg, BAD_CAST "'."); 3170 FREE_AND_NULL(str); 3171 } 3172 } else { 3173 if (node->type == XML_ATTRIBUTE_NODE) 3174 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3175 else 3176 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3177 "valid."); 3178 } 3179 if (expected) { 3180 xmlChar *expectedEscaped = xmlCharStrdup(expected); 3181 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3182 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); 3183 FREE_AND_NULL(expectedEscaped); 3184 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3185 } else 3186 msg = xmlStrcat(msg, BAD_CAST "\n"); 3187 if (node->type == XML_ATTRIBUTE_NODE) 3188 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3189 else 3190 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3191 } else { 3192 msg = xmlStrcat(msg, BAD_CAST message); 3193 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3194 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3195 (const char*) msg, str1, str2, NULL, NULL, NULL); 3196 } 3197 /* Cleanup. */ 3198 FREE_AND_NULL(msg) 3199 } 3200 3201 /** 3202 * xmlSchemaPContentErr: 3203 * @ctxt: the schema parser context 3204 * @error: the error code 3205 * @onwerDes: the designation of the holder of the content 3206 * @ownerItem: the owner item of the holder of the content 3207 * @ownerElem: the node of the holder of the content 3208 * @child: the invalid child node 3209 * @message: the optional error message 3210 * @content: the optional string describing the correct content 3211 * 3212 * Reports an error concerning the content of a schema element. 3213 */ 3214 static void 3215 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3216 xmlParserErrors error, 3217 xmlSchemaBasicItemPtr ownerItem, 3218 xmlNodePtr ownerElem, 3219 xmlNodePtr child, 3220 const char *message, 3221 const char *content) 3222 { 3223 xmlChar *des = NULL; 3224 3225 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3226 if (message != NULL) 3227 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3228 "%s: %s.\n", 3229 BAD_CAST des, BAD_CAST message); 3230 else { 3231 if (content != NULL) { 3232 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3233 "%s: The content is not valid. Expected is %s.\n", 3234 BAD_CAST des, BAD_CAST content); 3235 } else { 3236 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3237 "%s: The content is not valid.\n", 3238 BAD_CAST des, NULL); 3239 } 3240 } 3241 FREE_AND_NULL(des) 3242 } 3243 3244 /************************************************************************ 3245 * * 3246 * Streamable error functions * 3247 * * 3248 ************************************************************************/ 3249 3250 3251 3252 3253 /************************************************************************ 3254 * * 3255 * Validation helper functions * 3256 * * 3257 ************************************************************************/ 3258 3259 3260 /************************************************************************ 3261 * * 3262 * Allocation functions * 3263 * * 3264 ************************************************************************/ 3265 3266 /** 3267 * xmlSchemaNewSchemaForParserCtxt: 3268 * @ctxt: a schema validation context 3269 * 3270 * Allocate a new Schema structure. 3271 * 3272 * Returns the newly allocated structure or NULL in case or error 3273 */ 3274 static xmlSchemaPtr 3275 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3276 { 3277 xmlSchemaPtr ret; 3278 3279 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3280 if (ret == NULL) { 3281 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3282 return (NULL); 3283 } 3284 memset(ret, 0, sizeof(xmlSchema)); 3285 ret->dict = ctxt->dict; 3286 xmlDictReference(ret->dict); 3287 3288 return (ret); 3289 } 3290 3291 /** 3292 * xmlSchemaNewFacet: 3293 * 3294 * Allocate a new Facet structure. 3295 * 3296 * Returns the newly allocated structure or NULL in case or error 3297 */ 3298 xmlSchemaFacetPtr 3299 xmlSchemaNewFacet(void) 3300 { 3301 xmlSchemaFacetPtr ret; 3302 3303 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3304 if (ret == NULL) { 3305 return (NULL); 3306 } 3307 memset(ret, 0, sizeof(xmlSchemaFacet)); 3308 3309 return (ret); 3310 } 3311 3312 /** 3313 * xmlSchemaNewAnnot: 3314 * @ctxt: a schema validation context 3315 * @node: a node 3316 * 3317 * Allocate a new annotation structure. 3318 * 3319 * Returns the newly allocated structure or NULL in case or error 3320 */ 3321 static xmlSchemaAnnotPtr 3322 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3323 { 3324 xmlSchemaAnnotPtr ret; 3325 3326 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3327 if (ret == NULL) { 3328 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3329 return (NULL); 3330 } 3331 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3332 ret->content = node; 3333 return (ret); 3334 } 3335 3336 static xmlSchemaItemListPtr 3337 xmlSchemaItemListCreate(void) 3338 { 3339 xmlSchemaItemListPtr ret; 3340 3341 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3342 if (ret == NULL) { 3343 xmlSchemaPErrMemory(NULL, 3344 "allocating an item list structure", NULL); 3345 return (NULL); 3346 } 3347 memset(ret, 0, sizeof(xmlSchemaItemList)); 3348 return (ret); 3349 } 3350 3351 static void 3352 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3353 { 3354 if (list->items != NULL) { 3355 xmlFree(list->items); 3356 list->items = NULL; 3357 } 3358 list->nbItems = 0; 3359 list->sizeItems = 0; 3360 } 3361 3362 static int 3363 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3364 { 3365 if (list->items == NULL) { 3366 list->items = (void **) xmlMalloc( 3367 20 * sizeof(void *)); 3368 if (list->items == NULL) { 3369 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3370 return(-1); 3371 } 3372 list->sizeItems = 20; 3373 } else if (list->sizeItems <= list->nbItems) { 3374 list->sizeItems *= 2; 3375 list->items = (void **) xmlRealloc(list->items, 3376 list->sizeItems * sizeof(void *)); 3377 if (list->items == NULL) { 3378 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3379 list->sizeItems = 0; 3380 return(-1); 3381 } 3382 } 3383 list->items[list->nbItems++] = item; 3384 return(0); 3385 } 3386 3387 static int 3388 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3389 int initialSize, 3390 void *item) 3391 { 3392 if (list->items == NULL) { 3393 if (initialSize <= 0) 3394 initialSize = 1; 3395 list->items = (void **) xmlMalloc( 3396 initialSize * sizeof(void *)); 3397 if (list->items == NULL) { 3398 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3399 return(-1); 3400 } 3401 list->sizeItems = initialSize; 3402 } else if (list->sizeItems <= list->nbItems) { 3403 list->sizeItems *= 2; 3404 list->items = (void **) xmlRealloc(list->items, 3405 list->sizeItems * sizeof(void *)); 3406 if (list->items == NULL) { 3407 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3408 list->sizeItems = 0; 3409 return(-1); 3410 } 3411 } 3412 list->items[list->nbItems++] = item; 3413 return(0); 3414 } 3415 3416 static int 3417 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3418 { 3419 if (list->items == NULL) { 3420 list->items = (void **) xmlMalloc( 3421 20 * sizeof(void *)); 3422 if (list->items == NULL) { 3423 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3424 return(-1); 3425 } 3426 list->sizeItems = 20; 3427 } else if (list->sizeItems <= list->nbItems) { 3428 list->sizeItems *= 2; 3429 list->items = (void **) xmlRealloc(list->items, 3430 list->sizeItems * sizeof(void *)); 3431 if (list->items == NULL) { 3432 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3433 list->sizeItems = 0; 3434 return(-1); 3435 } 3436 } 3437 /* 3438 * Just append if the index is greater/equal than the item count. 3439 */ 3440 if (idx >= list->nbItems) { 3441 list->items[list->nbItems++] = item; 3442 } else { 3443 int i; 3444 for (i = list->nbItems; i > idx; i--) 3445 list->items[i] = list->items[i-1]; 3446 list->items[idx] = item; 3447 list->nbItems++; 3448 } 3449 return(0); 3450 } 3451 3452 #if 0 /* enable if ever needed */ 3453 static int 3454 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3455 int initialSize, 3456 void *item, 3457 int idx) 3458 { 3459 if (list->items == NULL) { 3460 if (initialSize <= 0) 3461 initialSize = 1; 3462 list->items = (void **) xmlMalloc( 3463 initialSize * sizeof(void *)); 3464 if (list->items == NULL) { 3465 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3466 return(-1); 3467 } 3468 list->sizeItems = initialSize; 3469 } else if (list->sizeItems <= list->nbItems) { 3470 list->sizeItems *= 2; 3471 list->items = (void **) xmlRealloc(list->items, 3472 list->sizeItems * sizeof(void *)); 3473 if (list->items == NULL) { 3474 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3475 list->sizeItems = 0; 3476 return(-1); 3477 } 3478 } 3479 /* 3480 * Just append if the index is greater/equal than the item count. 3481 */ 3482 if (idx >= list->nbItems) { 3483 list->items[list->nbItems++] = item; 3484 } else { 3485 int i; 3486 for (i = list->nbItems; i > idx; i--) 3487 list->items[i] = list->items[i-1]; 3488 list->items[idx] = item; 3489 list->nbItems++; 3490 } 3491 return(0); 3492 } 3493 #endif 3494 3495 static int 3496 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3497 { 3498 int i; 3499 if ((list->items == NULL) || (idx >= list->nbItems)) { 3500 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3501 "index error.\n"); 3502 return(-1); 3503 } 3504 3505 if (list->nbItems == 1) { 3506 /* TODO: Really free the list? */ 3507 xmlFree(list->items); 3508 list->items = NULL; 3509 list->nbItems = 0; 3510 list->sizeItems = 0; 3511 } else if (list->nbItems -1 == idx) { 3512 list->nbItems--; 3513 } else { 3514 for (i = idx; i < list->nbItems -1; i++) 3515 list->items[i] = list->items[i+1]; 3516 list->nbItems--; 3517 } 3518 return(0); 3519 } 3520 3521 /** 3522 * xmlSchemaItemListFree: 3523 * @annot: a schema type structure 3524 * 3525 * Deallocate a annotation structure 3526 */ 3527 static void 3528 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3529 { 3530 if (list == NULL) 3531 return; 3532 if (list->items != NULL) 3533 xmlFree(list->items); 3534 xmlFree(list); 3535 } 3536 3537 static void 3538 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3539 { 3540 if (bucket == NULL) 3541 return; 3542 if (bucket->globals != NULL) { 3543 xmlSchemaComponentListFree(bucket->globals); 3544 xmlSchemaItemListFree(bucket->globals); 3545 } 3546 if (bucket->locals != NULL) { 3547 xmlSchemaComponentListFree(bucket->locals); 3548 xmlSchemaItemListFree(bucket->locals); 3549 } 3550 if (bucket->relations != NULL) { 3551 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3552 do { 3553 prev = cur; 3554 cur = cur->next; 3555 xmlFree(prev); 3556 } while (cur != NULL); 3557 } 3558 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3559 xmlFreeDoc(bucket->doc); 3560 } 3561 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3562 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3563 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3564 } 3565 xmlFree(bucket); 3566 } 3567 3568 static void 3569 xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED) 3570 { 3571 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket); 3572 } 3573 3574 static xmlSchemaBucketPtr 3575 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3576 int type, const xmlChar *targetNamespace) 3577 { 3578 xmlSchemaBucketPtr ret; 3579 int size; 3580 xmlSchemaPtr mainSchema; 3581 3582 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3583 PERROR_INT("xmlSchemaBucketCreate", 3584 "no main schema on constructor"); 3585 return(NULL); 3586 } 3587 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3588 /* Create the schema bucket. */ 3589 if (WXS_IS_BUCKET_INCREDEF(type)) 3590 size = sizeof(xmlSchemaInclude); 3591 else 3592 size = sizeof(xmlSchemaImport); 3593 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3594 if (ret == NULL) { 3595 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3596 return(NULL); 3597 } 3598 memset(ret, 0, size); 3599 ret->targetNamespace = targetNamespace; 3600 ret->type = type; 3601 ret->globals = xmlSchemaItemListCreate(); 3602 if (ret->globals == NULL) { 3603 xmlFree(ret); 3604 return(NULL); 3605 } 3606 ret->locals = xmlSchemaItemListCreate(); 3607 if (ret->locals == NULL) { 3608 xmlFree(ret); 3609 return(NULL); 3610 } 3611 /* 3612 * The following will assure that only the first bucket is marked as 3613 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3614 * For each following import buckets an xmlSchema will be created. 3615 * An xmlSchema will be created for every distinct targetNamespace. 3616 * We assign the targetNamespace to the schemata here. 3617 */ 3618 if (! WXS_HAS_BUCKETS(pctxt)) { 3619 if (WXS_IS_BUCKET_INCREDEF(type)) { 3620 PERROR_INT("xmlSchemaBucketCreate", 3621 "first bucket but it's an include or redefine"); 3622 xmlSchemaBucketFree(ret); 3623 return(NULL); 3624 } 3625 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3626 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3627 /* Point to the *main* schema. */ 3628 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3629 WXS_IMPBUCKET(ret)->schema = mainSchema; 3630 /* 3631 * Ensure that the main schema gets a targetNamespace. 3632 */ 3633 mainSchema->targetNamespace = targetNamespace; 3634 } else { 3635 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3636 PERROR_INT("xmlSchemaBucketCreate", 3637 "main bucket but it's not the first one"); 3638 xmlSchemaBucketFree(ret); 3639 return(NULL); 3640 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3641 /* 3642 * Create a schema for imports and assign the 3643 * targetNamespace. 3644 */ 3645 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3646 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3647 xmlSchemaBucketFree(ret); 3648 return(NULL); 3649 } 3650 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3651 } 3652 } 3653 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3654 int res; 3655 /* 3656 * Imports go into the "schemasImports" slot of the main *schema*. 3657 * Note that we create an import entry for the main schema as well; i.e., 3658 * even if there's only one schema, we'll get an import. 3659 */ 3660 if (mainSchema->schemasImports == NULL) { 3661 mainSchema->schemasImports = xmlHashCreateDict(5, 3662 WXS_CONSTRUCTOR(pctxt)->dict); 3663 if (mainSchema->schemasImports == NULL) { 3664 xmlSchemaBucketFree(ret); 3665 return(NULL); 3666 } 3667 } 3668 if (targetNamespace == NULL) 3669 res = xmlHashAddEntry(mainSchema->schemasImports, 3670 XML_SCHEMAS_NO_NAMESPACE, ret); 3671 else 3672 res = xmlHashAddEntry(mainSchema->schemasImports, 3673 targetNamespace, ret); 3674 if (res != 0) { 3675 PERROR_INT("xmlSchemaBucketCreate", 3676 "failed to add the schema bucket to the hash"); 3677 xmlSchemaBucketFree(ret); 3678 return(NULL); 3679 } 3680 } else { 3681 /* Set the @ownerImport of an include bucket. */ 3682 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3683 WXS_INCBUCKET(ret)->ownerImport = 3684 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3685 else 3686 WXS_INCBUCKET(ret)->ownerImport = 3687 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3688 3689 /* Includes got into the "includes" slot of the *main* schema. */ 3690 if (mainSchema->includes == NULL) { 3691 mainSchema->includes = xmlSchemaItemListCreate(); 3692 if (mainSchema->includes == NULL) { 3693 xmlSchemaBucketFree(ret); 3694 return(NULL); 3695 } 3696 } 3697 xmlSchemaItemListAdd(mainSchema->includes, ret); 3698 } 3699 /* 3700 * Add to list of all buckets; this is used for lookup 3701 * during schema construction time only. 3702 */ 3703 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3704 return(NULL); 3705 return(ret); 3706 } 3707 3708 static int 3709 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3710 { 3711 if (*list == NULL) { 3712 *list = xmlSchemaItemListCreate(); 3713 if (*list == NULL) 3714 return(-1); 3715 } 3716 xmlSchemaItemListAddSize(*list, initialSize, item); 3717 return(0); 3718 } 3719 3720 /** 3721 * xmlSchemaFreeAnnot: 3722 * @annot: a schema type structure 3723 * 3724 * Deallocate a annotation structure 3725 */ 3726 static void 3727 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3728 { 3729 if (annot == NULL) 3730 return; 3731 if (annot->next == NULL) { 3732 xmlFree(annot); 3733 } else { 3734 xmlSchemaAnnotPtr prev; 3735 3736 do { 3737 prev = annot; 3738 annot = annot->next; 3739 xmlFree(prev); 3740 } while (annot != NULL); 3741 } 3742 } 3743 3744 /** 3745 * xmlSchemaFreeNotation: 3746 * @schema: a schema notation structure 3747 * 3748 * Deallocate a Schema Notation structure. 3749 */ 3750 static void 3751 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3752 { 3753 if (nota == NULL) 3754 return; 3755 xmlFree(nota); 3756 } 3757 3758 /** 3759 * xmlSchemaFreeAttribute: 3760 * @attr: an attribute declaration 3761 * 3762 * Deallocates an attribute declaration structure. 3763 */ 3764 static void 3765 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3766 { 3767 if (attr == NULL) 3768 return; 3769 if (attr->annot != NULL) 3770 xmlSchemaFreeAnnot(attr->annot); 3771 if (attr->defVal != NULL) 3772 xmlSchemaFreeValue(attr->defVal); 3773 xmlFree(attr); 3774 } 3775 3776 /** 3777 * xmlSchemaFreeAttributeUse: 3778 * @use: an attribute use 3779 * 3780 * Deallocates an attribute use structure. 3781 */ 3782 static void 3783 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3784 { 3785 if (use == NULL) 3786 return; 3787 if (use->annot != NULL) 3788 xmlSchemaFreeAnnot(use->annot); 3789 if (use->defVal != NULL) 3790 xmlSchemaFreeValue(use->defVal); 3791 xmlFree(use); 3792 } 3793 3794 /** 3795 * xmlSchemaFreeAttributeUseProhib: 3796 * @prohib: an attribute use prohibition 3797 * 3798 * Deallocates an attribute use structure. 3799 */ 3800 static void 3801 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3802 { 3803 if (prohib == NULL) 3804 return; 3805 xmlFree(prohib); 3806 } 3807 3808 /** 3809 * xmlSchemaFreeWildcardNsSet: 3810 * set: a schema wildcard namespace 3811 * 3812 * Deallocates a list of wildcard constraint structures. 3813 */ 3814 static void 3815 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3816 { 3817 xmlSchemaWildcardNsPtr next; 3818 3819 while (set != NULL) { 3820 next = set->next; 3821 xmlFree(set); 3822 set = next; 3823 } 3824 } 3825 3826 /** 3827 * xmlSchemaFreeWildcard: 3828 * @wildcard: a wildcard structure 3829 * 3830 * Deallocates a wildcard structure. 3831 */ 3832 void 3833 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3834 { 3835 if (wildcard == NULL) 3836 return; 3837 if (wildcard->annot != NULL) 3838 xmlSchemaFreeAnnot(wildcard->annot); 3839 if (wildcard->nsSet != NULL) 3840 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3841 if (wildcard->negNsSet != NULL) 3842 xmlFree(wildcard->negNsSet); 3843 xmlFree(wildcard); 3844 } 3845 3846 /** 3847 * xmlSchemaFreeAttributeGroup: 3848 * @schema: a schema attribute group structure 3849 * 3850 * Deallocate a Schema Attribute Group structure. 3851 */ 3852 static void 3853 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3854 { 3855 if (attrGr == NULL) 3856 return; 3857 if (attrGr->annot != NULL) 3858 xmlSchemaFreeAnnot(attrGr->annot); 3859 if (attrGr->attrUses != NULL) 3860 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3861 xmlFree(attrGr); 3862 } 3863 3864 /** 3865 * xmlSchemaFreeQNameRef: 3866 * @item: a QName reference structure 3867 * 3868 * Deallocatea a QName reference structure. 3869 */ 3870 static void 3871 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3872 { 3873 xmlFree(item); 3874 } 3875 3876 /** 3877 * xmlSchemaFreeTypeLinkList: 3878 * @alink: a type link 3879 * 3880 * Deallocate a list of types. 3881 */ 3882 static void 3883 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3884 { 3885 xmlSchemaTypeLinkPtr next; 3886 3887 while (link != NULL) { 3888 next = link->next; 3889 xmlFree(link); 3890 link = next; 3891 } 3892 } 3893 3894 static void 3895 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3896 { 3897 xmlSchemaIDCStateObjPtr next; 3898 while (sto != NULL) { 3899 next = sto->next; 3900 if (sto->history != NULL) 3901 xmlFree(sto->history); 3902 if (sto->xpathCtxt != NULL) 3903 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3904 xmlFree(sto); 3905 sto = next; 3906 } 3907 } 3908 3909 /** 3910 * xmlSchemaFreeIDC: 3911 * @idc: a identity-constraint definition 3912 * 3913 * Deallocates an identity-constraint definition. 3914 */ 3915 static void 3916 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3917 { 3918 xmlSchemaIDCSelectPtr cur, prev; 3919 3920 if (idcDef == NULL) 3921 return; 3922 if (idcDef->annot != NULL) 3923 xmlSchemaFreeAnnot(idcDef->annot); 3924 /* Selector */ 3925 if (idcDef->selector != NULL) { 3926 if (idcDef->selector->xpathComp != NULL) 3927 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3928 xmlFree(idcDef->selector); 3929 } 3930 /* Fields */ 3931 if (idcDef->fields != NULL) { 3932 cur = idcDef->fields; 3933 do { 3934 prev = cur; 3935 cur = cur->next; 3936 if (prev->xpathComp != NULL) 3937 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3938 xmlFree(prev); 3939 } while (cur != NULL); 3940 } 3941 xmlFree(idcDef); 3942 } 3943 3944 /** 3945 * xmlSchemaFreeElement: 3946 * @schema: a schema element structure 3947 * 3948 * Deallocate a Schema Element structure. 3949 */ 3950 static void 3951 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3952 { 3953 if (elem == NULL) 3954 return; 3955 if (elem->annot != NULL) 3956 xmlSchemaFreeAnnot(elem->annot); 3957 if (elem->contModel != NULL) 3958 xmlRegFreeRegexp(elem->contModel); 3959 if (elem->defVal != NULL) 3960 xmlSchemaFreeValue(elem->defVal); 3961 xmlFree(elem); 3962 } 3963 3964 /** 3965 * xmlSchemaFreeFacet: 3966 * @facet: a schema facet structure 3967 * 3968 * Deallocate a Schema Facet structure. 3969 */ 3970 void 3971 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3972 { 3973 if (facet == NULL) 3974 return; 3975 if (facet->val != NULL) 3976 xmlSchemaFreeValue(facet->val); 3977 if (facet->regexp != NULL) 3978 xmlRegFreeRegexp(facet->regexp); 3979 if (facet->annot != NULL) 3980 xmlSchemaFreeAnnot(facet->annot); 3981 xmlFree(facet); 3982 } 3983 3984 /** 3985 * xmlSchemaFreeType: 3986 * @type: a schema type structure 3987 * 3988 * Deallocate a Schema Type structure. 3989 */ 3990 void 3991 xmlSchemaFreeType(xmlSchemaTypePtr type) 3992 { 3993 if (type == NULL) 3994 return; 3995 if (type->annot != NULL) 3996 xmlSchemaFreeAnnot(type->annot); 3997 if (type->facets != NULL) { 3998 xmlSchemaFacetPtr facet, next; 3999 4000 facet = type->facets; 4001 while (facet != NULL) { 4002 next = facet->next; 4003 xmlSchemaFreeFacet(facet); 4004 facet = next; 4005 } 4006 } 4007 if (type->attrUses != NULL) 4008 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 4009 if (type->memberTypes != NULL) 4010 xmlSchemaFreeTypeLinkList(type->memberTypes); 4011 if (type->facetSet != NULL) { 4012 xmlSchemaFacetLinkPtr next, link; 4013 4014 link = type->facetSet; 4015 do { 4016 next = link->next; 4017 xmlFree(link); 4018 link = next; 4019 } while (link != NULL); 4020 } 4021 if (type->contModel != NULL) 4022 xmlRegFreeRegexp(type->contModel); 4023 xmlFree(type); 4024 } 4025 4026 /** 4027 * xmlSchemaFreeModelGroupDef: 4028 * @item: a schema model group definition 4029 * 4030 * Deallocates a schema model group definition. 4031 */ 4032 static void 4033 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4034 { 4035 if (item->annot != NULL) 4036 xmlSchemaFreeAnnot(item->annot); 4037 xmlFree(item); 4038 } 4039 4040 /** 4041 * xmlSchemaFreeModelGroup: 4042 * @item: a schema model group 4043 * 4044 * Deallocates a schema model group structure. 4045 */ 4046 static void 4047 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4048 { 4049 if (item->annot != NULL) 4050 xmlSchemaFreeAnnot(item->annot); 4051 xmlFree(item); 4052 } 4053 4054 static void 4055 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4056 { 4057 if ((list == NULL) || (list->nbItems == 0)) 4058 return; 4059 { 4060 xmlSchemaTreeItemPtr item; 4061 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4062 int i; 4063 4064 for (i = 0; i < list->nbItems; i++) { 4065 item = items[i]; 4066 if (item == NULL) 4067 continue; 4068 switch (item->type) { 4069 case XML_SCHEMA_TYPE_SIMPLE: 4070 case XML_SCHEMA_TYPE_COMPLEX: 4071 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4072 break; 4073 case XML_SCHEMA_TYPE_ATTRIBUTE: 4074 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4075 break; 4076 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4077 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4078 break; 4079 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4080 xmlSchemaFreeAttributeUseProhib( 4081 (xmlSchemaAttributeUseProhibPtr) item); 4082 break; 4083 case XML_SCHEMA_TYPE_ELEMENT: 4084 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4085 break; 4086 case XML_SCHEMA_TYPE_PARTICLE: 4087 if (item->annot != NULL) 4088 xmlSchemaFreeAnnot(item->annot); 4089 xmlFree(item); 4090 break; 4091 case XML_SCHEMA_TYPE_SEQUENCE: 4092 case XML_SCHEMA_TYPE_CHOICE: 4093 case XML_SCHEMA_TYPE_ALL: 4094 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4095 break; 4096 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4097 xmlSchemaFreeAttributeGroup( 4098 (xmlSchemaAttributeGroupPtr) item); 4099 break; 4100 case XML_SCHEMA_TYPE_GROUP: 4101 xmlSchemaFreeModelGroupDef( 4102 (xmlSchemaModelGroupDefPtr) item); 4103 break; 4104 case XML_SCHEMA_TYPE_ANY: 4105 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4106 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4107 break; 4108 case XML_SCHEMA_TYPE_IDC_KEY: 4109 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4110 case XML_SCHEMA_TYPE_IDC_KEYREF: 4111 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4112 break; 4113 case XML_SCHEMA_TYPE_NOTATION: 4114 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4115 break; 4116 case XML_SCHEMA_EXTRA_QNAMEREF: 4117 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4118 break; 4119 default: { 4120 /* TODO: This should never be hit. */ 4121 xmlSchemaPSimpleInternalErr(NULL, 4122 "Internal error: xmlSchemaComponentListFree, " 4123 "unexpected component type '%s'\n", 4124 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4125 } 4126 break; 4127 } 4128 } 4129 list->nbItems = 0; 4130 } 4131 } 4132 4133 /** 4134 * xmlSchemaFree: 4135 * @schema: a schema structure 4136 * 4137 * Deallocate a Schema structure. 4138 */ 4139 void 4140 xmlSchemaFree(xmlSchemaPtr schema) 4141 { 4142 if (schema == NULL) 4143 return; 4144 /* @volatiles is not used anymore :-/ */ 4145 if (schema->volatiles != NULL) 4146 TODO 4147 /* 4148 * Note that those slots are not responsible for freeing 4149 * schema components anymore; this will now be done by 4150 * the schema buckets. 4151 */ 4152 if (schema->notaDecl != NULL) 4153 xmlHashFree(schema->notaDecl, NULL); 4154 if (schema->attrDecl != NULL) 4155 xmlHashFree(schema->attrDecl, NULL); 4156 if (schema->attrgrpDecl != NULL) 4157 xmlHashFree(schema->attrgrpDecl, NULL); 4158 if (schema->elemDecl != NULL) 4159 xmlHashFree(schema->elemDecl, NULL); 4160 if (schema->typeDecl != NULL) 4161 xmlHashFree(schema->typeDecl, NULL); 4162 if (schema->groupDecl != NULL) 4163 xmlHashFree(schema->groupDecl, NULL); 4164 if (schema->idcDef != NULL) 4165 xmlHashFree(schema->idcDef, NULL); 4166 4167 if (schema->schemasImports != NULL) 4168 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry); 4169 if (schema->includes != NULL) { 4170 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4171 int i; 4172 for (i = 0; i < list->nbItems; i++) { 4173 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4174 } 4175 xmlSchemaItemListFree(list); 4176 } 4177 if (schema->annot != NULL) 4178 xmlSchemaFreeAnnot(schema->annot); 4179 /* Never free the doc here, since this will be done by the buckets. */ 4180 4181 xmlDictFree(schema->dict); 4182 xmlFree(schema); 4183 } 4184 4185 /************************************************************************ 4186 * * 4187 * Debug functions * 4188 * * 4189 ************************************************************************/ 4190 4191 #ifdef LIBXML_OUTPUT_ENABLED 4192 4193 static void 4194 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4195 4196 /** 4197 * xmlSchemaElementDump: 4198 * @elem: an element 4199 * @output: the file output 4200 * 4201 * Dump the element 4202 */ 4203 static void 4204 xmlSchemaElementDump(void *payload, void *data, 4205 const xmlChar * name ATTRIBUTE_UNUSED, 4206 const xmlChar * namespace ATTRIBUTE_UNUSED, 4207 const xmlChar * context ATTRIBUTE_UNUSED) 4208 { 4209 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload; 4210 FILE *output = (FILE *) data; 4211 if (elem == NULL) 4212 return; 4213 4214 4215 fprintf(output, "Element"); 4216 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4217 fprintf(output, " (global)"); 4218 fprintf(output, ": '%s' ", elem->name); 4219 if (namespace != NULL) 4220 fprintf(output, "ns '%s'", namespace); 4221 fprintf(output, "\n"); 4222 #if 0 4223 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4224 fprintf(output, " min %d ", elem->minOccurs); 4225 if (elem->maxOccurs >= UNBOUNDED) 4226 fprintf(output, "max: unbounded\n"); 4227 else if (elem->maxOccurs != 1) 4228 fprintf(output, "max: %d\n", elem->maxOccurs); 4229 else 4230 fprintf(output, "\n"); 4231 } 4232 #endif 4233 /* 4234 * Misc other properties. 4235 */ 4236 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4237 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4238 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4239 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4240 fprintf(output, " props: "); 4241 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4242 fprintf(output, "[fixed] "); 4243 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4244 fprintf(output, "[default] "); 4245 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4246 fprintf(output, "[abstract] "); 4247 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4248 fprintf(output, "[nillable] "); 4249 fprintf(output, "\n"); 4250 } 4251 /* 4252 * Default/fixed value. 4253 */ 4254 if (elem->value != NULL) 4255 fprintf(output, " value: '%s'\n", elem->value); 4256 /* 4257 * Type. 4258 */ 4259 if (elem->namedType != NULL) { 4260 fprintf(output, " type: '%s' ", elem->namedType); 4261 if (elem->namedTypeNs != NULL) 4262 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4263 else 4264 fprintf(output, "\n"); 4265 } else if (elem->subtypes != NULL) { 4266 /* 4267 * Dump local types. 4268 */ 4269 xmlSchemaTypeDump(elem->subtypes, output); 4270 } 4271 /* 4272 * Substitution group. 4273 */ 4274 if (elem->substGroup != NULL) { 4275 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4276 if (elem->substGroupNs != NULL) 4277 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4278 else 4279 fprintf(output, "\n"); 4280 } 4281 } 4282 4283 /** 4284 * xmlSchemaAnnotDump: 4285 * @output: the file output 4286 * @annot: a annotation 4287 * 4288 * Dump the annotation 4289 */ 4290 static void 4291 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4292 { 4293 xmlChar *content; 4294 4295 if (annot == NULL) 4296 return; 4297 4298 content = xmlNodeGetContent(annot->content); 4299 if (content != NULL) { 4300 fprintf(output, " Annot: %s\n", content); 4301 xmlFree(content); 4302 } else 4303 fprintf(output, " Annot: empty\n"); 4304 } 4305 4306 /** 4307 * xmlSchemaContentModelDump: 4308 * @particle: the schema particle 4309 * @output: the file output 4310 * @depth: the depth used for intentation 4311 * 4312 * Dump a SchemaType structure 4313 */ 4314 static void 4315 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4316 { 4317 xmlChar *str = NULL; 4318 xmlSchemaTreeItemPtr term; 4319 char shift[100]; 4320 int i; 4321 4322 if (particle == NULL) 4323 return; 4324 for (i = 0;((i < depth) && (i < 25));i++) 4325 shift[2 * i] = shift[2 * i + 1] = ' '; 4326 shift[2 * i] = shift[2 * i + 1] = 0; 4327 fprintf(output, "%s", shift); 4328 if (particle->children == NULL) { 4329 fprintf(output, "MISSING particle term\n"); 4330 return; 4331 } 4332 term = particle->children; 4333 if (term == NULL) { 4334 fprintf(output, "(NULL)"); 4335 } else { 4336 switch (term->type) { 4337 case XML_SCHEMA_TYPE_ELEMENT: 4338 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4339 ((xmlSchemaElementPtr)term)->targetNamespace, 4340 ((xmlSchemaElementPtr)term)->name)); 4341 FREE_AND_NULL(str); 4342 break; 4343 case XML_SCHEMA_TYPE_SEQUENCE: 4344 fprintf(output, "SEQUENCE"); 4345 break; 4346 case XML_SCHEMA_TYPE_CHOICE: 4347 fprintf(output, "CHOICE"); 4348 break; 4349 case XML_SCHEMA_TYPE_ALL: 4350 fprintf(output, "ALL"); 4351 break; 4352 case XML_SCHEMA_TYPE_ANY: 4353 fprintf(output, "ANY"); 4354 break; 4355 default: 4356 fprintf(output, "UNKNOWN\n"); 4357 return; 4358 } 4359 } 4360 if (particle->minOccurs != 1) 4361 fprintf(output, " min: %d", particle->minOccurs); 4362 if (particle->maxOccurs >= UNBOUNDED) 4363 fprintf(output, " max: unbounded"); 4364 else if (particle->maxOccurs != 1) 4365 fprintf(output, " max: %d", particle->maxOccurs); 4366 fprintf(output, "\n"); 4367 if (term && 4368 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4369 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4370 (term->type == XML_SCHEMA_TYPE_ALL)) && 4371 (term->children != NULL)) { 4372 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4373 output, depth +1); 4374 } 4375 if (particle->next != NULL) 4376 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4377 output, depth); 4378 } 4379 4380 /** 4381 * xmlSchemaAttrUsesDump: 4382 * @uses: attribute uses list 4383 * @output: the file output 4384 * 4385 * Dumps a list of attribute use components. 4386 */ 4387 static void 4388 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4389 { 4390 xmlSchemaAttributeUsePtr use; 4391 xmlSchemaAttributeUseProhibPtr prohib; 4392 xmlSchemaQNameRefPtr ref; 4393 const xmlChar *name, *tns; 4394 xmlChar *str = NULL; 4395 int i; 4396 4397 if ((uses == NULL) || (uses->nbItems == 0)) 4398 return; 4399 4400 fprintf(output, " attributes:\n"); 4401 for (i = 0; i < uses->nbItems; i++) { 4402 use = uses->items[i]; 4403 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4404 fprintf(output, " [prohibition] "); 4405 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4406 name = prohib->name; 4407 tns = prohib->targetNamespace; 4408 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4409 fprintf(output, " [reference] "); 4410 ref = (xmlSchemaQNameRefPtr) use; 4411 name = ref->name; 4412 tns = ref->targetNamespace; 4413 } else { 4414 fprintf(output, " [use] "); 4415 name = WXS_ATTRUSE_DECL_NAME(use); 4416 tns = WXS_ATTRUSE_DECL_TNS(use); 4417 } 4418 fprintf(output, "'%s'\n", 4419 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4420 FREE_AND_NULL(str); 4421 } 4422 } 4423 4424 /** 4425 * xmlSchemaTypeDump: 4426 * @output: the file output 4427 * @type: a type structure 4428 * 4429 * Dump a SchemaType structure 4430 */ 4431 static void 4432 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4433 { 4434 if (type == NULL) { 4435 fprintf(output, "Type: NULL\n"); 4436 return; 4437 } 4438 fprintf(output, "Type: "); 4439 if (type->name != NULL) 4440 fprintf(output, "'%s' ", type->name); 4441 else 4442 fprintf(output, "(no name) "); 4443 if (type->targetNamespace != NULL) 4444 fprintf(output, "ns '%s' ", type->targetNamespace); 4445 switch (type->type) { 4446 case XML_SCHEMA_TYPE_BASIC: 4447 fprintf(output, "[basic] "); 4448 break; 4449 case XML_SCHEMA_TYPE_SIMPLE: 4450 fprintf(output, "[simple] "); 4451 break; 4452 case XML_SCHEMA_TYPE_COMPLEX: 4453 fprintf(output, "[complex] "); 4454 break; 4455 case XML_SCHEMA_TYPE_SEQUENCE: 4456 fprintf(output, "[sequence] "); 4457 break; 4458 case XML_SCHEMA_TYPE_CHOICE: 4459 fprintf(output, "[choice] "); 4460 break; 4461 case XML_SCHEMA_TYPE_ALL: 4462 fprintf(output, "[all] "); 4463 break; 4464 case XML_SCHEMA_TYPE_UR: 4465 fprintf(output, "[ur] "); 4466 break; 4467 case XML_SCHEMA_TYPE_RESTRICTION: 4468 fprintf(output, "[restriction] "); 4469 break; 4470 case XML_SCHEMA_TYPE_EXTENSION: 4471 fprintf(output, "[extension] "); 4472 break; 4473 default: 4474 fprintf(output, "[unknown type %d] ", type->type); 4475 break; 4476 } 4477 fprintf(output, "content: "); 4478 switch (type->contentType) { 4479 case XML_SCHEMA_CONTENT_UNKNOWN: 4480 fprintf(output, "[unknown] "); 4481 break; 4482 case XML_SCHEMA_CONTENT_EMPTY: 4483 fprintf(output, "[empty] "); 4484 break; 4485 case XML_SCHEMA_CONTENT_ELEMENTS: 4486 fprintf(output, "[element] "); 4487 break; 4488 case XML_SCHEMA_CONTENT_MIXED: 4489 fprintf(output, "[mixed] "); 4490 break; 4491 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4492 /* not used. */ 4493 break; 4494 case XML_SCHEMA_CONTENT_BASIC: 4495 fprintf(output, "[basic] "); 4496 break; 4497 case XML_SCHEMA_CONTENT_SIMPLE: 4498 fprintf(output, "[simple] "); 4499 break; 4500 case XML_SCHEMA_CONTENT_ANY: 4501 fprintf(output, "[any] "); 4502 break; 4503 } 4504 fprintf(output, "\n"); 4505 if (type->base != NULL) { 4506 fprintf(output, " base type: '%s'", type->base); 4507 if (type->baseNs != NULL) 4508 fprintf(output, " ns '%s'\n", type->baseNs); 4509 else 4510 fprintf(output, "\n"); 4511 } 4512 if (type->attrUses != NULL) 4513 xmlSchemaAttrUsesDump(type->attrUses, output); 4514 if (type->annot != NULL) 4515 xmlSchemaAnnotDump(output, type->annot); 4516 #ifdef DUMP_CONTENT_MODEL 4517 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4518 (type->subtypes != NULL)) { 4519 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4520 output, 1); 4521 } 4522 #endif 4523 } 4524 4525 static void 4526 xmlSchemaTypeDumpEntry(void *type, void *output, 4527 const xmlChar *name ATTRIBUTE_UNUSED) 4528 { 4529 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output); 4530 } 4531 4532 /** 4533 * xmlSchemaDump: 4534 * @output: the file output 4535 * @schema: a schema structure 4536 * 4537 * Dump a Schema structure. 4538 */ 4539 void 4540 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4541 { 4542 if (output == NULL) 4543 return; 4544 if (schema == NULL) { 4545 fprintf(output, "Schemas: NULL\n"); 4546 return; 4547 } 4548 fprintf(output, "Schemas: "); 4549 if (schema->name != NULL) 4550 fprintf(output, "%s, ", schema->name); 4551 else 4552 fprintf(output, "no name, "); 4553 if (schema->targetNamespace != NULL) 4554 fprintf(output, "%s", (const char *) schema->targetNamespace); 4555 else 4556 fprintf(output, "no target namespace"); 4557 fprintf(output, "\n"); 4558 if (schema->annot != NULL) 4559 xmlSchemaAnnotDump(output, schema->annot); 4560 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output); 4561 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output); 4562 } 4563 4564 #ifdef DEBUG_IDC_NODE_TABLE 4565 /** 4566 * xmlSchemaDebugDumpIDCTable: 4567 * @vctxt: the WXS validation context 4568 * 4569 * Displays the current IDC table for debug purposes. 4570 */ 4571 static void 4572 xmlSchemaDebugDumpIDCTable(FILE * output, 4573 const xmlChar *namespaceName, 4574 const xmlChar *localName, 4575 xmlSchemaPSVIIDCBindingPtr bind) 4576 { 4577 xmlChar *str = NULL; 4578 const xmlChar *value; 4579 xmlSchemaPSVIIDCNodePtr tab; 4580 xmlSchemaPSVIIDCKeyPtr key; 4581 int i, j, res; 4582 4583 fprintf(output, "IDC: TABLES on '%s'\n", 4584 xmlSchemaFormatQName(&str, namespaceName, localName)); 4585 FREE_AND_NULL(str) 4586 4587 if (bind == NULL) 4588 return; 4589 do { 4590 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4591 xmlSchemaGetComponentQName(&str, 4592 bind->definition), bind->nbNodes); 4593 FREE_AND_NULL(str) 4594 for (i = 0; i < bind->nbNodes; i++) { 4595 tab = bind->nodeTable[i]; 4596 fprintf(output, " ( "); 4597 for (j = 0; j < bind->definition->nbFields; j++) { 4598 key = tab->keys[j]; 4599 if ((key != NULL) && (key->val != NULL)) { 4600 res = xmlSchemaGetCanonValue(key->val, &value); 4601 if (res >= 0) 4602 fprintf(output, "'%s' ", value); 4603 else 4604 fprintf(output, "CANON-VALUE-FAILED "); 4605 if (res == 0) 4606 FREE_AND_NULL(value) 4607 } else if (key != NULL) 4608 fprintf(output, "(no val), "); 4609 else 4610 fprintf(output, "(key missing), "); 4611 } 4612 fprintf(output, ")\n"); 4613 } 4614 if (bind->dupls && bind->dupls->nbItems) { 4615 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4616 for (i = 0; i < bind->dupls->nbItems; i++) { 4617 tab = bind->dupls->items[i]; 4618 fprintf(output, " ( "); 4619 for (j = 0; j < bind->definition->nbFields; j++) { 4620 key = tab->keys[j]; 4621 if ((key != NULL) && (key->val != NULL)) { 4622 res = xmlSchemaGetCanonValue(key->val, &value); 4623 if (res >= 0) 4624 fprintf(output, "'%s' ", value); 4625 else 4626 fprintf(output, "CANON-VALUE-FAILED "); 4627 if (res == 0) 4628 FREE_AND_NULL(value) 4629 } else if (key != NULL) 4630 fprintf(output, "(no val), "); 4631 else 4632 fprintf(output, "(key missing), "); 4633 } 4634 fprintf(output, ")\n"); 4635 } 4636 } 4637 bind = bind->next; 4638 } while (bind != NULL); 4639 } 4640 #endif /* DEBUG_IDC */ 4641 #endif /* LIBXML_OUTPUT_ENABLED */ 4642 4643 /************************************************************************ 4644 * * 4645 * Utilities * 4646 * * 4647 ************************************************************************/ 4648 4649 /** 4650 * xmlSchemaGetPropNode: 4651 * @node: the element node 4652 * @name: the name of the attribute 4653 * 4654 * Seeks an attribute with a name of @name in 4655 * no namespace. 4656 * 4657 * Returns the attribute or NULL if not present. 4658 */ 4659 static xmlAttrPtr 4660 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4661 { 4662 xmlAttrPtr prop; 4663 4664 if ((node == NULL) || (name == NULL)) 4665 return(NULL); 4666 prop = node->properties; 4667 while (prop != NULL) { 4668 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4669 return(prop); 4670 prop = prop->next; 4671 } 4672 return (NULL); 4673 } 4674 4675 /** 4676 * xmlSchemaGetPropNodeNs: 4677 * @node: the element node 4678 * @uri: the uri 4679 * @name: the name of the attribute 4680 * 4681 * Seeks an attribute with a local name of @name and 4682 * a namespace URI of @uri. 4683 * 4684 * Returns the attribute or NULL if not present. 4685 */ 4686 static xmlAttrPtr 4687 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4688 { 4689 xmlAttrPtr prop; 4690 4691 if ((node == NULL) || (name == NULL)) 4692 return(NULL); 4693 prop = node->properties; 4694 while (prop != NULL) { 4695 if ((prop->ns != NULL) && 4696 xmlStrEqual(prop->name, BAD_CAST name) && 4697 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4698 return(prop); 4699 prop = prop->next; 4700 } 4701 return (NULL); 4702 } 4703 4704 static const xmlChar * 4705 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4706 { 4707 xmlChar *val; 4708 const xmlChar *ret; 4709 4710 val = xmlNodeGetContent(node); 4711 if (val == NULL) 4712 val = xmlStrdup((xmlChar *)""); 4713 ret = xmlDictLookup(ctxt->dict, val, -1); 4714 xmlFree(val); 4715 return(ret); 4716 } 4717 4718 static const xmlChar * 4719 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4720 { 4721 return((const xmlChar*) xmlNodeGetContent(node)); 4722 } 4723 4724 /** 4725 * xmlSchemaGetProp: 4726 * @ctxt: the parser context 4727 * @node: the node 4728 * @name: the property name 4729 * 4730 * Read a attribute value and internalize the string 4731 * 4732 * Returns the string or NULL if not present. 4733 */ 4734 static const xmlChar * 4735 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4736 const char *name) 4737 { 4738 xmlChar *val; 4739 const xmlChar *ret; 4740 4741 val = xmlGetNoNsProp(node, BAD_CAST name); 4742 if (val == NULL) 4743 return(NULL); 4744 ret = xmlDictLookup(ctxt->dict, val, -1); 4745 xmlFree(val); 4746 return(ret); 4747 } 4748 4749 /************************************************************************ 4750 * * 4751 * Parsing functions * 4752 * * 4753 ************************************************************************/ 4754 4755 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4756 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4757 ret = xmlHashLookup(schema->slot, name); \ 4758 if (ret != NULL) goto exit; \ 4759 } \ 4760 if (xmlHashSize(schema->schemasImports) > 1) { \ 4761 xmlSchemaImportPtr import; \ 4762 if (nsName == NULL) \ 4763 import = xmlHashLookup(schema->schemasImports, \ 4764 XML_SCHEMAS_NO_NAMESPACE); \ 4765 else \ 4766 import = xmlHashLookup(schema->schemasImports, nsName); \ 4767 if (import == NULL) \ 4768 goto exit; \ 4769 ret = xmlHashLookup(import->schema->slot, name); \ 4770 } 4771 4772 /** 4773 * xmlSchemaGetElem: 4774 * @schema: the schema context 4775 * @name: the element name 4776 * @ns: the element namespace 4777 * 4778 * Lookup a global element declaration in the schema. 4779 * 4780 * Returns the element declaration or NULL if not found. 4781 */ 4782 static xmlSchemaElementPtr 4783 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4784 const xmlChar * nsName) 4785 { 4786 xmlSchemaElementPtr ret = NULL; 4787 4788 if ((name == NULL) || (schema == NULL)) 4789 return(NULL); 4790 if (schema != NULL) { 4791 WXS_FIND_GLOBAL_ITEM(elemDecl) 4792 } 4793 exit: 4794 #ifdef DEBUG 4795 if (ret == NULL) { 4796 if (nsName == NULL) 4797 fprintf(stderr, "Unable to lookup element decl. %s", name); 4798 else 4799 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4800 nsName); 4801 } 4802 #endif 4803 return (ret); 4804 } 4805 4806 /** 4807 * xmlSchemaGetType: 4808 * @schema: the main schema 4809 * @name: the type's name 4810 * nsName: the type's namespace 4811 * 4812 * Lookup a type in the schemas or the predefined types 4813 * 4814 * Returns the group definition or NULL if not found. 4815 */ 4816 static xmlSchemaTypePtr 4817 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4818 const xmlChar * nsName) 4819 { 4820 xmlSchemaTypePtr ret = NULL; 4821 4822 if (name == NULL) 4823 return (NULL); 4824 /* First try the built-in types. */ 4825 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4826 ret = xmlSchemaGetPredefinedType(name, nsName); 4827 if (ret != NULL) 4828 goto exit; 4829 /* 4830 * Note that we try the parsed schemas as well here 4831 * since one might have parsed the S4S, which contain more 4832 * than the built-in types. 4833 * TODO: Can we optimize this? 4834 */ 4835 } 4836 if (schema != NULL) { 4837 WXS_FIND_GLOBAL_ITEM(typeDecl) 4838 } 4839 exit: 4840 4841 #ifdef DEBUG 4842 if (ret == NULL) { 4843 if (nsName == NULL) 4844 fprintf(stderr, "Unable to lookup type %s", name); 4845 else 4846 fprintf(stderr, "Unable to lookup type %s:%s", name, 4847 nsName); 4848 } 4849 #endif 4850 return (ret); 4851 } 4852 4853 /** 4854 * xmlSchemaGetAttributeDecl: 4855 * @schema: the context of the schema 4856 * @name: the name of the attribute 4857 * @ns: the target namespace of the attribute 4858 * 4859 * Lookup a an attribute in the schema or imported schemas 4860 * 4861 * Returns the attribute declaration or NULL if not found. 4862 */ 4863 static xmlSchemaAttributePtr 4864 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4865 const xmlChar * nsName) 4866 { 4867 xmlSchemaAttributePtr ret = NULL; 4868 4869 if ((name == NULL) || (schema == NULL)) 4870 return (NULL); 4871 if (schema != NULL) { 4872 WXS_FIND_GLOBAL_ITEM(attrDecl) 4873 } 4874 exit: 4875 #ifdef DEBUG 4876 if (ret == NULL) { 4877 if (nsName == NULL) 4878 fprintf(stderr, "Unable to lookup attribute %s", name); 4879 else 4880 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4881 nsName); 4882 } 4883 #endif 4884 return (ret); 4885 } 4886 4887 /** 4888 * xmlSchemaGetAttributeGroup: 4889 * @schema: the context of the schema 4890 * @name: the name of the attribute group 4891 * @ns: the target namespace of the attribute group 4892 * 4893 * Lookup a an attribute group in the schema or imported schemas 4894 * 4895 * Returns the attribute group definition or NULL if not found. 4896 */ 4897 static xmlSchemaAttributeGroupPtr 4898 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4899 const xmlChar * nsName) 4900 { 4901 xmlSchemaAttributeGroupPtr ret = NULL; 4902 4903 if ((name == NULL) || (schema == NULL)) 4904 return (NULL); 4905 if (schema != NULL) { 4906 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4907 } 4908 exit: 4909 /* TODO: 4910 if ((ret != NULL) && (ret->redef != NULL)) { 4911 * Return the last redefinition. * 4912 ret = ret->redef; 4913 } 4914 */ 4915 #ifdef DEBUG 4916 if (ret == NULL) { 4917 if (nsName == NULL) 4918 fprintf(stderr, "Unable to lookup attribute group %s", name); 4919 else 4920 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4921 nsName); 4922 } 4923 #endif 4924 return (ret); 4925 } 4926 4927 /** 4928 * xmlSchemaGetGroup: 4929 * @schema: the context of the schema 4930 * @name: the name of the group 4931 * @ns: the target namespace of the group 4932 * 4933 * Lookup a group in the schema or imported schemas 4934 * 4935 * Returns the group definition or NULL if not found. 4936 */ 4937 static xmlSchemaModelGroupDefPtr 4938 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4939 const xmlChar * nsName) 4940 { 4941 xmlSchemaModelGroupDefPtr ret = NULL; 4942 4943 if ((name == NULL) || (schema == NULL)) 4944 return (NULL); 4945 if (schema != NULL) { 4946 WXS_FIND_GLOBAL_ITEM(groupDecl) 4947 } 4948 exit: 4949 4950 #ifdef DEBUG 4951 if (ret == NULL) { 4952 if (nsName == NULL) 4953 fprintf(stderr, "Unable to lookup group %s", name); 4954 else 4955 fprintf(stderr, "Unable to lookup group %s:%s", name, 4956 nsName); 4957 } 4958 #endif 4959 return (ret); 4960 } 4961 4962 static xmlSchemaNotationPtr 4963 xmlSchemaGetNotation(xmlSchemaPtr schema, 4964 const xmlChar *name, 4965 const xmlChar *nsName) 4966 { 4967 xmlSchemaNotationPtr ret = NULL; 4968 4969 if ((name == NULL) || (schema == NULL)) 4970 return (NULL); 4971 if (schema != NULL) { 4972 WXS_FIND_GLOBAL_ITEM(notaDecl) 4973 } 4974 exit: 4975 return (ret); 4976 } 4977 4978 static xmlSchemaIDCPtr 4979 xmlSchemaGetIDC(xmlSchemaPtr schema, 4980 const xmlChar *name, 4981 const xmlChar *nsName) 4982 { 4983 xmlSchemaIDCPtr ret = NULL; 4984 4985 if ((name == NULL) || (schema == NULL)) 4986 return (NULL); 4987 if (schema != NULL) { 4988 WXS_FIND_GLOBAL_ITEM(idcDef) 4989 } 4990 exit: 4991 return (ret); 4992 } 4993 4994 /** 4995 * xmlSchemaGetNamedComponent: 4996 * @schema: the schema 4997 * @name: the name of the group 4998 * @ns: the target namespace of the group 4999 * 5000 * Lookup a group in the schema or imported schemas 5001 * 5002 * Returns the group definition or NULL if not found. 5003 */ 5004 static xmlSchemaBasicItemPtr 5005 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 5006 xmlSchemaTypeType itemType, 5007 const xmlChar *name, 5008 const xmlChar *targetNs) 5009 { 5010 switch (itemType) { 5011 case XML_SCHEMA_TYPE_GROUP: 5012 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 5013 name, targetNs)); 5014 case XML_SCHEMA_TYPE_ELEMENT: 5015 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 5016 name, targetNs)); 5017 default: 5018 TODO 5019 return (NULL); 5020 } 5021 } 5022 5023 /************************************************************************ 5024 * * 5025 * Parsing functions * 5026 * * 5027 ************************************************************************/ 5028 5029 #define IS_BLANK_NODE(n) \ 5030 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 5031 5032 /** 5033 * xmlSchemaIsBlank: 5034 * @str: a string 5035 * @len: the length of the string or -1 5036 * 5037 * Check if a string is ignorable 5038 * 5039 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5040 */ 5041 static int 5042 xmlSchemaIsBlank(xmlChar * str, int len) 5043 { 5044 if (str == NULL) 5045 return (1); 5046 if (len < 0) { 5047 while (*str != 0) { 5048 if (!(IS_BLANK_CH(*str))) 5049 return (0); 5050 str++; 5051 } 5052 } else while ((*str != 0) && (len != 0)) { 5053 if (!(IS_BLANK_CH(*str))) 5054 return (0); 5055 str++; 5056 len--; 5057 } 5058 5059 return (1); 5060 } 5061 5062 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5063 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5064 /* 5065 * xmlSchemaFindRedefCompInGraph: 5066 * ATTENTION TODO: This uses pointer comp. for strings. 5067 */ 5068 static xmlSchemaBasicItemPtr 5069 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5070 xmlSchemaTypeType type, 5071 const xmlChar *name, 5072 const xmlChar *nsName) 5073 { 5074 xmlSchemaBasicItemPtr ret; 5075 int i; 5076 5077 if ((bucket == NULL) || (name == NULL)) 5078 return(NULL); 5079 if ((bucket->globals == NULL) || 5080 (bucket->globals->nbItems == 0)) 5081 goto subschemas; 5082 /* 5083 * Search in global components. 5084 */ 5085 for (i = 0; i < bucket->globals->nbItems; i++) { 5086 ret = bucket->globals->items[i]; 5087 if (ret->type == type) { 5088 switch (type) { 5089 case XML_SCHEMA_TYPE_COMPLEX: 5090 case XML_SCHEMA_TYPE_SIMPLE: 5091 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5092 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5093 nsName)) 5094 { 5095 return(ret); 5096 } 5097 break; 5098 case XML_SCHEMA_TYPE_GROUP: 5099 if ((WXS_COMP_NAME(ret, 5100 xmlSchemaModelGroupDefPtr) == name) && 5101 (WXS_COMP_TNS(ret, 5102 xmlSchemaModelGroupDefPtr) == nsName)) 5103 { 5104 return(ret); 5105 } 5106 break; 5107 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5108 if ((WXS_COMP_NAME(ret, 5109 xmlSchemaAttributeGroupPtr) == name) && 5110 (WXS_COMP_TNS(ret, 5111 xmlSchemaAttributeGroupPtr) == nsName)) 5112 { 5113 return(ret); 5114 } 5115 break; 5116 default: 5117 /* Should not be hit. */ 5118 return(NULL); 5119 } 5120 } 5121 } 5122 subschemas: 5123 /* 5124 * Process imported/included schemas. 5125 */ 5126 if (bucket->relations != NULL) { 5127 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5128 5129 /* 5130 * TODO: Marking the bucket will not avoid multiple searches 5131 * in the same schema, but avoids at least circularity. 5132 */ 5133 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5134 do { 5135 if ((rel->bucket != NULL) && 5136 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5137 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5138 type, name, nsName); 5139 if (ret != NULL) 5140 return(ret); 5141 } 5142 rel = rel->next; 5143 } while (rel != NULL); 5144 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5145 } 5146 return(NULL); 5147 } 5148 5149 /** 5150 * xmlSchemaAddNotation: 5151 * @ctxt: a schema parser context 5152 * @schema: the schema being built 5153 * @name: the item name 5154 * 5155 * Add an XML schema annotation declaration 5156 * *WARNING* this interface is highly subject to change 5157 * 5158 * Returns the new struture or NULL in case of error 5159 */ 5160 static xmlSchemaNotationPtr 5161 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5162 const xmlChar *name, const xmlChar *nsName, 5163 xmlNodePtr node ATTRIBUTE_UNUSED) 5164 { 5165 xmlSchemaNotationPtr ret = NULL; 5166 5167 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5168 return (NULL); 5169 5170 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5171 if (ret == NULL) { 5172 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5173 return (NULL); 5174 } 5175 memset(ret, 0, sizeof(xmlSchemaNotation)); 5176 ret->type = XML_SCHEMA_TYPE_NOTATION; 5177 ret->name = name; 5178 ret->targetNamespace = nsName; 5179 /* TODO: do we need the node to be set? 5180 * ret->node = node;*/ 5181 WXS_ADD_GLOBAL(ctxt, ret); 5182 return (ret); 5183 } 5184 5185 /** 5186 * xmlSchemaAddAttribute: 5187 * @ctxt: a schema parser context 5188 * @schema: the schema being built 5189 * @name: the item name 5190 * @namespace: the namespace 5191 * 5192 * Add an XML schema Attrribute declaration 5193 * *WARNING* this interface is highly subject to change 5194 * 5195 * Returns the new struture or NULL in case of error 5196 */ 5197 static xmlSchemaAttributePtr 5198 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5199 const xmlChar * name, const xmlChar * nsName, 5200 xmlNodePtr node, int topLevel) 5201 { 5202 xmlSchemaAttributePtr ret = NULL; 5203 5204 if ((ctxt == NULL) || (schema == NULL)) 5205 return (NULL); 5206 5207 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5208 if (ret == NULL) { 5209 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5210 return (NULL); 5211 } 5212 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5213 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5214 ret->node = node; 5215 ret->name = name; 5216 ret->targetNamespace = nsName; 5217 5218 if (topLevel) 5219 WXS_ADD_GLOBAL(ctxt, ret); 5220 else 5221 WXS_ADD_LOCAL(ctxt, ret); 5222 WXS_ADD_PENDING(ctxt, ret); 5223 return (ret); 5224 } 5225 5226 /** 5227 * xmlSchemaAddAttributeUse: 5228 * @ctxt: a schema parser context 5229 * @schema: the schema being built 5230 * @name: the item name 5231 * @namespace: the namespace 5232 * 5233 * Add an XML schema Attrribute declaration 5234 * *WARNING* this interface is highly subject to change 5235 * 5236 * Returns the new struture or NULL in case of error 5237 */ 5238 static xmlSchemaAttributeUsePtr 5239 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5240 xmlNodePtr node) 5241 { 5242 xmlSchemaAttributeUsePtr ret = NULL; 5243 5244 if (pctxt == NULL) 5245 return (NULL); 5246 5247 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5248 if (ret == NULL) { 5249 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5250 return (NULL); 5251 } 5252 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5253 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5254 ret->node = node; 5255 5256 WXS_ADD_LOCAL(pctxt, ret); 5257 return (ret); 5258 } 5259 5260 /* 5261 * xmlSchemaAddRedef: 5262 * 5263 * Adds a redefinition information. This is used at a later stage to: 5264 * resolve references to the redefined components and to check constraints. 5265 */ 5266 static xmlSchemaRedefPtr 5267 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5268 xmlSchemaBucketPtr targetBucket, 5269 void *item, 5270 const xmlChar *refName, 5271 const xmlChar *refTargetNs) 5272 { 5273 xmlSchemaRedefPtr ret; 5274 5275 ret = (xmlSchemaRedefPtr) 5276 xmlMalloc(sizeof(xmlSchemaRedef)); 5277 if (ret == NULL) { 5278 xmlSchemaPErrMemory(pctxt, 5279 "allocating redefinition info", NULL); 5280 return (NULL); 5281 } 5282 memset(ret, 0, sizeof(xmlSchemaRedef)); 5283 ret->item = item; 5284 ret->targetBucket = targetBucket; 5285 ret->refName = refName; 5286 ret->refTargetNs = refTargetNs; 5287 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5288 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5289 else 5290 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5291 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5292 5293 return (ret); 5294 } 5295 5296 /** 5297 * xmlSchemaAddAttributeGroupDefinition: 5298 * @ctxt: a schema parser context 5299 * @schema: the schema being built 5300 * @name: the item name 5301 * @nsName: the target namespace 5302 * @node: the corresponding node 5303 * 5304 * Add an XML schema Attrribute Group definition. 5305 * 5306 * Returns the new struture or NULL in case of error 5307 */ 5308 static xmlSchemaAttributeGroupPtr 5309 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5310 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5311 const xmlChar *name, 5312 const xmlChar *nsName, 5313 xmlNodePtr node) 5314 { 5315 xmlSchemaAttributeGroupPtr ret = NULL; 5316 5317 if ((pctxt == NULL) || (name == NULL)) 5318 return (NULL); 5319 5320 ret = (xmlSchemaAttributeGroupPtr) 5321 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5322 if (ret == NULL) { 5323 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5324 return (NULL); 5325 } 5326 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5327 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5328 ret->name = name; 5329 ret->targetNamespace = nsName; 5330 ret->node = node; 5331 5332 /* TODO: Remove the flag. */ 5333 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5334 if (pctxt->isRedefine) { 5335 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5336 ret, name, nsName); 5337 if (pctxt->redef == NULL) { 5338 xmlFree(ret); 5339 return(NULL); 5340 } 5341 pctxt->redefCounter = 0; 5342 } 5343 WXS_ADD_GLOBAL(pctxt, ret); 5344 WXS_ADD_PENDING(pctxt, ret); 5345 return (ret); 5346 } 5347 5348 /** 5349 * xmlSchemaAddElement: 5350 * @ctxt: a schema parser context 5351 * @schema: the schema being built 5352 * @name: the type name 5353 * @namespace: the type namespace 5354 * 5355 * Add an XML schema Element declaration 5356 * *WARNING* this interface is highly subject to change 5357 * 5358 * Returns the new struture or NULL in case of error 5359 */ 5360 static xmlSchemaElementPtr 5361 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5362 const xmlChar * name, const xmlChar * nsName, 5363 xmlNodePtr node, int topLevel) 5364 { 5365 xmlSchemaElementPtr ret = NULL; 5366 5367 if ((ctxt == NULL) || (name == NULL)) 5368 return (NULL); 5369 5370 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5371 if (ret == NULL) { 5372 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5373 return (NULL); 5374 } 5375 memset(ret, 0, sizeof(xmlSchemaElement)); 5376 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5377 ret->name = name; 5378 ret->targetNamespace = nsName; 5379 ret->node = node; 5380 5381 if (topLevel) 5382 WXS_ADD_GLOBAL(ctxt, ret); 5383 else 5384 WXS_ADD_LOCAL(ctxt, ret); 5385 WXS_ADD_PENDING(ctxt, ret); 5386 return (ret); 5387 } 5388 5389 /** 5390 * xmlSchemaAddType: 5391 * @ctxt: a schema parser context 5392 * @schema: the schema being built 5393 * @name: the item name 5394 * @namespace: the namespace 5395 * 5396 * Add an XML schema item 5397 * *WARNING* this interface is highly subject to change 5398 * 5399 * Returns the new struture or NULL in case of error 5400 */ 5401 static xmlSchemaTypePtr 5402 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5403 xmlSchemaTypeType type, 5404 const xmlChar * name, const xmlChar * nsName, 5405 xmlNodePtr node, int topLevel) 5406 { 5407 xmlSchemaTypePtr ret = NULL; 5408 5409 if ((ctxt == NULL) || (schema == NULL)) 5410 return (NULL); 5411 5412 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5413 if (ret == NULL) { 5414 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5415 return (NULL); 5416 } 5417 memset(ret, 0, sizeof(xmlSchemaType)); 5418 ret->type = type; 5419 ret->name = name; 5420 ret->targetNamespace = nsName; 5421 ret->node = node; 5422 if (topLevel) { 5423 if (ctxt->isRedefine) { 5424 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5425 ret, name, nsName); 5426 if (ctxt->redef == NULL) { 5427 xmlFree(ret); 5428 return(NULL); 5429 } 5430 ctxt->redefCounter = 0; 5431 } 5432 WXS_ADD_GLOBAL(ctxt, ret); 5433 } else 5434 WXS_ADD_LOCAL(ctxt, ret); 5435 WXS_ADD_PENDING(ctxt, ret); 5436 return (ret); 5437 } 5438 5439 static xmlSchemaQNameRefPtr 5440 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5441 xmlSchemaTypeType refType, 5442 const xmlChar *refName, 5443 const xmlChar *refNs) 5444 { 5445 xmlSchemaQNameRefPtr ret; 5446 5447 ret = (xmlSchemaQNameRefPtr) 5448 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5449 if (ret == NULL) { 5450 xmlSchemaPErrMemory(pctxt, 5451 "allocating QName reference item", NULL); 5452 return (NULL); 5453 } 5454 ret->node = NULL; 5455 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5456 ret->name = refName; 5457 ret->targetNamespace = refNs; 5458 ret->item = NULL; 5459 ret->itemType = refType; 5460 /* 5461 * Store the reference item in the schema. 5462 */ 5463 WXS_ADD_LOCAL(pctxt, ret); 5464 return (ret); 5465 } 5466 5467 static xmlSchemaAttributeUseProhibPtr 5468 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5469 { 5470 xmlSchemaAttributeUseProhibPtr ret; 5471 5472 ret = (xmlSchemaAttributeUseProhibPtr) 5473 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5474 if (ret == NULL) { 5475 xmlSchemaPErrMemory(pctxt, 5476 "allocating attribute use prohibition", NULL); 5477 return (NULL); 5478 } 5479 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5480 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5481 WXS_ADD_LOCAL(pctxt, ret); 5482 return (ret); 5483 } 5484 5485 5486 /** 5487 * xmlSchemaAddModelGroup: 5488 * @ctxt: a schema parser context 5489 * @schema: the schema being built 5490 * @type: the "compositor" type of the model group 5491 * @node: the node in the schema doc 5492 * 5493 * Adds a schema model group 5494 * *WARNING* this interface is highly subject to change 5495 * 5496 * Returns the new struture or NULL in case of error 5497 */ 5498 static xmlSchemaModelGroupPtr 5499 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5500 xmlSchemaPtr schema, 5501 xmlSchemaTypeType type, 5502 xmlNodePtr node) 5503 { 5504 xmlSchemaModelGroupPtr ret = NULL; 5505 5506 if ((ctxt == NULL) || (schema == NULL)) 5507 return (NULL); 5508 5509 ret = (xmlSchemaModelGroupPtr) 5510 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5511 if (ret == NULL) { 5512 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5513 NULL); 5514 return (NULL); 5515 } 5516 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5517 ret->type = type; 5518 ret->node = node; 5519 WXS_ADD_LOCAL(ctxt, ret); 5520 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5521 (type == XML_SCHEMA_TYPE_CHOICE)) 5522 WXS_ADD_PENDING(ctxt, ret); 5523 return (ret); 5524 } 5525 5526 5527 /** 5528 * xmlSchemaAddParticle: 5529 * @ctxt: a schema parser context 5530 * @schema: the schema being built 5531 * @node: the corresponding node in the schema doc 5532 * @min: the minOccurs 5533 * @max: the maxOccurs 5534 * 5535 * Adds an XML schema particle component. 5536 * *WARNING* this interface is highly subject to change 5537 * 5538 * Returns the new struture or NULL in case of error 5539 */ 5540 static xmlSchemaParticlePtr 5541 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5542 xmlNodePtr node, int min, int max) 5543 { 5544 xmlSchemaParticlePtr ret = NULL; 5545 if (ctxt == NULL) 5546 return (NULL); 5547 5548 #ifdef DEBUG 5549 fprintf(stderr, "Adding particle component\n"); 5550 #endif 5551 ret = (xmlSchemaParticlePtr) 5552 xmlMalloc(sizeof(xmlSchemaParticle)); 5553 if (ret == NULL) { 5554 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5555 NULL); 5556 return (NULL); 5557 } 5558 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5559 ret->annot = NULL; 5560 ret->node = node; 5561 ret->minOccurs = min; 5562 ret->maxOccurs = max; 5563 ret->next = NULL; 5564 ret->children = NULL; 5565 5566 WXS_ADD_LOCAL(ctxt, ret); 5567 /* 5568 * Note that addition to pending components will be done locally 5569 * to the specific parsing function, since the most particles 5570 * need not to be fixed up (i.e. the reference to be resolved). 5571 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5572 */ 5573 return (ret); 5574 } 5575 5576 /** 5577 * xmlSchemaAddModelGroupDefinition: 5578 * @ctxt: a schema validation context 5579 * @schema: the schema being built 5580 * @name: the group name 5581 * 5582 * Add an XML schema Group definition 5583 * 5584 * Returns the new struture or NULL in case of error 5585 */ 5586 static xmlSchemaModelGroupDefPtr 5587 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5588 xmlSchemaPtr schema, 5589 const xmlChar *name, 5590 const xmlChar *nsName, 5591 xmlNodePtr node) 5592 { 5593 xmlSchemaModelGroupDefPtr ret = NULL; 5594 5595 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5596 return (NULL); 5597 5598 ret = (xmlSchemaModelGroupDefPtr) 5599 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5600 if (ret == NULL) { 5601 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5602 return (NULL); 5603 } 5604 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5605 ret->name = name; 5606 ret->type = XML_SCHEMA_TYPE_GROUP; 5607 ret->node = node; 5608 ret->targetNamespace = nsName; 5609 5610 if (ctxt->isRedefine) { 5611 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5612 ret, name, nsName); 5613 if (ctxt->redef == NULL) { 5614 xmlFree(ret); 5615 return(NULL); 5616 } 5617 ctxt->redefCounter = 0; 5618 } 5619 WXS_ADD_GLOBAL(ctxt, ret); 5620 WXS_ADD_PENDING(ctxt, ret); 5621 return (ret); 5622 } 5623 5624 /** 5625 * xmlSchemaNewWildcardNs: 5626 * @ctxt: a schema validation context 5627 * 5628 * Creates a new wildcard namespace constraint. 5629 * 5630 * Returns the new struture or NULL in case of error 5631 */ 5632 static xmlSchemaWildcardNsPtr 5633 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5634 { 5635 xmlSchemaWildcardNsPtr ret; 5636 5637 ret = (xmlSchemaWildcardNsPtr) 5638 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5639 if (ret == NULL) { 5640 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5641 return (NULL); 5642 } 5643 ret->value = NULL; 5644 ret->next = NULL; 5645 return (ret); 5646 } 5647 5648 static xmlSchemaIDCPtr 5649 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5650 const xmlChar *name, const xmlChar *nsName, 5651 int category, xmlNodePtr node) 5652 { 5653 xmlSchemaIDCPtr ret = NULL; 5654 5655 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5656 return (NULL); 5657 5658 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5659 if (ret == NULL) { 5660 xmlSchemaPErrMemory(ctxt, 5661 "allocating an identity-constraint definition", NULL); 5662 return (NULL); 5663 } 5664 memset(ret, 0, sizeof(xmlSchemaIDC)); 5665 /* The target namespace of the parent element declaration. */ 5666 ret->targetNamespace = nsName; 5667 ret->name = name; 5668 ret->type = category; 5669 ret->node = node; 5670 5671 WXS_ADD_GLOBAL(ctxt, ret); 5672 /* 5673 * Only keyrefs need to be fixup up. 5674 */ 5675 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5676 WXS_ADD_PENDING(ctxt, ret); 5677 return (ret); 5678 } 5679 5680 /** 5681 * xmlSchemaAddWildcard: 5682 * @ctxt: a schema validation context 5683 * @schema: a schema 5684 * 5685 * Adds a wildcard. 5686 * It corresponds to a xsd:anyAttribute and xsd:any. 5687 * 5688 * Returns the new struture or NULL in case of error 5689 */ 5690 static xmlSchemaWildcardPtr 5691 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5692 xmlSchemaTypeType type, xmlNodePtr node) 5693 { 5694 xmlSchemaWildcardPtr ret = NULL; 5695 5696 if ((ctxt == NULL) || (schema == NULL)) 5697 return (NULL); 5698 5699 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5700 if (ret == NULL) { 5701 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5702 return (NULL); 5703 } 5704 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5705 ret->type = type; 5706 ret->node = node; 5707 WXS_ADD_LOCAL(ctxt, ret); 5708 return (ret); 5709 } 5710 5711 static void 5712 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5713 { 5714 if (group == NULL) 5715 return; 5716 if (group->members != NULL) 5717 xmlSchemaItemListFree(group->members); 5718 xmlFree(group); 5719 } 5720 5721 static void 5722 xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED) 5723 { 5724 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group); 5725 } 5726 5727 static xmlSchemaSubstGroupPtr 5728 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5729 xmlSchemaElementPtr head) 5730 { 5731 xmlSchemaSubstGroupPtr ret; 5732 5733 /* Init subst group hash. */ 5734 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5735 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5736 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5737 return(NULL); 5738 } 5739 /* Create a new substitution group. */ 5740 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5741 if (ret == NULL) { 5742 xmlSchemaPErrMemory(NULL, 5743 "allocating a substitution group container", NULL); 5744 return(NULL); 5745 } 5746 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5747 ret->head = head; 5748 /* Create list of members. */ 5749 ret->members = xmlSchemaItemListCreate(); 5750 if (ret->members == NULL) { 5751 xmlSchemaSubstGroupFree(ret); 5752 return(NULL); 5753 } 5754 /* Add subst group to hash. */ 5755 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5756 head->name, head->targetNamespace, ret) != 0) { 5757 PERROR_INT("xmlSchemaSubstGroupAdd", 5758 "failed to add a new substitution container"); 5759 xmlSchemaSubstGroupFree(ret); 5760 return(NULL); 5761 } 5762 return(ret); 5763 } 5764 5765 static xmlSchemaSubstGroupPtr 5766 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5767 xmlSchemaElementPtr head) 5768 { 5769 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5770 return(NULL); 5771 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5772 head->name, head->targetNamespace)); 5773 5774 } 5775 5776 /** 5777 * xmlSchemaAddElementSubstitutionMember: 5778 * @pctxt: a schema parser context 5779 * @head: the head of the substitution group 5780 * @member: the new member of the substitution group 5781 * 5782 * Allocate a new annotation structure. 5783 * 5784 * Returns the newly allocated structure or NULL in case or error 5785 */ 5786 static int 5787 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5788 xmlSchemaElementPtr head, 5789 xmlSchemaElementPtr member) 5790 { 5791 xmlSchemaSubstGroupPtr substGroup = NULL; 5792 5793 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5794 return (-1); 5795 5796 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5797 if (substGroup == NULL) 5798 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5799 if (substGroup == NULL) 5800 return(-1); 5801 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5802 return(-1); 5803 return(0); 5804 } 5805 5806 /************************************************************************ 5807 * * 5808 * Utilities for parsing * 5809 * * 5810 ************************************************************************/ 5811 5812 /** 5813 * xmlSchemaPValAttrNodeQNameValue: 5814 * @ctxt: a schema parser context 5815 * @schema: the schema context 5816 * @ownerDes: the designation of the parent element 5817 * @ownerItem: the parent as a schema object 5818 * @value: the QName value 5819 * @local: the resulting local part if found, the attribute value otherwise 5820 * @uri: the resulting namespace URI if found 5821 * 5822 * Extracts the local name and the URI of a QName value and validates it. 5823 * This one is intended to be used on attribute values that 5824 * should resolve to schema components. 5825 * 5826 * Returns 0, in case the QName is valid, a positive error code 5827 * if not valid and -1 if an internal error occurs. 5828 */ 5829 static int 5830 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5831 xmlSchemaPtr schema, 5832 xmlSchemaBasicItemPtr ownerItem, 5833 xmlAttrPtr attr, 5834 const xmlChar *value, 5835 const xmlChar **uri, 5836 const xmlChar **local) 5837 { 5838 const xmlChar *pref; 5839 xmlNsPtr ns; 5840 int len, ret; 5841 5842 *uri = NULL; 5843 *local = NULL; 5844 ret = xmlValidateQName(value, 1); 5845 if (ret > 0) { 5846 xmlSchemaPSimpleTypeErr(ctxt, 5847 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5848 ownerItem, (xmlNodePtr) attr, 5849 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5850 NULL, value, NULL, NULL, NULL); 5851 *local = value; 5852 return (ctxt->err); 5853 } else if (ret < 0) 5854 return (-1); 5855 5856 if (!strchr((char *) value, ':')) { 5857 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5858 if (ns) 5859 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5860 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5861 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5862 * parser context. */ 5863 /* 5864 * This one takes care of included schemas with no 5865 * target namespace. 5866 */ 5867 *uri = ctxt->targetNamespace; 5868 } 5869 *local = xmlDictLookup(ctxt->dict, value, -1); 5870 return (0); 5871 } 5872 /* 5873 * At this point xmlSplitQName3 has to return a local name. 5874 */ 5875 *local = xmlSplitQName3(value, &len); 5876 *local = xmlDictLookup(ctxt->dict, *local, -1); 5877 pref = xmlDictLookup(ctxt->dict, value, len); 5878 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5879 if (ns == NULL) { 5880 xmlSchemaPSimpleTypeErr(ctxt, 5881 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5882 ownerItem, (xmlNodePtr) attr, 5883 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5884 "The value '%s' of simple type 'xs:QName' has no " 5885 "corresponding namespace declaration in scope", value, NULL); 5886 return (ctxt->err); 5887 } else { 5888 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5889 } 5890 return (0); 5891 } 5892 5893 /** 5894 * xmlSchemaPValAttrNodeQName: 5895 * @ctxt: a schema parser context 5896 * @schema: the schema context 5897 * @ownerDes: the designation of the owner element 5898 * @ownerItem: the owner as a schema object 5899 * @attr: the attribute node 5900 * @local: the resulting local part if found, the attribute value otherwise 5901 * @uri: the resulting namespace URI if found 5902 * 5903 * Extracts and validates the QName of an attribute value. 5904 * This one is intended to be used on attribute values that 5905 * should resolve to schema components. 5906 * 5907 * Returns 0, in case the QName is valid, a positive error code 5908 * if not valid and -1 if an internal error occurs. 5909 */ 5910 static int 5911 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5912 xmlSchemaPtr schema, 5913 xmlSchemaBasicItemPtr ownerItem, 5914 xmlAttrPtr attr, 5915 const xmlChar **uri, 5916 const xmlChar **local) 5917 { 5918 const xmlChar *value; 5919 5920 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5921 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5922 ownerItem, attr, value, uri, local)); 5923 } 5924 5925 /** 5926 * xmlSchemaPValAttrQName: 5927 * @ctxt: a schema parser context 5928 * @schema: the schema context 5929 * @ownerDes: the designation of the parent element 5930 * @ownerItem: the owner as a schema object 5931 * @ownerElem: the parent node of the attribute 5932 * @name: the name of the attribute 5933 * @local: the resulting local part if found, the attribute value otherwise 5934 * @uri: the resulting namespace URI if found 5935 * 5936 * Extracts and validates the QName of an attribute value. 5937 * 5938 * Returns 0, in case the QName is valid, a positive error code 5939 * if not valid and -1 if an internal error occurs. 5940 */ 5941 static int 5942 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5943 xmlSchemaPtr schema, 5944 xmlSchemaBasicItemPtr ownerItem, 5945 xmlNodePtr ownerElem, 5946 const char *name, 5947 const xmlChar **uri, 5948 const xmlChar **local) 5949 { 5950 xmlAttrPtr attr; 5951 5952 attr = xmlSchemaGetPropNode(ownerElem, name); 5953 if (attr == NULL) { 5954 *local = NULL; 5955 *uri = NULL; 5956 return (0); 5957 } 5958 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5959 ownerItem, attr, uri, local)); 5960 } 5961 5962 /** 5963 * xmlSchemaPValAttrID: 5964 * @ctxt: a schema parser context 5965 * @schema: the schema context 5966 * @ownerDes: the designation of the parent element 5967 * @ownerItem: the owner as a schema object 5968 * @ownerElem: the parent node of the attribute 5969 * @name: the name of the attribute 5970 * 5971 * Extracts and validates the ID of an attribute value. 5972 * 5973 * Returns 0, in case the ID is valid, a positive error code 5974 * if not valid and -1 if an internal error occurs. 5975 */ 5976 static int 5977 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5978 { 5979 int ret; 5980 const xmlChar *value; 5981 5982 if (attr == NULL) 5983 return(0); 5984 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5985 ret = xmlValidateNCName(value, 1); 5986 if (ret == 0) { 5987 /* 5988 * NOTE: the IDness might have already be declared in the DTD 5989 */ 5990 if (attr->atype != XML_ATTRIBUTE_ID) { 5991 xmlIDPtr res; 5992 xmlChar *strip; 5993 5994 /* 5995 * TODO: Use xmlSchemaStrip here; it's not exported at this 5996 * moment. 5997 */ 5998 strip = xmlSchemaCollapseString(value); 5999 if (strip != NULL) { 6000 xmlFree((xmlChar *) value); 6001 value = strip; 6002 } 6003 res = xmlAddID(NULL, attr->doc, value, attr); 6004 if (res == NULL) { 6005 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6006 xmlSchemaPSimpleTypeErr(ctxt, 6007 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6008 NULL, (xmlNodePtr) attr, 6009 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 6010 NULL, NULL, "Duplicate value '%s' of simple " 6011 "type 'xs:ID'", value, NULL); 6012 } else 6013 attr->atype = XML_ATTRIBUTE_ID; 6014 } 6015 } else if (ret > 0) { 6016 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6017 xmlSchemaPSimpleTypeErr(ctxt, 6018 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6019 NULL, (xmlNodePtr) attr, 6020 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 6021 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 6022 "not a valid 'xs:NCName'", 6023 value, NULL); 6024 } 6025 if (value != NULL) 6026 xmlFree((xmlChar *)value); 6027 6028 return (ret); 6029 } 6030 6031 static int 6032 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 6033 xmlNodePtr ownerElem, 6034 const xmlChar *name) 6035 { 6036 xmlAttrPtr attr; 6037 6038 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 6039 if (attr == NULL) 6040 return(0); 6041 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6042 6043 } 6044 6045 /** 6046 * xmlGetMaxOccurs: 6047 * @ctxt: a schema validation context 6048 * @node: a subtree containing XML Schema informations 6049 * 6050 * Get the maxOccurs property 6051 * 6052 * Returns the default if not found, or the value 6053 */ 6054 static int 6055 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6056 int min, int max, int def, const char *expected) 6057 { 6058 const xmlChar *val, *cur; 6059 int ret = 0; 6060 xmlAttrPtr attr; 6061 6062 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6063 if (attr == NULL) 6064 return (def); 6065 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6066 6067 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6068 if (max != UNBOUNDED) { 6069 xmlSchemaPSimpleTypeErr(ctxt, 6070 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6071 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6072 NULL, (xmlNodePtr) attr, NULL, expected, 6073 val, NULL, NULL, NULL); 6074 return (def); 6075 } else 6076 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6077 } 6078 6079 cur = val; 6080 while (IS_BLANK_CH(*cur)) 6081 cur++; 6082 if (*cur == 0) { 6083 xmlSchemaPSimpleTypeErr(ctxt, 6084 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6085 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6086 NULL, (xmlNodePtr) attr, NULL, expected, 6087 val, NULL, NULL, NULL); 6088 return (def); 6089 } 6090 while ((*cur >= '0') && (*cur <= '9')) { 6091 ret = ret * 10 + (*cur - '0'); 6092 cur++; 6093 } 6094 while (IS_BLANK_CH(*cur)) 6095 cur++; 6096 /* 6097 * TODO: Restrict the maximal value to Integer. 6098 */ 6099 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6100 xmlSchemaPSimpleTypeErr(ctxt, 6101 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6102 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6103 NULL, (xmlNodePtr) attr, NULL, expected, 6104 val, NULL, NULL, NULL); 6105 return (def); 6106 } 6107 return (ret); 6108 } 6109 6110 /** 6111 * xmlGetMinOccurs: 6112 * @ctxt: a schema validation context 6113 * @node: a subtree containing XML Schema informations 6114 * 6115 * Get the minOccurs property 6116 * 6117 * Returns the default if not found, or the value 6118 */ 6119 static int 6120 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6121 int min, int max, int def, const char *expected) 6122 { 6123 const xmlChar *val, *cur; 6124 int ret = 0; 6125 xmlAttrPtr attr; 6126 6127 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6128 if (attr == NULL) 6129 return (def); 6130 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6131 cur = val; 6132 while (IS_BLANK_CH(*cur)) 6133 cur++; 6134 if (*cur == 0) { 6135 xmlSchemaPSimpleTypeErr(ctxt, 6136 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6137 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6138 NULL, (xmlNodePtr) attr, NULL, expected, 6139 val, NULL, NULL, NULL); 6140 return (def); 6141 } 6142 while ((*cur >= '0') && (*cur <= '9')) { 6143 ret = ret * 10 + (*cur - '0'); 6144 cur++; 6145 } 6146 while (IS_BLANK_CH(*cur)) 6147 cur++; 6148 /* 6149 * TODO: Restrict the maximal value to Integer. 6150 */ 6151 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6152 xmlSchemaPSimpleTypeErr(ctxt, 6153 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6154 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6155 NULL, (xmlNodePtr) attr, NULL, expected, 6156 val, NULL, NULL, NULL); 6157 return (def); 6158 } 6159 return (ret); 6160 } 6161 6162 /** 6163 * xmlSchemaPGetBoolNodeValue: 6164 * @ctxt: a schema validation context 6165 * @ownerDes: owner designation 6166 * @ownerItem: the owner as a schema item 6167 * @node: the node holding the value 6168 * 6169 * Converts a boolean string value into 1 or 0. 6170 * 6171 * Returns 0 or 1. 6172 */ 6173 static int 6174 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6175 xmlSchemaBasicItemPtr ownerItem, 6176 xmlNodePtr node) 6177 { 6178 xmlChar *value = NULL; 6179 int res = 0; 6180 6181 value = xmlNodeGetContent(node); 6182 /* 6183 * 3.2.2.1 Lexical representation 6184 * An instance of a datatype that is defined as `boolean` 6185 * can have the following legal literals {true, false, 1, 0}. 6186 */ 6187 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6188 res = 1; 6189 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6190 res = 0; 6191 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6192 res = 1; 6193 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6194 res = 0; 6195 else { 6196 xmlSchemaPSimpleTypeErr(ctxt, 6197 XML_SCHEMAP_INVALID_BOOLEAN, 6198 ownerItem, node, 6199 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6200 NULL, BAD_CAST value, 6201 NULL, NULL, NULL); 6202 } 6203 if (value != NULL) 6204 xmlFree(value); 6205 return (res); 6206 } 6207 6208 /** 6209 * xmlGetBooleanProp: 6210 * @ctxt: a schema validation context 6211 * @node: a subtree containing XML Schema informations 6212 * @name: the attribute name 6213 * @def: the default value 6214 * 6215 * Evaluate if a boolean property is set 6216 * 6217 * Returns the default if not found, 0 if found to be false, 6218 * 1 if found to be true 6219 */ 6220 static int 6221 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6222 xmlNodePtr node, 6223 const char *name, int def) 6224 { 6225 const xmlChar *val; 6226 6227 val = xmlSchemaGetProp(ctxt, node, name); 6228 if (val == NULL) 6229 return (def); 6230 /* 6231 * 3.2.2.1 Lexical representation 6232 * An instance of a datatype that is defined as `boolean` 6233 * can have the following legal literals {true, false, 1, 0}. 6234 */ 6235 if (xmlStrEqual(val, BAD_CAST "true")) 6236 def = 1; 6237 else if (xmlStrEqual(val, BAD_CAST "false")) 6238 def = 0; 6239 else if (xmlStrEqual(val, BAD_CAST "1")) 6240 def = 1; 6241 else if (xmlStrEqual(val, BAD_CAST "0")) 6242 def = 0; 6243 else { 6244 xmlSchemaPSimpleTypeErr(ctxt, 6245 XML_SCHEMAP_INVALID_BOOLEAN, 6246 NULL, 6247 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6248 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6249 NULL, val, NULL, NULL, NULL); 6250 } 6251 return (def); 6252 } 6253 6254 /************************************************************************ 6255 * * 6256 * Shema extraction from an Infoset * 6257 * * 6258 ************************************************************************/ 6259 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6260 ctxt, xmlSchemaPtr schema, 6261 xmlNodePtr node, 6262 int topLevel); 6263 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6264 ctxt, 6265 xmlSchemaPtr schema, 6266 xmlNodePtr node, 6267 int topLevel); 6268 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6269 ctxt, 6270 xmlSchemaPtr schema, 6271 xmlNodePtr node, 6272 xmlSchemaTypeType parentType); 6273 static xmlSchemaBasicItemPtr 6274 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6275 xmlSchemaPtr schema, 6276 xmlNodePtr node, 6277 xmlSchemaItemListPtr uses, 6278 int parentType); 6279 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6280 xmlSchemaPtr schema, 6281 xmlNodePtr node); 6282 static xmlSchemaWildcardPtr 6283 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6284 xmlSchemaPtr schema, xmlNodePtr node); 6285 6286 /** 6287 * xmlSchemaPValAttrNodeValue: 6288 * 6289 * @ctxt: a schema parser context 6290 * @ownerDes: the designation of the parent element 6291 * @ownerItem: the schema object owner if existent 6292 * @attr: the schema attribute node being validated 6293 * @value: the value 6294 * @type: the built-in type to be validated against 6295 * 6296 * Validates a value against the given built-in type. 6297 * This one is intended to be used internally for validation 6298 * of schema attribute values during parsing of the schema. 6299 * 6300 * Returns 0 if the value is valid, a positive error code 6301 * number otherwise and -1 in case of an internal or API error. 6302 */ 6303 static int 6304 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6305 xmlSchemaBasicItemPtr ownerItem, 6306 xmlAttrPtr attr, 6307 const xmlChar *value, 6308 xmlSchemaTypePtr type) 6309 { 6310 6311 int ret = 0; 6312 6313 /* 6314 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6315 * one is really meant to be used internally, so better not. 6316 */ 6317 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6318 return (-1); 6319 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6320 PERROR_INT("xmlSchemaPValAttrNodeValue", 6321 "the given type is not a built-in type"); 6322 return (-1); 6323 } 6324 switch (type->builtInType) { 6325 case XML_SCHEMAS_NCNAME: 6326 case XML_SCHEMAS_QNAME: 6327 case XML_SCHEMAS_ANYURI: 6328 case XML_SCHEMAS_TOKEN: 6329 case XML_SCHEMAS_LANGUAGE: 6330 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6331 (xmlNodePtr) attr); 6332 break; 6333 default: { 6334 PERROR_INT("xmlSchemaPValAttrNodeValue", 6335 "validation using the given type is not supported while " 6336 "parsing a schema"); 6337 return (-1); 6338 } 6339 } 6340 /* 6341 * TODO: Should we use the S4S error codes instead? 6342 */ 6343 if (ret < 0) { 6344 PERROR_INT("xmlSchemaPValAttrNodeValue", 6345 "failed to validate a schema attribute value"); 6346 return (-1); 6347 } else if (ret > 0) { 6348 if (WXS_IS_LIST(type)) 6349 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6350 else 6351 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6352 xmlSchemaPSimpleTypeErr(pctxt, 6353 ret, ownerItem, (xmlNodePtr) attr, 6354 type, NULL, value, NULL, NULL, NULL); 6355 } 6356 return (ret); 6357 } 6358 6359 /** 6360 * xmlSchemaPValAttrNode: 6361 * 6362 * @ctxt: a schema parser context 6363 * @ownerDes: the designation of the parent element 6364 * @ownerItem: the schema object owner if existent 6365 * @attr: the schema attribute node being validated 6366 * @type: the built-in type to be validated against 6367 * @value: the resulting value if any 6368 * 6369 * Extracts and validates a value against the given built-in type. 6370 * This one is intended to be used internally for validation 6371 * of schema attribute values during parsing of the schema. 6372 * 6373 * Returns 0 if the value is valid, a positive error code 6374 * number otherwise and -1 in case of an internal or API error. 6375 */ 6376 static int 6377 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6378 xmlSchemaBasicItemPtr ownerItem, 6379 xmlAttrPtr attr, 6380 xmlSchemaTypePtr type, 6381 const xmlChar **value) 6382 { 6383 const xmlChar *val; 6384 6385 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6386 return (-1); 6387 6388 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6389 if (value != NULL) 6390 *value = val; 6391 6392 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6393 val, type)); 6394 } 6395 6396 /** 6397 * xmlSchemaPValAttr: 6398 * 6399 * @ctxt: a schema parser context 6400 * @node: the element node of the attribute 6401 * @ownerDes: the designation of the parent element 6402 * @ownerItem: the schema object owner if existent 6403 * @ownerElem: the owner element node 6404 * @name: the name of the schema attribute node 6405 * @type: the built-in type to be validated against 6406 * @value: the resulting value if any 6407 * 6408 * Extracts and validates a value against the given built-in type. 6409 * This one is intended to be used internally for validation 6410 * of schema attribute values during parsing of the schema. 6411 * 6412 * Returns 0 if the value is valid, a positive error code 6413 * number otherwise and -1 in case of an internal or API error. 6414 */ 6415 static int 6416 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6417 xmlSchemaBasicItemPtr ownerItem, 6418 xmlNodePtr ownerElem, 6419 const char *name, 6420 xmlSchemaTypePtr type, 6421 const xmlChar **value) 6422 { 6423 xmlAttrPtr attr; 6424 6425 if ((ctxt == NULL) || (type == NULL)) { 6426 if (value != NULL) 6427 *value = NULL; 6428 return (-1); 6429 } 6430 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6431 if (value != NULL) 6432 *value = NULL; 6433 xmlSchemaPErr(ctxt, ownerElem, 6434 XML_SCHEMAP_INTERNAL, 6435 "Internal error: xmlSchemaPValAttr, the given " 6436 "type '%s' is not a built-in type.\n", 6437 type->name, NULL); 6438 return (-1); 6439 } 6440 attr = xmlSchemaGetPropNode(ownerElem, name); 6441 if (attr == NULL) { 6442 if (value != NULL) 6443 *value = NULL; 6444 return (0); 6445 } 6446 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6447 type, value)); 6448 } 6449 6450 static int 6451 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6452 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6453 xmlNodePtr node, 6454 xmlAttrPtr attr, 6455 const xmlChar *namespaceName) 6456 { 6457 /* TODO: Pointer comparison instead? */ 6458 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6459 return (0); 6460 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6461 return (0); 6462 /* 6463 * Check if the referenced namespace was <import>ed. 6464 */ 6465 if (WXS_BUCKET(pctxt)->relations != NULL) { 6466 xmlSchemaSchemaRelationPtr rel; 6467 6468 rel = WXS_BUCKET(pctxt)->relations; 6469 do { 6470 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6471 xmlStrEqual(namespaceName, rel->importNamespace)) 6472 return (0); 6473 rel = rel->next; 6474 } while (rel != NULL); 6475 } 6476 /* 6477 * No matching <import>ed namespace found. 6478 */ 6479 { 6480 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6481 6482 if (namespaceName == NULL) 6483 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6484 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6485 "References from this schema to components in no " 6486 "namespace are not allowed, since not indicated by an " 6487 "import statement", NULL, NULL); 6488 else 6489 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6490 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6491 "References from this schema to components in the " 6492 "namespace '%s' are not allowed, since not indicated by an " 6493 "import statement", namespaceName, NULL); 6494 } 6495 return (XML_SCHEMAP_SRC_RESOLVE); 6496 } 6497 6498 /** 6499 * xmlSchemaParseLocalAttributes: 6500 * @ctxt: a schema validation context 6501 * @schema: the schema being built 6502 * @node: a subtree containing XML Schema informations 6503 * @type: the hosting type where the attributes will be anchored 6504 * 6505 * Parses attribute uses and attribute declarations and 6506 * attribute group references. 6507 */ 6508 static int 6509 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6510 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6511 int parentType, int *hasRefs) 6512 { 6513 void *item; 6514 6515 while ((IS_SCHEMA((*child), "attribute")) || 6516 (IS_SCHEMA((*child), "attributeGroup"))) { 6517 if (IS_SCHEMA((*child), "attribute")) { 6518 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6519 *list, parentType); 6520 } else { 6521 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6522 if ((item != NULL) && (hasRefs != NULL)) 6523 *hasRefs = 1; 6524 } 6525 if (item != NULL) { 6526 if (*list == NULL) { 6527 /* TODO: Customize grow factor. */ 6528 *list = xmlSchemaItemListCreate(); 6529 if (*list == NULL) 6530 return(-1); 6531 } 6532 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6533 return(-1); 6534 } 6535 *child = (*child)->next; 6536 } 6537 return (0); 6538 } 6539 6540 /** 6541 * xmlSchemaParseAnnotation: 6542 * @ctxt: a schema validation context 6543 * @schema: the schema being built 6544 * @node: a subtree containing XML Schema informations 6545 * 6546 * parse a XML schema Attrribute declaration 6547 * *WARNING* this interface is highly subject to change 6548 * 6549 * Returns -1 in case of error, 0 if the declaration is improper and 6550 * 1 in case of success. 6551 */ 6552 static xmlSchemaAnnotPtr 6553 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6554 { 6555 xmlSchemaAnnotPtr ret; 6556 xmlNodePtr child = NULL; 6557 xmlAttrPtr attr; 6558 int barked = 0; 6559 6560 /* 6561 * INFO: S4S completed. 6562 */ 6563 /* 6564 * id = ID 6565 * {any attributes with non-schema namespace . . .}> 6566 * Content: (appinfo | documentation)* 6567 */ 6568 if ((ctxt == NULL) || (node == NULL)) 6569 return (NULL); 6570 if (needed) 6571 ret = xmlSchemaNewAnnot(ctxt, node); 6572 else 6573 ret = NULL; 6574 attr = node->properties; 6575 while (attr != NULL) { 6576 if (((attr->ns == NULL) && 6577 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6578 ((attr->ns != NULL) && 6579 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6580 6581 xmlSchemaPIllegalAttrErr(ctxt, 6582 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6583 } 6584 attr = attr->next; 6585 } 6586 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6587 /* 6588 * And now for the children... 6589 */ 6590 child = node->children; 6591 while (child != NULL) { 6592 if (IS_SCHEMA(child, "appinfo")) { 6593 /* TODO: make available the content of "appinfo". */ 6594 /* 6595 * source = anyURI 6596 * {any attributes with non-schema namespace . . .}> 6597 * Content: ({any})* 6598 */ 6599 attr = child->properties; 6600 while (attr != NULL) { 6601 if (((attr->ns == NULL) && 6602 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6603 ((attr->ns != NULL) && 6604 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6605 6606 xmlSchemaPIllegalAttrErr(ctxt, 6607 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6608 } 6609 attr = attr->next; 6610 } 6611 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6612 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6613 child = child->next; 6614 } else if (IS_SCHEMA(child, "documentation")) { 6615 /* TODO: make available the content of "documentation". */ 6616 /* 6617 * source = anyURI 6618 * {any attributes with non-schema namespace . . .}> 6619 * Content: ({any})* 6620 */ 6621 attr = child->properties; 6622 while (attr != NULL) { 6623 if (attr->ns == NULL) { 6624 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6625 xmlSchemaPIllegalAttrErr(ctxt, 6626 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6627 } 6628 } else { 6629 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6630 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6631 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6632 6633 xmlSchemaPIllegalAttrErr(ctxt, 6634 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6635 } 6636 } 6637 attr = attr->next; 6638 } 6639 /* 6640 * Attribute "xml:lang". 6641 */ 6642 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6643 if (attr != NULL) 6644 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6645 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6646 child = child->next; 6647 } else { 6648 if (!barked) 6649 xmlSchemaPContentErr(ctxt, 6650 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6651 NULL, node, child, NULL, "(appinfo | documentation)*"); 6652 barked = 1; 6653 child = child->next; 6654 } 6655 } 6656 6657 return (ret); 6658 } 6659 6660 /** 6661 * xmlSchemaParseFacet: 6662 * @ctxt: a schema validation context 6663 * @schema: the schema being built 6664 * @node: a subtree containing XML Schema informations 6665 * 6666 * parse a XML schema Facet declaration 6667 * *WARNING* this interface is highly subject to change 6668 * 6669 * Returns the new type structure or NULL in case of error 6670 */ 6671 static xmlSchemaFacetPtr 6672 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6673 xmlNodePtr node) 6674 { 6675 xmlSchemaFacetPtr facet; 6676 xmlNodePtr child = NULL; 6677 const xmlChar *value; 6678 6679 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6680 return (NULL); 6681 6682 facet = xmlSchemaNewFacet(); 6683 if (facet == NULL) { 6684 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6685 return (NULL); 6686 } 6687 facet->node = node; 6688 value = xmlSchemaGetProp(ctxt, node, "value"); 6689 if (value == NULL) { 6690 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6691 "Facet %s has no value\n", node->name, NULL); 6692 xmlSchemaFreeFacet(facet); 6693 return (NULL); 6694 } 6695 if (IS_SCHEMA(node, "minInclusive")) { 6696 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6697 } else if (IS_SCHEMA(node, "minExclusive")) { 6698 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6699 } else if (IS_SCHEMA(node, "maxInclusive")) { 6700 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6701 } else if (IS_SCHEMA(node, "maxExclusive")) { 6702 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6703 } else if (IS_SCHEMA(node, "totalDigits")) { 6704 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6705 } else if (IS_SCHEMA(node, "fractionDigits")) { 6706 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6707 } else if (IS_SCHEMA(node, "pattern")) { 6708 facet->type = XML_SCHEMA_FACET_PATTERN; 6709 } else if (IS_SCHEMA(node, "enumeration")) { 6710 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6711 } else if (IS_SCHEMA(node, "whiteSpace")) { 6712 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6713 } else if (IS_SCHEMA(node, "length")) { 6714 facet->type = XML_SCHEMA_FACET_LENGTH; 6715 } else if (IS_SCHEMA(node, "maxLength")) { 6716 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6717 } else if (IS_SCHEMA(node, "minLength")) { 6718 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6719 } else { 6720 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6721 "Unknown facet type %s\n", node->name, NULL); 6722 xmlSchemaFreeFacet(facet); 6723 return (NULL); 6724 } 6725 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6726 facet->value = value; 6727 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6728 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6729 const xmlChar *fixed; 6730 6731 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6732 if (fixed != NULL) { 6733 if (xmlStrEqual(fixed, BAD_CAST "true")) 6734 facet->fixed = 1; 6735 } 6736 } 6737 child = node->children; 6738 6739 if (IS_SCHEMA(child, "annotation")) { 6740 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6741 child = child->next; 6742 } 6743 if (child != NULL) { 6744 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6745 "Facet %s has unexpected child content\n", 6746 node->name, NULL); 6747 } 6748 return (facet); 6749 } 6750 6751 /** 6752 * xmlSchemaParseWildcardNs: 6753 * @ctxt: a schema parser context 6754 * @wildc: the wildcard, already created 6755 * @node: a subtree containing XML Schema informations 6756 * 6757 * Parses the attribute "processContents" and "namespace" 6758 * of a xsd:anyAttribute and xsd:any. 6759 * *WARNING* this interface is highly subject to change 6760 * 6761 * Returns 0 if everything goes fine, a positive error code 6762 * if something is not valid and -1 if an internal error occurs. 6763 */ 6764 static int 6765 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6766 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6767 xmlSchemaWildcardPtr wildc, 6768 xmlNodePtr node) 6769 { 6770 const xmlChar *pc, *ns, *dictnsItem; 6771 int ret = 0; 6772 xmlChar *nsItem; 6773 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6774 xmlAttrPtr attr; 6775 6776 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6777 if ((pc == NULL) 6778 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6779 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6780 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6781 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6782 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6783 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6784 } else { 6785 xmlSchemaPSimpleTypeErr(ctxt, 6786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6787 NULL, node, 6788 NULL, "(strict | skip | lax)", pc, 6789 NULL, NULL, NULL); 6790 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6791 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6792 } 6793 /* 6794 * Build the namespace constraints. 6795 */ 6796 attr = xmlSchemaGetPropNode(node, "namespace"); 6797 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6798 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6799 wildc->any = 1; 6800 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6801 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6802 if (wildc->negNsSet == NULL) { 6803 return (-1); 6804 } 6805 wildc->negNsSet->value = ctxt->targetNamespace; 6806 } else { 6807 const xmlChar *end, *cur; 6808 6809 cur = ns; 6810 do { 6811 while (IS_BLANK_CH(*cur)) 6812 cur++; 6813 end = cur; 6814 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6815 end++; 6816 if (end == cur) 6817 break; 6818 nsItem = xmlStrndup(cur, end - cur); 6819 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6820 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6821 xmlSchemaPSimpleTypeErr(ctxt, 6822 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6823 NULL, (xmlNodePtr) attr, 6824 NULL, 6825 "((##any | ##other) | List of (xs:anyURI | " 6826 "(##targetNamespace | ##local)))", 6827 nsItem, NULL, NULL, NULL); 6828 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6829 } else { 6830 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6831 dictnsItem = ctxt->targetNamespace; 6832 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6833 dictnsItem = NULL; 6834 } else { 6835 /* 6836 * Validate the item (anyURI). 6837 */ 6838 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6839 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6840 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6841 } 6842 /* 6843 * Avoid dublicate namespaces. 6844 */ 6845 tmp = wildc->nsSet; 6846 while (tmp != NULL) { 6847 if (dictnsItem == tmp->value) 6848 break; 6849 tmp = tmp->next; 6850 } 6851 if (tmp == NULL) { 6852 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6853 if (tmp == NULL) { 6854 xmlFree(nsItem); 6855 return (-1); 6856 } 6857 tmp->value = dictnsItem; 6858 tmp->next = NULL; 6859 if (wildc->nsSet == NULL) 6860 wildc->nsSet = tmp; 6861 else if (lastNs != NULL) 6862 lastNs->next = tmp; 6863 lastNs = tmp; 6864 } 6865 6866 } 6867 xmlFree(nsItem); 6868 cur = end; 6869 } while (*cur != 0); 6870 } 6871 return (ret); 6872 } 6873 6874 static int 6875 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6876 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6877 xmlNodePtr node, 6878 int minOccurs, 6879 int maxOccurs) { 6880 6881 if ((maxOccurs == 0) && ( minOccurs == 0)) 6882 return (0); 6883 if (maxOccurs != UNBOUNDED) { 6884 /* 6885 * TODO: Maybe we should better not create the particle, 6886 * if min/max is invalid, since it could confuse the build of the 6887 * content model. 6888 */ 6889 /* 6890 * 3.9.6 Schema Component Constraint: Particle Correct 6891 * 6892 */ 6893 if (maxOccurs < 1) { 6894 /* 6895 * 2.2 {max occurs} must be greater than or equal to 1. 6896 */ 6897 xmlSchemaPCustomAttrErr(ctxt, 6898 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6899 NULL, NULL, 6900 xmlSchemaGetPropNode(node, "maxOccurs"), 6901 "The value must be greater than or equal to 1"); 6902 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6903 } else if (minOccurs > maxOccurs) { 6904 /* 6905 * 2.1 {min occurs} must not be greater than {max occurs}. 6906 */ 6907 xmlSchemaPCustomAttrErr(ctxt, 6908 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6909 NULL, NULL, 6910 xmlSchemaGetPropNode(node, "minOccurs"), 6911 "The value must not be greater than the value of 'maxOccurs'"); 6912 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6913 } 6914 } 6915 return (0); 6916 } 6917 6918 /** 6919 * xmlSchemaParseAny: 6920 * @ctxt: a schema validation context 6921 * @schema: the schema being built 6922 * @node: a subtree containing XML Schema informations 6923 * 6924 * Parsea a XML schema <any> element. A particle and wildcard 6925 * will be created (except if minOccurs==maxOccurs==0, in this case 6926 * nothing will be created). 6927 * *WARNING* this interface is highly subject to change 6928 * 6929 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6930 */ 6931 static xmlSchemaParticlePtr 6932 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6933 xmlNodePtr node) 6934 { 6935 xmlSchemaParticlePtr particle; 6936 xmlNodePtr child = NULL; 6937 xmlSchemaWildcardPtr wild; 6938 int min, max; 6939 xmlAttrPtr attr; 6940 xmlSchemaAnnotPtr annot = NULL; 6941 6942 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6943 return (NULL); 6944 /* 6945 * Check for illegal attributes. 6946 */ 6947 attr = node->properties; 6948 while (attr != NULL) { 6949 if (attr->ns == NULL) { 6950 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6951 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6952 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6953 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6954 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6955 xmlSchemaPIllegalAttrErr(ctxt, 6956 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6957 } 6958 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6959 xmlSchemaPIllegalAttrErr(ctxt, 6960 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6961 } 6962 attr = attr->next; 6963 } 6964 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6965 /* 6966 * minOccurs/maxOccurs. 6967 */ 6968 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6969 "(xs:nonNegativeInteger | unbounded)"); 6970 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6971 "xs:nonNegativeInteger"); 6972 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6973 /* 6974 * Create & parse the wildcard. 6975 */ 6976 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6977 if (wild == NULL) 6978 return (NULL); 6979 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6980 /* 6981 * And now for the children... 6982 */ 6983 child = node->children; 6984 if (IS_SCHEMA(child, "annotation")) { 6985 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6986 child = child->next; 6987 } 6988 if (child != NULL) { 6989 xmlSchemaPContentErr(ctxt, 6990 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6991 NULL, node, child, 6992 NULL, "(annotation?)"); 6993 } 6994 /* 6995 * No component if minOccurs==maxOccurs==0. 6996 */ 6997 if ((min == 0) && (max == 0)) { 6998 /* Don't free the wildcard, since it's already on the list. */ 6999 return (NULL); 7000 } 7001 /* 7002 * Create the particle. 7003 */ 7004 particle = xmlSchemaAddParticle(ctxt, node, min, max); 7005 if (particle == NULL) 7006 return (NULL); 7007 particle->annot = annot; 7008 particle->children = (xmlSchemaTreeItemPtr) wild; 7009 7010 return (particle); 7011 } 7012 7013 /** 7014 * xmlSchemaParseNotation: 7015 * @ctxt: a schema validation context 7016 * @schema: the schema being built 7017 * @node: a subtree containing XML Schema informations 7018 * 7019 * parse a XML schema Notation declaration 7020 * 7021 * Returns the new structure or NULL in case of error 7022 */ 7023 static xmlSchemaNotationPtr 7024 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 7025 xmlNodePtr node) 7026 { 7027 const xmlChar *name; 7028 xmlSchemaNotationPtr ret; 7029 xmlNodePtr child = NULL; 7030 7031 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7032 return (NULL); 7033 name = xmlSchemaGetProp(ctxt, node, "name"); 7034 if (name == NULL) { 7035 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 7036 "Notation has no name\n", NULL, NULL); 7037 return (NULL); 7038 } 7039 ret = xmlSchemaAddNotation(ctxt, schema, name, 7040 ctxt->targetNamespace, node); 7041 if (ret == NULL) 7042 return (NULL); 7043 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7044 7045 child = node->children; 7046 if (IS_SCHEMA(child, "annotation")) { 7047 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7048 child = child->next; 7049 } 7050 if (child != NULL) { 7051 xmlSchemaPContentErr(ctxt, 7052 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7053 NULL, node, child, 7054 NULL, "(annotation?)"); 7055 } 7056 7057 return (ret); 7058 } 7059 7060 /** 7061 * xmlSchemaParseAnyAttribute: 7062 * @ctxt: a schema validation context 7063 * @schema: the schema being built 7064 * @node: a subtree containing XML Schema informations 7065 * 7066 * parse a XML schema AnyAttrribute declaration 7067 * *WARNING* this interface is highly subject to change 7068 * 7069 * Returns a wildcard or NULL. 7070 */ 7071 static xmlSchemaWildcardPtr 7072 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7073 xmlSchemaPtr schema, xmlNodePtr node) 7074 { 7075 xmlSchemaWildcardPtr ret; 7076 xmlNodePtr child = NULL; 7077 xmlAttrPtr attr; 7078 7079 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7080 return (NULL); 7081 7082 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7083 node); 7084 if (ret == NULL) { 7085 return (NULL); 7086 } 7087 /* 7088 * Check for illegal attributes. 7089 */ 7090 attr = node->properties; 7091 while (attr != NULL) { 7092 if (attr->ns == NULL) { 7093 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7094 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7095 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7096 xmlSchemaPIllegalAttrErr(ctxt, 7097 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7098 } 7099 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7100 xmlSchemaPIllegalAttrErr(ctxt, 7101 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7102 } 7103 attr = attr->next; 7104 } 7105 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7106 /* 7107 * Parse the namespace list. 7108 */ 7109 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7110 return (NULL); 7111 /* 7112 * And now for the children... 7113 */ 7114 child = node->children; 7115 if (IS_SCHEMA(child, "annotation")) { 7116 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7117 child = child->next; 7118 } 7119 if (child != NULL) { 7120 xmlSchemaPContentErr(ctxt, 7121 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7122 NULL, node, child, 7123 NULL, "(annotation?)"); 7124 } 7125 7126 return (ret); 7127 } 7128 7129 7130 /** 7131 * xmlSchemaParseAttribute: 7132 * @ctxt: a schema validation context 7133 * @schema: the schema being built 7134 * @node: a subtree containing XML Schema informations 7135 * 7136 * parse a XML schema Attrribute declaration 7137 * *WARNING* this interface is highly subject to change 7138 * 7139 * Returns the attribute declaration. 7140 */ 7141 static xmlSchemaBasicItemPtr 7142 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7143 xmlSchemaPtr schema, 7144 xmlNodePtr node, 7145 xmlSchemaItemListPtr uses, 7146 int parentType) 7147 { 7148 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7149 xmlSchemaAttributeUsePtr use = NULL; 7150 xmlNodePtr child = NULL; 7151 xmlAttrPtr attr; 7152 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7153 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7154 int nberrors, hasForm = 0, defValueType = 0; 7155 7156 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7157 #define WXS_ATTR_DEF_VAL_FIXED 2 7158 7159 /* 7160 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7161 */ 7162 7163 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7164 return (NULL); 7165 attr = xmlSchemaGetPropNode(node, "ref"); 7166 if (attr != NULL) { 7167 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7168 NULL, attr, &tmpNs, &tmpName) != 0) { 7169 return (NULL); 7170 } 7171 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7172 return(NULL); 7173 isRef = 1; 7174 } 7175 nberrors = pctxt->nberrors; 7176 /* 7177 * Check for illegal attributes. 7178 */ 7179 attr = node->properties; 7180 while (attr != NULL) { 7181 if (attr->ns == NULL) { 7182 if (isRef) { 7183 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7184 xmlSchemaPValAttrNodeID(pctxt, attr); 7185 goto attr_next; 7186 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7187 goto attr_next; 7188 } 7189 } else { 7190 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7191 goto attr_next; 7192 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7193 xmlSchemaPValAttrNodeID(pctxt, attr); 7194 goto attr_next; 7195 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7196 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7197 attr, &tmpNs, &tmpName); 7198 goto attr_next; 7199 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7200 /* 7201 * Evaluate the target namespace 7202 */ 7203 hasForm = 1; 7204 attrValue = xmlSchemaGetNodeContent(pctxt, 7205 (xmlNodePtr) attr); 7206 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7207 ns = pctxt->targetNamespace; 7208 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7209 { 7210 xmlSchemaPSimpleTypeErr(pctxt, 7211 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7212 NULL, (xmlNodePtr) attr, 7213 NULL, "(qualified | unqualified)", 7214 attrValue, NULL, NULL, NULL); 7215 } 7216 goto attr_next; 7217 } 7218 } 7219 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7220 7221 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7222 /* TODO: Maybe we need to normalize the value beforehand. */ 7223 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7224 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7225 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7226 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7227 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7228 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7229 else { 7230 xmlSchemaPSimpleTypeErr(pctxt, 7231 XML_SCHEMAP_INVALID_ATTR_USE, 7232 NULL, (xmlNodePtr) attr, 7233 NULL, "(optional | prohibited | required)", 7234 attrValue, NULL, NULL, NULL); 7235 } 7236 goto attr_next; 7237 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7238 /* 7239 * 3.2.3 : 1 7240 * default and fixed must not both be present. 7241 */ 7242 if (defValue) { 7243 xmlSchemaPMutualExclAttrErr(pctxt, 7244 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7245 NULL, attr, "default", "fixed"); 7246 } else { 7247 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7248 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7249 } 7250 goto attr_next; 7251 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7252 /* 7253 * 3.2.3 : 1 7254 * default and fixed must not both be present. 7255 */ 7256 if (defValue) { 7257 xmlSchemaPMutualExclAttrErr(pctxt, 7258 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7259 NULL, attr, "default", "fixed"); 7260 } else { 7261 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7262 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7263 } 7264 goto attr_next; 7265 } 7266 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7267 goto attr_next; 7268 7269 xmlSchemaPIllegalAttrErr(pctxt, 7270 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7271 7272 attr_next: 7273 attr = attr->next; 7274 } 7275 /* 7276 * 3.2.3 : 2 7277 * If default and use are both present, use must have 7278 * the actual value optional. 7279 */ 7280 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7281 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7282 xmlSchemaPSimpleTypeErr(pctxt, 7283 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7284 NULL, node, NULL, 7285 "(optional | prohibited | required)", NULL, 7286 "The value of the attribute 'use' must be 'optional' " 7287 "if the attribute 'default' is present", 7288 NULL, NULL); 7289 } 7290 /* 7291 * We want correct attributes. 7292 */ 7293 if (nberrors != pctxt->nberrors) 7294 return(NULL); 7295 if (! isRef) { 7296 xmlSchemaAttributePtr attrDecl; 7297 7298 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7299 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7300 ns = pctxt->targetNamespace; 7301 /* 7302 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7303 * TODO: Move this to the component layer. 7304 */ 7305 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7306 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7307 XML_SCHEMAP_NO_XSI, 7308 node, NULL, 7309 "The target namespace must not match '%s'", 7310 xmlSchemaInstanceNs, NULL); 7311 } 7312 attr = xmlSchemaGetPropNode(node, "name"); 7313 if (attr == NULL) { 7314 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7315 NULL, node, "name", NULL); 7316 return (NULL); 7317 } 7318 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7319 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7320 return (NULL); 7321 } 7322 /* 7323 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7324 * TODO: Move this to the component layer. 7325 */ 7326 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7327 xmlSchemaPSimpleTypeErr(pctxt, 7328 XML_SCHEMAP_NO_XMLNS, 7329 NULL, (xmlNodePtr) attr, 7330 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7331 "The value of the attribute must not match 'xmlns'", 7332 NULL, NULL); 7333 return (NULL); 7334 } 7335 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7336 goto check_children; 7337 /* 7338 * Create the attribute use component. 7339 */ 7340 use = xmlSchemaAddAttributeUse(pctxt, node); 7341 if (use == NULL) 7342 return(NULL); 7343 use->occurs = occurs; 7344 /* 7345 * Create the attribute declaration. 7346 */ 7347 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7348 if (attrDecl == NULL) 7349 return (NULL); 7350 if (tmpName != NULL) { 7351 attrDecl->typeName = tmpName; 7352 attrDecl->typeNs = tmpNs; 7353 } 7354 use->attrDecl = attrDecl; 7355 /* 7356 * Value constraint. 7357 */ 7358 if (defValue != NULL) { 7359 attrDecl->defValue = defValue; 7360 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7361 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7362 } 7363 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7364 xmlSchemaQNameRefPtr ref; 7365 7366 /* 7367 * Create the attribute use component. 7368 */ 7369 use = xmlSchemaAddAttributeUse(pctxt, node); 7370 if (use == NULL) 7371 return(NULL); 7372 /* 7373 * We need to resolve the reference at later stage. 7374 */ 7375 WXS_ADD_PENDING(pctxt, use); 7376 use->occurs = occurs; 7377 /* 7378 * Create a QName reference to the attribute declaration. 7379 */ 7380 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7381 tmpName, tmpNs); 7382 if (ref == NULL) 7383 return(NULL); 7384 /* 7385 * Assign the reference. This will be substituted for the 7386 * referenced attribute declaration when the QName is resolved. 7387 */ 7388 use->attrDecl = WXS_ATTR_CAST ref; 7389 /* 7390 * Value constraint. 7391 */ 7392 if (defValue != NULL) 7393 use->defValue = defValue; 7394 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7395 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7396 } 7397 7398 check_children: 7399 /* 7400 * And now for the children... 7401 */ 7402 child = node->children; 7403 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7404 xmlSchemaAttributeUseProhibPtr prohib; 7405 7406 if (IS_SCHEMA(child, "annotation")) { 7407 xmlSchemaParseAnnotation(pctxt, child, 0); 7408 child = child->next; 7409 } 7410 if (child != NULL) { 7411 xmlSchemaPContentErr(pctxt, 7412 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7413 NULL, node, child, NULL, 7414 "(annotation?)"); 7415 } 7416 /* 7417 * Check for pointlessness of attribute prohibitions. 7418 */ 7419 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7420 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7421 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7422 node, NULL, 7423 "Skipping attribute use prohibition, since it is " 7424 "pointless inside an <attributeGroup>", 7425 NULL, NULL, NULL); 7426 return(NULL); 7427 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7428 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7429 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7430 node, NULL, 7431 "Skipping attribute use prohibition, since it is " 7432 "pointless when extending a type", 7433 NULL, NULL, NULL); 7434 return(NULL); 7435 } 7436 if (! isRef) { 7437 tmpName = name; 7438 tmpNs = ns; 7439 } 7440 /* 7441 * Check for duplicate attribute prohibitions. 7442 */ 7443 if (uses) { 7444 int i; 7445 7446 for (i = 0; i < uses->nbItems; i++) { 7447 use = uses->items[i]; 7448 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7449 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7450 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7451 { 7452 xmlChar *str = NULL; 7453 7454 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7455 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7456 node, NULL, 7457 "Skipping duplicate attribute use prohibition '%s'", 7458 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7459 NULL, NULL); 7460 FREE_AND_NULL(str) 7461 return(NULL); 7462 } 7463 } 7464 } 7465 /* 7466 * Create the attribute prohibition helper component. 7467 */ 7468 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7469 if (prohib == NULL) 7470 return(NULL); 7471 prohib->node = node; 7472 prohib->name = tmpName; 7473 prohib->targetNamespace = tmpNs; 7474 if (isRef) { 7475 /* 7476 * We need at least to resolve to the attribute declaration. 7477 */ 7478 WXS_ADD_PENDING(pctxt, prohib); 7479 } 7480 return(WXS_BASIC_CAST prohib); 7481 } else { 7482 if (IS_SCHEMA(child, "annotation")) { 7483 /* 7484 * TODO: Should this go into the attr decl? 7485 */ 7486 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7487 child = child->next; 7488 } 7489 if (isRef) { 7490 if (child != NULL) { 7491 if (IS_SCHEMA(child, "simpleType")) 7492 /* 7493 * 3.2.3 : 3.2 7494 * If ref is present, then all of <simpleType>, 7495 * form and type must be absent. 7496 */ 7497 xmlSchemaPContentErr(pctxt, 7498 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7499 NULL, node, child, NULL, 7500 "(annotation?)"); 7501 else 7502 xmlSchemaPContentErr(pctxt, 7503 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7504 NULL, node, child, NULL, 7505 "(annotation?)"); 7506 } 7507 } else { 7508 if (IS_SCHEMA(child, "simpleType")) { 7509 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7510 /* 7511 * 3.2.3 : 4 7512 * type and <simpleType> must not both be present. 7513 */ 7514 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7515 NULL, node, child, 7516 "The attribute 'type' and the <simpleType> child " 7517 "are mutually exclusive", NULL); 7518 } else 7519 WXS_ATTRUSE_TYPEDEF(use) = 7520 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7521 child = child->next; 7522 } 7523 if (child != NULL) 7524 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7525 NULL, node, child, NULL, 7526 "(annotation?, simpleType?)"); 7527 } 7528 } 7529 return (WXS_BASIC_CAST use); 7530 } 7531 7532 7533 static xmlSchemaAttributePtr 7534 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7535 xmlSchemaPtr schema, 7536 xmlNodePtr node) 7537 { 7538 const xmlChar *attrValue; 7539 xmlSchemaAttributePtr ret; 7540 xmlNodePtr child = NULL; 7541 xmlAttrPtr attr; 7542 7543 /* 7544 * Note that the w3c spec assumes the schema to be validated with schema 7545 * for schemas beforehand. 7546 * 7547 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7548 */ 7549 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7550 return (NULL); 7551 /* 7552 * 3.2.3 : 3.1 7553 * One of ref or name must be present, but not both 7554 */ 7555 attr = xmlSchemaGetPropNode(node, "name"); 7556 if (attr == NULL) { 7557 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7558 NULL, node, "name", NULL); 7559 return (NULL); 7560 } 7561 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7562 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7563 return (NULL); 7564 } 7565 /* 7566 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7567 * TODO: Move this to the component layer. 7568 */ 7569 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7570 xmlSchemaPSimpleTypeErr(pctxt, 7571 XML_SCHEMAP_NO_XMLNS, 7572 NULL, (xmlNodePtr) attr, 7573 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7574 "The value of the attribute must not match 'xmlns'", 7575 NULL, NULL); 7576 return (NULL); 7577 } 7578 /* 7579 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7580 * TODO: Move this to the component layer. 7581 * Or better leave it here and add it to the component layer 7582 * if we have a schema construction API. 7583 */ 7584 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7585 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7586 XML_SCHEMAP_NO_XSI, node, NULL, 7587 "The target namespace must not match '%s'", 7588 xmlSchemaInstanceNs, NULL); 7589 } 7590 7591 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7592 pctxt->targetNamespace, node, 1); 7593 if (ret == NULL) 7594 return (NULL); 7595 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7596 7597 /* 7598 * Check for illegal attributes. 7599 */ 7600 attr = node->properties; 7601 while (attr != NULL) { 7602 if (attr->ns == NULL) { 7603 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7604 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7605 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7606 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7607 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7608 { 7609 xmlSchemaPIllegalAttrErr(pctxt, 7610 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7611 } 7612 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7613 xmlSchemaPIllegalAttrErr(pctxt, 7614 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7615 } 7616 attr = attr->next; 7617 } 7618 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7619 node, "type", &ret->typeNs, &ret->typeName); 7620 7621 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7622 /* 7623 * Attribute "fixed". 7624 */ 7625 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7626 if (ret->defValue != NULL) 7627 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7628 /* 7629 * Attribute "default". 7630 */ 7631 attr = xmlSchemaGetPropNode(node, "default"); 7632 if (attr != NULL) { 7633 /* 7634 * 3.2.3 : 1 7635 * default and fixed must not both be present. 7636 */ 7637 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7638 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7639 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7640 } else 7641 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7642 } 7643 /* 7644 * And now for the children... 7645 */ 7646 child = node->children; 7647 if (IS_SCHEMA(child, "annotation")) { 7648 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7649 child = child->next; 7650 } 7651 if (IS_SCHEMA(child, "simpleType")) { 7652 if (ret->typeName != NULL) { 7653 /* 7654 * 3.2.3 : 4 7655 * type and <simpleType> must not both be present. 7656 */ 7657 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7658 NULL, node, child, 7659 "The attribute 'type' and the <simpleType> child " 7660 "are mutually exclusive", NULL); 7661 } else 7662 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7663 child = child->next; 7664 } 7665 if (child != NULL) 7666 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7667 NULL, node, child, NULL, 7668 "(annotation?, simpleType?)"); 7669 7670 return (ret); 7671 } 7672 7673 /** 7674 * xmlSchemaParseAttributeGroupRef: 7675 * @ctxt: a schema validation context 7676 * @schema: the schema being built 7677 * @node: a subtree containing XML Schema informations 7678 * 7679 * Parse an attribute group definition reference. 7680 * Note that a reference to an attribute group does not 7681 * correspond to any component at all. 7682 * *WARNING* this interface is highly subject to change 7683 * 7684 * Returns the attribute group or NULL in case of error. 7685 */ 7686 static xmlSchemaQNameRefPtr 7687 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7688 xmlSchemaPtr schema, 7689 xmlNodePtr node) 7690 { 7691 xmlSchemaQNameRefPtr ret; 7692 xmlNodePtr child = NULL; 7693 xmlAttrPtr attr; 7694 const xmlChar *refNs = NULL, *ref = NULL; 7695 7696 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7697 return (NULL); 7698 7699 attr = xmlSchemaGetPropNode(node, "ref"); 7700 if (attr == NULL) { 7701 xmlSchemaPMissingAttrErr(pctxt, 7702 XML_SCHEMAP_S4S_ATTR_MISSING, 7703 NULL, node, "ref", NULL); 7704 return (NULL); 7705 } 7706 xmlSchemaPValAttrNodeQName(pctxt, schema, 7707 NULL, attr, &refNs, &ref); 7708 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7709 return(NULL); 7710 7711 /* 7712 * Check for illegal attributes. 7713 */ 7714 attr = node->properties; 7715 while (attr != NULL) { 7716 if (attr->ns == NULL) { 7717 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7718 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7719 { 7720 xmlSchemaPIllegalAttrErr(pctxt, 7721 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7722 } 7723 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7724 xmlSchemaPIllegalAttrErr(pctxt, 7725 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7726 } 7727 attr = attr->next; 7728 } 7729 /* Attribute ID */ 7730 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7731 7732 /* 7733 * And now for the children... 7734 */ 7735 child = node->children; 7736 if (IS_SCHEMA(child, "annotation")) { 7737 /* 7738 * TODO: We do not have a place to store the annotation, do we? 7739 */ 7740 xmlSchemaParseAnnotation(pctxt, child, 0); 7741 child = child->next; 7742 } 7743 if (child != NULL) { 7744 xmlSchemaPContentErr(pctxt, 7745 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7746 NULL, node, child, NULL, 7747 "(annotation?)"); 7748 } 7749 7750 /* 7751 * Handle attribute group redefinitions. 7752 */ 7753 if (pctxt->isRedefine && pctxt->redef && 7754 (pctxt->redef->item->type == 7755 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7756 (ref == pctxt->redef->refName) && 7757 (refNs == pctxt->redef->refTargetNs)) 7758 { 7759 /* 7760 * SPEC src-redefine: 7761 * (7.1) "If it has an <attributeGroup> among its contents 7762 * the `actual value` of whose ref [attribute] is the same 7763 * as the `actual value` of its own name attribute plus 7764 * target namespace, then it must have exactly one such group." 7765 */ 7766 if (pctxt->redefCounter != 0) { 7767 xmlChar *str = NULL; 7768 7769 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7770 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7771 "The redefining attribute group definition " 7772 "'%s' must not contain more than one " 7773 "reference to the redefined definition", 7774 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7775 FREE_AND_NULL(str); 7776 return(NULL); 7777 } 7778 pctxt->redefCounter++; 7779 /* 7780 * URGENT TODO: How to ensure that the reference will not be 7781 * handled by the normal component resolution mechanism? 7782 */ 7783 ret = xmlSchemaNewQNameRef(pctxt, 7784 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7785 if (ret == NULL) 7786 return(NULL); 7787 ret->node = node; 7788 pctxt->redef->reference = WXS_BASIC_CAST ret; 7789 } else { 7790 /* 7791 * Create a QName-reference helper component. We will substitute this 7792 * component for the attribute uses of the referenced attribute group 7793 * definition. 7794 */ 7795 ret = xmlSchemaNewQNameRef(pctxt, 7796 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7797 if (ret == NULL) 7798 return(NULL); 7799 ret->node = node; 7800 /* Add to pending items, to be able to resolve the reference. */ 7801 WXS_ADD_PENDING(pctxt, ret); 7802 } 7803 return (ret); 7804 } 7805 7806 /** 7807 * xmlSchemaParseAttributeGroupDefinition: 7808 * @pctxt: a schema validation context 7809 * @schema: the schema being built 7810 * @node: a subtree containing XML Schema informations 7811 * 7812 * parse a XML schema Attribute Group declaration 7813 * *WARNING* this interface is highly subject to change 7814 * 7815 * Returns the attribute group definition or NULL in case of error. 7816 */ 7817 static xmlSchemaAttributeGroupPtr 7818 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7819 xmlSchemaPtr schema, 7820 xmlNodePtr node) 7821 { 7822 const xmlChar *name; 7823 xmlSchemaAttributeGroupPtr ret; 7824 xmlNodePtr child = NULL; 7825 xmlAttrPtr attr; 7826 int hasRefs = 0; 7827 7828 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7829 return (NULL); 7830 7831 attr = xmlSchemaGetPropNode(node, "name"); 7832 if (attr == NULL) { 7833 xmlSchemaPMissingAttrErr(pctxt, 7834 XML_SCHEMAP_S4S_ATTR_MISSING, 7835 NULL, node, "name", NULL); 7836 return (NULL); 7837 } 7838 /* 7839 * The name is crucial, exit if invalid. 7840 */ 7841 if (xmlSchemaPValAttrNode(pctxt, 7842 NULL, attr, 7843 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7844 return (NULL); 7845 } 7846 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7847 name, pctxt->targetNamespace, node); 7848 if (ret == NULL) 7849 return (NULL); 7850 /* 7851 * Check for illegal attributes. 7852 */ 7853 attr = node->properties; 7854 while (attr != NULL) { 7855 if (attr->ns == NULL) { 7856 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7857 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7858 { 7859 xmlSchemaPIllegalAttrErr(pctxt, 7860 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7861 } 7862 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7863 xmlSchemaPIllegalAttrErr(pctxt, 7864 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7865 } 7866 attr = attr->next; 7867 } 7868 /* Attribute ID */ 7869 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7870 /* 7871 * And now for the children... 7872 */ 7873 child = node->children; 7874 if (IS_SCHEMA(child, "annotation")) { 7875 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7876 child = child->next; 7877 } 7878 /* 7879 * Parse contained attribute decls/refs. 7880 */ 7881 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7882 (xmlSchemaItemListPtr *) &(ret->attrUses), 7883 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7884 return(NULL); 7885 if (hasRefs) 7886 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7887 /* 7888 * Parse the attribute wildcard. 7889 */ 7890 if (IS_SCHEMA(child, "anyAttribute")) { 7891 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7892 schema, child); 7893 child = child->next; 7894 } 7895 if (child != NULL) { 7896 xmlSchemaPContentErr(pctxt, 7897 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7898 NULL, node, child, NULL, 7899 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7900 } 7901 return (ret); 7902 } 7903 7904 /** 7905 * xmlSchemaPValAttrFormDefault: 7906 * @value: the value 7907 * @flags: the flags to be modified 7908 * @flagQualified: the specific flag for "qualified" 7909 * 7910 * Returns 0 if the value is valid, 1 otherwise. 7911 */ 7912 static int 7913 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7914 int *flags, 7915 int flagQualified) 7916 { 7917 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7918 if ((*flags & flagQualified) == 0) 7919 *flags |= flagQualified; 7920 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7921 return (1); 7922 7923 return (0); 7924 } 7925 7926 /** 7927 * xmlSchemaPValAttrBlockFinal: 7928 * @value: the value 7929 * @flags: the flags to be modified 7930 * @flagAll: the specific flag for "#all" 7931 * @flagExtension: the specific flag for "extension" 7932 * @flagRestriction: the specific flag for "restriction" 7933 * @flagSubstitution: the specific flag for "substitution" 7934 * @flagList: the specific flag for "list" 7935 * @flagUnion: the specific flag for "union" 7936 * 7937 * Validates the value of the attribute "final" and "block". The value 7938 * is converted into the specified flag values and returned in @flags. 7939 * 7940 * Returns 0 if the value is valid, 1 otherwise. 7941 */ 7942 7943 static int 7944 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7945 int *flags, 7946 int flagAll, 7947 int flagExtension, 7948 int flagRestriction, 7949 int flagSubstitution, 7950 int flagList, 7951 int flagUnion) 7952 { 7953 int ret = 0; 7954 7955 /* 7956 * TODO: This does not check for dublicate entries. 7957 */ 7958 if ((flags == NULL) || (value == NULL)) 7959 return (-1); 7960 if (value[0] == 0) 7961 return (0); 7962 if (xmlStrEqual(value, BAD_CAST "#all")) { 7963 if (flagAll != -1) 7964 *flags |= flagAll; 7965 else { 7966 if (flagExtension != -1) 7967 *flags |= flagExtension; 7968 if (flagRestriction != -1) 7969 *flags |= flagRestriction; 7970 if (flagSubstitution != -1) 7971 *flags |= flagSubstitution; 7972 if (flagList != -1) 7973 *flags |= flagList; 7974 if (flagUnion != -1) 7975 *flags |= flagUnion; 7976 } 7977 } else { 7978 const xmlChar *end, *cur = value; 7979 xmlChar *item; 7980 7981 do { 7982 while (IS_BLANK_CH(*cur)) 7983 cur++; 7984 end = cur; 7985 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7986 end++; 7987 if (end == cur) 7988 break; 7989 item = xmlStrndup(cur, end - cur); 7990 if (xmlStrEqual(item, BAD_CAST "extension")) { 7991 if (flagExtension != -1) { 7992 if ((*flags & flagExtension) == 0) 7993 *flags |= flagExtension; 7994 } else 7995 ret = 1; 7996 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7997 if (flagRestriction != -1) { 7998 if ((*flags & flagRestriction) == 0) 7999 *flags |= flagRestriction; 8000 } else 8001 ret = 1; 8002 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 8003 if (flagSubstitution != -1) { 8004 if ((*flags & flagSubstitution) == 0) 8005 *flags |= flagSubstitution; 8006 } else 8007 ret = 1; 8008 } else if (xmlStrEqual(item, BAD_CAST "list")) { 8009 if (flagList != -1) { 8010 if ((*flags & flagList) == 0) 8011 *flags |= flagList; 8012 } else 8013 ret = 1; 8014 } else if (xmlStrEqual(item, BAD_CAST "union")) { 8015 if (flagUnion != -1) { 8016 if ((*flags & flagUnion) == 0) 8017 *flags |= flagUnion; 8018 } else 8019 ret = 1; 8020 } else 8021 ret = 1; 8022 if (item != NULL) 8023 xmlFree(item); 8024 cur = end; 8025 } while ((ret == 0) && (*cur != 0)); 8026 } 8027 8028 return (ret); 8029 } 8030 8031 static int 8032 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 8033 xmlSchemaIDCPtr idc, 8034 xmlSchemaIDCSelectPtr selector, 8035 xmlAttrPtr attr, 8036 int isField) 8037 { 8038 xmlNodePtr node; 8039 8040 /* 8041 * c-selector-xpath: 8042 * Schema Component Constraint: Selector Value OK 8043 * 8044 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8045 * in [XPath]. 8046 */ 8047 if (selector == NULL) { 8048 xmlSchemaPErr(ctxt, idc->node, 8049 XML_SCHEMAP_INTERNAL, 8050 "Internal error: xmlSchemaCheckCSelectorXPath, " 8051 "the selector is not specified.\n", NULL, NULL); 8052 return (-1); 8053 } 8054 if (attr == NULL) 8055 node = idc->node; 8056 else 8057 node = (xmlNodePtr) attr; 8058 if (selector->xpath == NULL) { 8059 xmlSchemaPCustomErr(ctxt, 8060 /* TODO: Adjust error code. */ 8061 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8062 NULL, node, 8063 "The XPath expression of the selector is not valid", NULL); 8064 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8065 } else { 8066 const xmlChar **nsArray = NULL; 8067 xmlNsPtr *nsList = NULL; 8068 /* 8069 * Compile the XPath expression. 8070 */ 8071 /* 8072 * TODO: We need the array of in-scope namespaces for compilation. 8073 * TODO: Call xmlPatterncompile with different options for selector/ 8074 * field. 8075 */ 8076 if (attr == NULL) 8077 nsList = NULL; 8078 else 8079 nsList = xmlGetNsList(attr->doc, attr->parent); 8080 /* 8081 * Build an array of prefixes and namespaces. 8082 */ 8083 if (nsList != NULL) { 8084 int i, count = 0; 8085 8086 for (i = 0; nsList[i] != NULL; i++) 8087 count++; 8088 8089 nsArray = (const xmlChar **) xmlMalloc( 8090 (count * 2 + 1) * sizeof(const xmlChar *)); 8091 if (nsArray == NULL) { 8092 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8093 NULL); 8094 xmlFree(nsList); 8095 return (-1); 8096 } 8097 for (i = 0; i < count; i++) { 8098 nsArray[2 * i] = nsList[i]->href; 8099 nsArray[2 * i + 1] = nsList[i]->prefix; 8100 } 8101 nsArray[count * 2] = NULL; 8102 xmlFree(nsList); 8103 } 8104 /* 8105 * TODO: Differentiate between "selector" and "field". 8106 */ 8107 if (isField) 8108 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8109 NULL, XML_PATTERN_XSFIELD, nsArray); 8110 else 8111 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8112 NULL, XML_PATTERN_XSSEL, nsArray); 8113 if (nsArray != NULL) 8114 xmlFree((xmlChar **) nsArray); 8115 8116 if (selector->xpathComp == NULL) { 8117 xmlSchemaPCustomErr(ctxt, 8118 /* TODO: Adjust error code? */ 8119 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8120 NULL, node, 8121 "The XPath expression '%s' could not be " 8122 "compiled", selector->xpath); 8123 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8124 } 8125 } 8126 return (0); 8127 } 8128 8129 #define ADD_ANNOTATION(annot) \ 8130 xmlSchemaAnnotPtr cur = item->annot; \ 8131 if (item->annot == NULL) { \ 8132 item->annot = annot; \ 8133 return (annot); \ 8134 } \ 8135 cur = item->annot; \ 8136 if (cur->next != NULL) { \ 8137 cur = cur->next; \ 8138 } \ 8139 cur->next = annot; 8140 8141 /** 8142 * xmlSchemaAssignAnnotation: 8143 * @item: the schema component 8144 * @annot: the annotation 8145 * 8146 * Adds the annotation to the given schema component. 8147 * 8148 * Returns the given annotaion. 8149 */ 8150 static xmlSchemaAnnotPtr 8151 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8152 xmlSchemaAnnotPtr annot) 8153 { 8154 if ((annItem == NULL) || (annot == NULL)) 8155 return (NULL); 8156 switch (annItem->type) { 8157 case XML_SCHEMA_TYPE_ELEMENT: { 8158 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8159 ADD_ANNOTATION(annot) 8160 } 8161 break; 8162 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8163 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8164 ADD_ANNOTATION(annot) 8165 } 8166 break; 8167 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8168 case XML_SCHEMA_TYPE_ANY: { 8169 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8170 ADD_ANNOTATION(annot) 8171 } 8172 break; 8173 case XML_SCHEMA_TYPE_PARTICLE: 8174 case XML_SCHEMA_TYPE_IDC_KEY: 8175 case XML_SCHEMA_TYPE_IDC_KEYREF: 8176 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8177 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8178 ADD_ANNOTATION(annot) 8179 } 8180 break; 8181 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8182 xmlSchemaAttributeGroupPtr item = 8183 (xmlSchemaAttributeGroupPtr) annItem; 8184 ADD_ANNOTATION(annot) 8185 } 8186 break; 8187 case XML_SCHEMA_TYPE_NOTATION: { 8188 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8189 ADD_ANNOTATION(annot) 8190 } 8191 break; 8192 case XML_SCHEMA_FACET_MININCLUSIVE: 8193 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8194 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8195 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8196 case XML_SCHEMA_FACET_TOTALDIGITS: 8197 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8198 case XML_SCHEMA_FACET_PATTERN: 8199 case XML_SCHEMA_FACET_ENUMERATION: 8200 case XML_SCHEMA_FACET_WHITESPACE: 8201 case XML_SCHEMA_FACET_LENGTH: 8202 case XML_SCHEMA_FACET_MAXLENGTH: 8203 case XML_SCHEMA_FACET_MINLENGTH: { 8204 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8205 ADD_ANNOTATION(annot) 8206 } 8207 break; 8208 case XML_SCHEMA_TYPE_SIMPLE: 8209 case XML_SCHEMA_TYPE_COMPLEX: { 8210 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8211 ADD_ANNOTATION(annot) 8212 } 8213 break; 8214 case XML_SCHEMA_TYPE_GROUP: { 8215 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8216 ADD_ANNOTATION(annot) 8217 } 8218 break; 8219 case XML_SCHEMA_TYPE_SEQUENCE: 8220 case XML_SCHEMA_TYPE_CHOICE: 8221 case XML_SCHEMA_TYPE_ALL: { 8222 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8223 ADD_ANNOTATION(annot) 8224 } 8225 break; 8226 default: 8227 xmlSchemaPCustomErr(NULL, 8228 XML_SCHEMAP_INTERNAL, 8229 NULL, NULL, 8230 "Internal error: xmlSchemaAddAnnotation, " 8231 "The item is not a annotated schema component", NULL); 8232 break; 8233 } 8234 return (annot); 8235 } 8236 8237 /** 8238 * xmlSchemaParseIDCSelectorAndField: 8239 * @ctxt: a schema validation context 8240 * @schema: the schema being built 8241 * @node: a subtree containing XML Schema informations 8242 * 8243 * Parses a XML Schema identity-contraint definition's 8244 * <selector> and <field> elements. 8245 * 8246 * Returns the parsed identity-constraint definition. 8247 */ 8248 static xmlSchemaIDCSelectPtr 8249 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8250 xmlSchemaIDCPtr idc, 8251 xmlNodePtr node, 8252 int isField) 8253 { 8254 xmlSchemaIDCSelectPtr item; 8255 xmlNodePtr child = NULL; 8256 xmlAttrPtr attr; 8257 8258 /* 8259 * Check for illegal attributes. 8260 */ 8261 attr = node->properties; 8262 while (attr != NULL) { 8263 if (attr->ns == NULL) { 8264 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8265 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8266 xmlSchemaPIllegalAttrErr(ctxt, 8267 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8268 } 8269 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8270 xmlSchemaPIllegalAttrErr(ctxt, 8271 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8272 } 8273 attr = attr->next; 8274 } 8275 /* 8276 * Create the item. 8277 */ 8278 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8279 if (item == NULL) { 8280 xmlSchemaPErrMemory(ctxt, 8281 "allocating a 'selector' of an identity-constraint definition", 8282 NULL); 8283 return (NULL); 8284 } 8285 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8286 /* 8287 * Attribute "xpath" (mandatory). 8288 */ 8289 attr = xmlSchemaGetPropNode(node, "xpath"); 8290 if (attr == NULL) { 8291 xmlSchemaPMissingAttrErr(ctxt, 8292 XML_SCHEMAP_S4S_ATTR_MISSING, 8293 NULL, node, 8294 "name", NULL); 8295 } else { 8296 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8297 /* 8298 * URGENT TODO: "field"s have an other syntax than "selector"s. 8299 */ 8300 8301 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8302 isField) == -1) { 8303 xmlSchemaPErr(ctxt, 8304 (xmlNodePtr) attr, 8305 XML_SCHEMAP_INTERNAL, 8306 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8307 "validating the XPath expression of a IDC selector.\n", 8308 NULL, NULL); 8309 } 8310 8311 } 8312 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8313 /* 8314 * And now for the children... 8315 */ 8316 child = node->children; 8317 if (IS_SCHEMA(child, "annotation")) { 8318 /* 8319 * Add the annotation to the parent IDC. 8320 */ 8321 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8322 xmlSchemaParseAnnotation(ctxt, child, 1)); 8323 child = child->next; 8324 } 8325 if (child != NULL) { 8326 xmlSchemaPContentErr(ctxt, 8327 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8328 NULL, node, child, 8329 NULL, "(annotation?)"); 8330 } 8331 8332 return (item); 8333 } 8334 8335 /** 8336 * xmlSchemaParseIDC: 8337 * @ctxt: a schema validation context 8338 * @schema: the schema being built 8339 * @node: a subtree containing XML Schema informations 8340 * 8341 * Parses a XML Schema identity-contraint definition. 8342 * 8343 * Returns the parsed identity-constraint definition. 8344 */ 8345 static xmlSchemaIDCPtr 8346 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8347 xmlSchemaPtr schema, 8348 xmlNodePtr node, 8349 xmlSchemaTypeType idcCategory, 8350 const xmlChar *targetNamespace) 8351 { 8352 xmlSchemaIDCPtr item = NULL; 8353 xmlNodePtr child = NULL; 8354 xmlAttrPtr attr; 8355 const xmlChar *name = NULL; 8356 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8357 8358 /* 8359 * Check for illegal attributes. 8360 */ 8361 attr = node->properties; 8362 while (attr != NULL) { 8363 if (attr->ns == NULL) { 8364 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8365 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8366 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8367 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8368 xmlSchemaPIllegalAttrErr(ctxt, 8369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8370 } 8371 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8372 xmlSchemaPIllegalAttrErr(ctxt, 8373 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8374 } 8375 attr = attr->next; 8376 } 8377 /* 8378 * Attribute "name" (mandatory). 8379 */ 8380 attr = xmlSchemaGetPropNode(node, "name"); 8381 if (attr == NULL) { 8382 xmlSchemaPMissingAttrErr(ctxt, 8383 XML_SCHEMAP_S4S_ATTR_MISSING, 8384 NULL, node, 8385 "name", NULL); 8386 return (NULL); 8387 } else if (xmlSchemaPValAttrNode(ctxt, 8388 NULL, attr, 8389 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8390 return (NULL); 8391 } 8392 /* Create the component. */ 8393 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8394 idcCategory, node); 8395 if (item == NULL) 8396 return(NULL); 8397 8398 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8399 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8400 /* 8401 * Attribute "refer" (mandatory). 8402 */ 8403 attr = xmlSchemaGetPropNode(node, "refer"); 8404 if (attr == NULL) { 8405 xmlSchemaPMissingAttrErr(ctxt, 8406 XML_SCHEMAP_S4S_ATTR_MISSING, 8407 NULL, node, 8408 "refer", NULL); 8409 } else { 8410 /* 8411 * Create a reference item. 8412 */ 8413 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8414 NULL, NULL); 8415 if (item->ref == NULL) 8416 return (NULL); 8417 xmlSchemaPValAttrNodeQName(ctxt, schema, 8418 NULL, attr, 8419 &(item->ref->targetNamespace), 8420 &(item->ref->name)); 8421 xmlSchemaCheckReference(ctxt, schema, node, attr, 8422 item->ref->targetNamespace); 8423 } 8424 } 8425 /* 8426 * And now for the children... 8427 */ 8428 child = node->children; 8429 if (IS_SCHEMA(child, "annotation")) { 8430 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8431 child = child->next; 8432 } 8433 if (child == NULL) { 8434 xmlSchemaPContentErr(ctxt, 8435 XML_SCHEMAP_S4S_ELEM_MISSING, 8436 NULL, node, child, 8437 "A child element is missing", 8438 "(annotation?, (selector, field+))"); 8439 } 8440 /* 8441 * Child element <selector>. 8442 */ 8443 if (IS_SCHEMA(child, "selector")) { 8444 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8445 item, child, 0); 8446 child = child->next; 8447 /* 8448 * Child elements <field>. 8449 */ 8450 if (IS_SCHEMA(child, "field")) { 8451 do { 8452 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8453 item, child, 1); 8454 if (field != NULL) { 8455 field->index = item->nbFields; 8456 item->nbFields++; 8457 if (lastField != NULL) 8458 lastField->next = field; 8459 else 8460 item->fields = field; 8461 lastField = field; 8462 } 8463 child = child->next; 8464 } while (IS_SCHEMA(child, "field")); 8465 } else { 8466 xmlSchemaPContentErr(ctxt, 8467 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8468 NULL, node, child, 8469 NULL, "(annotation?, (selector, field+))"); 8470 } 8471 } 8472 if (child != NULL) { 8473 xmlSchemaPContentErr(ctxt, 8474 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8475 NULL, node, child, 8476 NULL, "(annotation?, (selector, field+))"); 8477 } 8478 8479 return (item); 8480 } 8481 8482 /** 8483 * xmlSchemaParseElement: 8484 * @ctxt: a schema validation context 8485 * @schema: the schema being built 8486 * @node: a subtree containing XML Schema informations 8487 * @topLevel: indicates if this is global declaration 8488 * 8489 * Parses a XML schema element declaration. 8490 * *WARNING* this interface is highly subject to change 8491 * 8492 * Returns the element declaration or a particle; NULL in case 8493 * of an error or if the particle has minOccurs==maxOccurs==0. 8494 */ 8495 static xmlSchemaBasicItemPtr 8496 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8497 xmlNodePtr node, int *isElemRef, int topLevel) 8498 { 8499 xmlSchemaElementPtr decl = NULL; 8500 xmlSchemaParticlePtr particle = NULL; 8501 xmlSchemaAnnotPtr annot = NULL; 8502 xmlNodePtr child = NULL; 8503 xmlAttrPtr attr, nameAttr; 8504 int min, max, isRef = 0; 8505 xmlChar *des = NULL; 8506 8507 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8508 /* TODO: Complete implementation of 3.3.6 */ 8509 8510 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8511 return (NULL); 8512 8513 if (isElemRef != NULL) 8514 *isElemRef = 0; 8515 /* 8516 * If we get a "ref" attribute on a local <element> we will assume it's 8517 * a reference - even if there's a "name" attribute; this seems to be more 8518 * robust. 8519 */ 8520 nameAttr = xmlSchemaGetPropNode(node, "name"); 8521 attr = xmlSchemaGetPropNode(node, "ref"); 8522 if ((topLevel) || (attr == NULL)) { 8523 if (nameAttr == NULL) { 8524 xmlSchemaPMissingAttrErr(ctxt, 8525 XML_SCHEMAP_S4S_ATTR_MISSING, 8526 NULL, node, "name", NULL); 8527 return (NULL); 8528 } 8529 } else 8530 isRef = 1; 8531 8532 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8533 child = node->children; 8534 if (IS_SCHEMA(child, "annotation")) { 8535 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8536 child = child->next; 8537 } 8538 /* 8539 * Skip particle part if a global declaration. 8540 */ 8541 if (topLevel) 8542 goto declaration_part; 8543 /* 8544 * The particle part ================================================== 8545 */ 8546 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8547 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8548 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8549 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8550 if (particle == NULL) 8551 goto return_null; 8552 8553 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8554 8555 if (isRef) { 8556 const xmlChar *refNs = NULL, *ref = NULL; 8557 xmlSchemaQNameRefPtr refer = NULL; 8558 /* 8559 * The reference part ============================================= 8560 */ 8561 if (isElemRef != NULL) 8562 *isElemRef = 1; 8563 8564 xmlSchemaPValAttrNodeQName(ctxt, schema, 8565 NULL, attr, &refNs, &ref); 8566 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8567 /* 8568 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8569 */ 8570 if (nameAttr != NULL) { 8571 xmlSchemaPMutualExclAttrErr(ctxt, 8572 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8573 } 8574 /* 8575 * Check for illegal attributes. 8576 */ 8577 attr = node->properties; 8578 while (attr != NULL) { 8579 if (attr->ns == NULL) { 8580 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8581 xmlStrEqual(attr->name, BAD_CAST "name") || 8582 xmlStrEqual(attr->name, BAD_CAST "id") || 8583 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8584 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8585 { 8586 attr = attr->next; 8587 continue; 8588 } else { 8589 /* SPEC (3.3.3 : 2.2) */ 8590 xmlSchemaPCustomAttrErr(ctxt, 8591 XML_SCHEMAP_SRC_ELEMENT_2_2, 8592 NULL, NULL, attr, 8593 "Only the attributes 'minOccurs', 'maxOccurs' and " 8594 "'id' are allowed in addition to 'ref'"); 8595 break; 8596 } 8597 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8598 xmlSchemaPIllegalAttrErr(ctxt, 8599 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8600 } 8601 attr = attr->next; 8602 } 8603 /* 8604 * No children except <annotation> expected. 8605 */ 8606 if (child != NULL) { 8607 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8608 NULL, node, child, NULL, "(annotation?)"); 8609 } 8610 if ((min == 0) && (max == 0)) 8611 goto return_null; 8612 /* 8613 * Create the reference item and attach it to the particle. 8614 */ 8615 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8616 ref, refNs); 8617 if (refer == NULL) 8618 goto return_null; 8619 particle->children = (xmlSchemaTreeItemPtr) refer; 8620 particle->annot = annot; 8621 /* 8622 * Add the particle to pending components, since the reference 8623 * need to be resolved. 8624 */ 8625 WXS_ADD_PENDING(ctxt, particle); 8626 return ((xmlSchemaBasicItemPtr) particle); 8627 } 8628 /* 8629 * The declaration part =============================================== 8630 */ 8631 declaration_part: 8632 { 8633 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8634 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8635 8636 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8637 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8638 goto return_null; 8639 /* 8640 * Evaluate the target namespace. 8641 */ 8642 if (topLevel) { 8643 ns = ctxt->targetNamespace; 8644 } else { 8645 attr = xmlSchemaGetPropNode(node, "form"); 8646 if (attr != NULL) { 8647 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8648 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8649 ns = ctxt->targetNamespace; 8650 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8651 xmlSchemaPSimpleTypeErr(ctxt, 8652 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8653 NULL, (xmlNodePtr) attr, 8654 NULL, "(qualified | unqualified)", 8655 attrValue, NULL, NULL, NULL); 8656 } 8657 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8658 ns = ctxt->targetNamespace; 8659 } 8660 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8661 if (decl == NULL) { 8662 goto return_null; 8663 } 8664 /* 8665 * Check for illegal attributes. 8666 */ 8667 attr = node->properties; 8668 while (attr != NULL) { 8669 if (attr->ns == NULL) { 8670 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8671 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8672 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8673 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8674 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8675 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8676 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8677 { 8678 if (topLevel == 0) { 8679 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8680 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8681 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8682 { 8683 xmlSchemaPIllegalAttrErr(ctxt, 8684 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8685 } 8686 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8687 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8688 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8689 8690 xmlSchemaPIllegalAttrErr(ctxt, 8691 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8692 } 8693 } 8694 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8695 8696 xmlSchemaPIllegalAttrErr(ctxt, 8697 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8698 } 8699 attr = attr->next; 8700 } 8701 /* 8702 * Extract/validate attributes. 8703 */ 8704 if (topLevel) { 8705 /* 8706 * Process top attributes of global element declarations here. 8707 */ 8708 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8709 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8710 xmlSchemaPValAttrQName(ctxt, schema, 8711 NULL, node, "substitutionGroup", 8712 &(decl->substGroupNs), &(decl->substGroup)); 8713 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8714 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8715 /* 8716 * Attribute "final". 8717 */ 8718 attr = xmlSchemaGetPropNode(node, "final"); 8719 if (attr == NULL) { 8720 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8721 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8722 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8723 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8724 } else { 8725 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8726 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8727 -1, 8728 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8729 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8730 xmlSchemaPSimpleTypeErr(ctxt, 8731 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8732 NULL, (xmlNodePtr) attr, 8733 NULL, "(#all | List of (extension | restriction))", 8734 attrValue, NULL, NULL, NULL); 8735 } 8736 } 8737 } 8738 /* 8739 * Attribute "block". 8740 */ 8741 attr = xmlSchemaGetPropNode(node, "block"); 8742 if (attr == NULL) { 8743 /* 8744 * Apply default "block" values. 8745 */ 8746 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8747 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8748 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8749 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8750 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8751 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8752 } else { 8753 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8754 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8755 -1, 8756 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8757 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8758 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8759 xmlSchemaPSimpleTypeErr(ctxt, 8760 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8761 NULL, (xmlNodePtr) attr, 8762 NULL, "(#all | List of (extension | " 8763 "restriction | substitution))", attrValue, 8764 NULL, NULL, NULL); 8765 } 8766 } 8767 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8768 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8769 8770 attr = xmlSchemaGetPropNode(node, "type"); 8771 if (attr != NULL) { 8772 xmlSchemaPValAttrNodeQName(ctxt, schema, 8773 NULL, attr, 8774 &(decl->namedTypeNs), &(decl->namedType)); 8775 xmlSchemaCheckReference(ctxt, schema, node, 8776 attr, decl->namedTypeNs); 8777 } 8778 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8779 attr = xmlSchemaGetPropNode(node, "fixed"); 8780 if (attr != NULL) { 8781 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8782 if (decl->value != NULL) { 8783 /* 8784 * 3.3.3 : 1 8785 * default and fixed must not both be present. 8786 */ 8787 xmlSchemaPMutualExclAttrErr(ctxt, 8788 XML_SCHEMAP_SRC_ELEMENT_1, 8789 NULL, attr, "default", "fixed"); 8790 } else { 8791 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8792 decl->value = fixed; 8793 } 8794 } 8795 /* 8796 * And now for the children... 8797 */ 8798 if (IS_SCHEMA(child, "complexType")) { 8799 /* 8800 * 3.3.3 : 3 8801 * "type" and either <simpleType> or <complexType> are mutually 8802 * exclusive 8803 */ 8804 if (decl->namedType != NULL) { 8805 xmlSchemaPContentErr(ctxt, 8806 XML_SCHEMAP_SRC_ELEMENT_3, 8807 NULL, node, child, 8808 "The attribute 'type' and the <complexType> child are " 8809 "mutually exclusive", NULL); 8810 } else 8811 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8812 child = child->next; 8813 } else if (IS_SCHEMA(child, "simpleType")) { 8814 /* 8815 * 3.3.3 : 3 8816 * "type" and either <simpleType> or <complexType> are 8817 * mutually exclusive 8818 */ 8819 if (decl->namedType != NULL) { 8820 xmlSchemaPContentErr(ctxt, 8821 XML_SCHEMAP_SRC_ELEMENT_3, 8822 NULL, node, child, 8823 "The attribute 'type' and the <simpleType> child are " 8824 "mutually exclusive", NULL); 8825 } else 8826 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8827 child = child->next; 8828 } 8829 while ((IS_SCHEMA(child, "unique")) || 8830 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8831 if (IS_SCHEMA(child, "unique")) { 8832 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8833 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8834 } else if (IS_SCHEMA(child, "key")) { 8835 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8836 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8837 } else if (IS_SCHEMA(child, "keyref")) { 8838 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8839 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8840 } 8841 if (lastIDC != NULL) 8842 lastIDC->next = curIDC; 8843 else 8844 decl->idcs = (void *) curIDC; 8845 lastIDC = curIDC; 8846 child = child->next; 8847 } 8848 if (child != NULL) { 8849 xmlSchemaPContentErr(ctxt, 8850 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8851 NULL, node, child, 8852 NULL, "(annotation?, ((simpleType | complexType)?, " 8853 "(unique | key | keyref)*))"); 8854 } 8855 decl->annot = annot; 8856 } 8857 /* 8858 * NOTE: Element Declaration Representation OK 4. will be checked at a 8859 * different layer. 8860 */ 8861 FREE_AND_NULL(des) 8862 if (topLevel) 8863 return ((xmlSchemaBasicItemPtr) decl); 8864 else { 8865 particle->children = (xmlSchemaTreeItemPtr) decl; 8866 return ((xmlSchemaBasicItemPtr) particle); 8867 } 8868 8869 return_null: 8870 FREE_AND_NULL(des); 8871 if (annot != NULL) { 8872 if (particle != NULL) 8873 particle->annot = NULL; 8874 if (decl != NULL) 8875 decl->annot = NULL; 8876 xmlSchemaFreeAnnot(annot); 8877 } 8878 return (NULL); 8879 } 8880 8881 /** 8882 * xmlSchemaParseUnion: 8883 * @ctxt: a schema validation context 8884 * @schema: the schema being built 8885 * @node: a subtree containing XML Schema informations 8886 * 8887 * parse a XML schema Union definition 8888 * *WARNING* this interface is highly subject to change 8889 * 8890 * Returns -1 in case of internal error, 0 in case of success and a positive 8891 * error code otherwise. 8892 */ 8893 static int 8894 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8895 xmlNodePtr node) 8896 { 8897 xmlSchemaTypePtr type; 8898 xmlNodePtr child = NULL; 8899 xmlAttrPtr attr; 8900 const xmlChar *cur = NULL; 8901 8902 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8903 return (-1); 8904 /* Not a component, don't create it. */ 8905 type = ctxt->ctxtType; 8906 /* 8907 * Mark the simple type as being of variety "union". 8908 */ 8909 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8910 /* 8911 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8912 * then the `simple ur-type definition`." 8913 */ 8914 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8915 /* 8916 * Check for illegal attributes. 8917 */ 8918 attr = node->properties; 8919 while (attr != NULL) { 8920 if (attr->ns == NULL) { 8921 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8922 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8923 xmlSchemaPIllegalAttrErr(ctxt, 8924 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8925 } 8926 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8927 xmlSchemaPIllegalAttrErr(ctxt, 8928 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8929 } 8930 attr = attr->next; 8931 } 8932 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8933 /* 8934 * Attribute "memberTypes". This is a list of QNames. 8935 * TODO: Check the value to contain anything. 8936 */ 8937 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8938 if (attr != NULL) { 8939 const xmlChar *end; 8940 xmlChar *tmp; 8941 const xmlChar *localName, *nsName; 8942 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8943 xmlSchemaQNameRefPtr ref; 8944 8945 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8946 type->base = cur; 8947 do { 8948 while (IS_BLANK_CH(*cur)) 8949 cur++; 8950 end = cur; 8951 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8952 end++; 8953 if (end == cur) 8954 break; 8955 tmp = xmlStrndup(cur, end - cur); 8956 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8957 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8958 /* 8959 * Create the member type link. 8960 */ 8961 link = (xmlSchemaTypeLinkPtr) 8962 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8963 if (link == NULL) { 8964 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8965 "allocating a type link", NULL); 8966 return (-1); 8967 } 8968 link->type = NULL; 8969 link->next = NULL; 8970 if (lastLink == NULL) 8971 type->memberTypes = link; 8972 else 8973 lastLink->next = link; 8974 lastLink = link; 8975 /* 8976 * Create a reference item. 8977 */ 8978 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8979 localName, nsName); 8980 if (ref == NULL) { 8981 FREE_AND_NULL(tmp) 8982 return (-1); 8983 } 8984 /* 8985 * Assign the reference to the link, it will be resolved 8986 * later during fixup of the union simple type. 8987 */ 8988 link->type = (xmlSchemaTypePtr) ref; 8989 } 8990 FREE_AND_NULL(tmp) 8991 cur = end; 8992 } while (*cur != 0); 8993 8994 } 8995 /* 8996 * And now for the children... 8997 */ 8998 child = node->children; 8999 if (IS_SCHEMA(child, "annotation")) { 9000 /* 9001 * Add the annotation to the simple type ancestor. 9002 */ 9003 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9004 xmlSchemaParseAnnotation(ctxt, child, 1)); 9005 child = child->next; 9006 } 9007 if (IS_SCHEMA(child, "simpleType")) { 9008 xmlSchemaTypePtr subtype, last = NULL; 9009 9010 /* 9011 * Anchor the member types in the "subtypes" field of the 9012 * simple type. 9013 */ 9014 while (IS_SCHEMA(child, "simpleType")) { 9015 subtype = (xmlSchemaTypePtr) 9016 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9017 if (subtype != NULL) { 9018 if (last == NULL) { 9019 type->subtypes = subtype; 9020 last = subtype; 9021 } else { 9022 last->next = subtype; 9023 last = subtype; 9024 } 9025 last->next = NULL; 9026 } 9027 child = child->next; 9028 } 9029 } 9030 if (child != NULL) { 9031 xmlSchemaPContentErr(ctxt, 9032 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9033 NULL, node, child, NULL, "(annotation?, simpleType*)"); 9034 } 9035 if ((attr == NULL) && (type->subtypes == NULL)) { 9036 /* 9037 * src-union-memberTypes-or-simpleTypes 9038 * Either the memberTypes [attribute] of the <union> element must 9039 * be non-empty or there must be at least one simpleType [child]. 9040 */ 9041 xmlSchemaPCustomErr(ctxt, 9042 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9043 NULL, node, 9044 "Either the attribute 'memberTypes' or " 9045 "at least one <simpleType> child must be present", NULL); 9046 } 9047 return (0); 9048 } 9049 9050 /** 9051 * xmlSchemaParseList: 9052 * @ctxt: a schema validation context 9053 * @schema: the schema being built 9054 * @node: a subtree containing XML Schema informations 9055 * 9056 * parse a XML schema List definition 9057 * *WARNING* this interface is highly subject to change 9058 * 9059 * Returns -1 in case of error, 0 if the declaration is improper and 9060 * 1 in case of success. 9061 */ 9062 static xmlSchemaTypePtr 9063 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9064 xmlNodePtr node) 9065 { 9066 xmlSchemaTypePtr type; 9067 xmlNodePtr child = NULL; 9068 xmlAttrPtr attr; 9069 9070 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9071 return (NULL); 9072 /* Not a component, don't create it. */ 9073 type = ctxt->ctxtType; 9074 /* 9075 * Mark the type as being of variety "list". 9076 */ 9077 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9078 /* 9079 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9080 * then the `simple ur-type definition`." 9081 */ 9082 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9083 /* 9084 * Check for illegal attributes. 9085 */ 9086 attr = node->properties; 9087 while (attr != NULL) { 9088 if (attr->ns == NULL) { 9089 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9090 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9091 xmlSchemaPIllegalAttrErr(ctxt, 9092 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9093 } 9094 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9095 xmlSchemaPIllegalAttrErr(ctxt, 9096 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9097 } 9098 attr = attr->next; 9099 } 9100 9101 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9102 9103 /* 9104 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9105 * fields for holding the reference to the itemType. 9106 * 9107 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9108 * the "ref" fields. 9109 */ 9110 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9111 node, "itemType", &(type->baseNs), &(type->base)); 9112 /* 9113 * And now for the children... 9114 */ 9115 child = node->children; 9116 if (IS_SCHEMA(child, "annotation")) { 9117 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9118 xmlSchemaParseAnnotation(ctxt, child, 1)); 9119 child = child->next; 9120 } 9121 if (IS_SCHEMA(child, "simpleType")) { 9122 /* 9123 * src-list-itemType-or-simpleType 9124 * Either the itemType [attribute] or the <simpleType> [child] of 9125 * the <list> element must be present, but not both. 9126 */ 9127 if (type->base != NULL) { 9128 xmlSchemaPCustomErr(ctxt, 9129 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9130 NULL, node, 9131 "The attribute 'itemType' and the <simpleType> child " 9132 "are mutually exclusive", NULL); 9133 } else { 9134 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9135 } 9136 child = child->next; 9137 } else if (type->base == NULL) { 9138 xmlSchemaPCustomErr(ctxt, 9139 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9140 NULL, node, 9141 "Either the attribute 'itemType' or the <simpleType> child " 9142 "must be present", NULL); 9143 } 9144 if (child != NULL) { 9145 xmlSchemaPContentErr(ctxt, 9146 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9147 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9148 } 9149 if ((type->base == NULL) && 9150 (type->subtypes == NULL) && 9151 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9152 xmlSchemaPCustomErr(ctxt, 9153 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9154 NULL, node, 9155 "Either the attribute 'itemType' or the <simpleType> child " 9156 "must be present", NULL); 9157 } 9158 return (NULL); 9159 } 9160 9161 /** 9162 * xmlSchemaParseSimpleType: 9163 * @ctxt: a schema validation context 9164 * @schema: the schema being built 9165 * @node: a subtree containing XML Schema informations 9166 * 9167 * parse a XML schema Simple Type definition 9168 * *WARNING* this interface is highly subject to change 9169 * 9170 * Returns -1 in case of error, 0 if the declaration is improper and 9171 * 1 in case of success. 9172 */ 9173 static xmlSchemaTypePtr 9174 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9175 xmlNodePtr node, int topLevel) 9176 { 9177 xmlSchemaTypePtr type, oldCtxtType; 9178 xmlNodePtr child = NULL; 9179 const xmlChar *attrValue = NULL; 9180 xmlAttrPtr attr; 9181 int hasRestriction = 0; 9182 9183 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9184 return (NULL); 9185 9186 if (topLevel) { 9187 attr = xmlSchemaGetPropNode(node, "name"); 9188 if (attr == NULL) { 9189 xmlSchemaPMissingAttrErr(ctxt, 9190 XML_SCHEMAP_S4S_ATTR_MISSING, 9191 NULL, node, 9192 "name", NULL); 9193 return (NULL); 9194 } else { 9195 if (xmlSchemaPValAttrNode(ctxt, 9196 NULL, attr, 9197 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9198 return (NULL); 9199 /* 9200 * Skip built-in types. 9201 */ 9202 if (ctxt->isS4S) { 9203 xmlSchemaTypePtr biType; 9204 9205 if (ctxt->isRedefine) { 9206 /* 9207 * REDEFINE: Disallow redefinition of built-in-types. 9208 * TODO: It seems that the spec does not say anything 9209 * about this case. 9210 */ 9211 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9212 NULL, node, 9213 "Redefinition of built-in simple types is not " 9214 "supported", NULL); 9215 return(NULL); 9216 } 9217 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9218 if (biType != NULL) 9219 return (biType); 9220 } 9221 } 9222 } 9223 /* 9224 * TargetNamespace: 9225 * SPEC "The `actual value` of the targetNamespace [attribute] 9226 * of the <schema> ancestor element information item if present, 9227 * otherwise `absent`. 9228 */ 9229 if (topLevel == 0) { 9230 #ifdef ENABLE_NAMED_LOCALS 9231 char buf[40]; 9232 #endif 9233 /* 9234 * Parse as local simple type definition. 9235 */ 9236 #ifdef ENABLE_NAMED_LOCALS 9237 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9238 type = xmlSchemaAddType(ctxt, schema, 9239 XML_SCHEMA_TYPE_SIMPLE, 9240 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9241 ctxt->targetNamespace, node, 0); 9242 #else 9243 type = xmlSchemaAddType(ctxt, schema, 9244 XML_SCHEMA_TYPE_SIMPLE, 9245 NULL, ctxt->targetNamespace, node, 0); 9246 #endif 9247 if (type == NULL) 9248 return (NULL); 9249 type->type = XML_SCHEMA_TYPE_SIMPLE; 9250 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9251 /* 9252 * Check for illegal attributes. 9253 */ 9254 attr = node->properties; 9255 while (attr != NULL) { 9256 if (attr->ns == NULL) { 9257 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9258 xmlSchemaPIllegalAttrErr(ctxt, 9259 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9260 } 9261 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9262 xmlSchemaPIllegalAttrErr(ctxt, 9263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9264 } 9265 attr = attr->next; 9266 } 9267 } else { 9268 /* 9269 * Parse as global simple type definition. 9270 * 9271 * Note that attrValue is the value of the attribute "name" here. 9272 */ 9273 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9274 attrValue, ctxt->targetNamespace, node, 1); 9275 if (type == NULL) 9276 return (NULL); 9277 type->type = XML_SCHEMA_TYPE_SIMPLE; 9278 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9279 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9280 /* 9281 * Check for illegal attributes. 9282 */ 9283 attr = node->properties; 9284 while (attr != NULL) { 9285 if (attr->ns == NULL) { 9286 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9287 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9288 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9289 xmlSchemaPIllegalAttrErr(ctxt, 9290 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9291 } 9292 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9293 xmlSchemaPIllegalAttrErr(ctxt, 9294 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9295 } 9296 attr = attr->next; 9297 } 9298 /* 9299 * Attribute "final". 9300 */ 9301 attr = xmlSchemaGetPropNode(node, "final"); 9302 if (attr == NULL) { 9303 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9304 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9305 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9306 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9307 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9308 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9309 } else { 9310 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9311 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9312 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9313 XML_SCHEMAS_TYPE_FINAL_LIST, 9314 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9315 9316 xmlSchemaPSimpleTypeErr(ctxt, 9317 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9318 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9319 NULL, "(#all | List of (list | union | restriction)", 9320 attrValue, NULL, NULL, NULL); 9321 } 9322 } 9323 } 9324 type->targetNamespace = ctxt->targetNamespace; 9325 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9326 /* 9327 * And now for the children... 9328 */ 9329 oldCtxtType = ctxt->ctxtType; 9330 9331 ctxt->ctxtType = type; 9332 9333 child = node->children; 9334 if (IS_SCHEMA(child, "annotation")) { 9335 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9336 child = child->next; 9337 } 9338 if (child == NULL) { 9339 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9340 NULL, node, child, NULL, 9341 "(annotation?, (restriction | list | union))"); 9342 } else if (IS_SCHEMA(child, "restriction")) { 9343 xmlSchemaParseRestriction(ctxt, schema, child, 9344 XML_SCHEMA_TYPE_SIMPLE); 9345 hasRestriction = 1; 9346 child = child->next; 9347 } else if (IS_SCHEMA(child, "list")) { 9348 xmlSchemaParseList(ctxt, schema, child); 9349 child = child->next; 9350 } else if (IS_SCHEMA(child, "union")) { 9351 xmlSchemaParseUnion(ctxt, schema, child); 9352 child = child->next; 9353 } 9354 if (child != NULL) { 9355 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9356 NULL, node, child, NULL, 9357 "(annotation?, (restriction | list | union))"); 9358 } 9359 /* 9360 * REDEFINE: SPEC src-redefine (5) 9361 * "Within the [children], each <simpleType> must have a 9362 * <restriction> among its [children] ... the `actual value` of whose 9363 * base [attribute] must be the same as the `actual value` of its own 9364 * name attribute plus target namespace;" 9365 */ 9366 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9367 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9368 NULL, node, "This is a redefinition, thus the " 9369 "<simpleType> must have a <restriction> child", NULL); 9370 } 9371 9372 ctxt->ctxtType = oldCtxtType; 9373 return (type); 9374 } 9375 9376 /** 9377 * xmlSchemaParseModelGroupDefRef: 9378 * @ctxt: the parser context 9379 * @schema: the schema being built 9380 * @node: the node 9381 * 9382 * Parses a reference to a model group definition. 9383 * 9384 * We will return a particle component with a qname-component or 9385 * NULL in case of an error. 9386 */ 9387 static xmlSchemaTreeItemPtr 9388 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9389 xmlSchemaPtr schema, 9390 xmlNodePtr node) 9391 { 9392 xmlSchemaParticlePtr item; 9393 xmlNodePtr child = NULL; 9394 xmlAttrPtr attr; 9395 const xmlChar *ref = NULL, *refNs = NULL; 9396 int min, max; 9397 9398 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9399 return (NULL); 9400 9401 attr = xmlSchemaGetPropNode(node, "ref"); 9402 if (attr == NULL) { 9403 xmlSchemaPMissingAttrErr(ctxt, 9404 XML_SCHEMAP_S4S_ATTR_MISSING, 9405 NULL, node, "ref", NULL); 9406 return (NULL); 9407 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9408 attr, &refNs, &ref) != 0) { 9409 return (NULL); 9410 } 9411 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9412 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9413 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9414 "(xs:nonNegativeInteger | unbounded)"); 9415 /* 9416 * Check for illegal attributes. 9417 */ 9418 attr = node->properties; 9419 while (attr != NULL) { 9420 if (attr->ns == NULL) { 9421 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9422 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9423 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9424 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9425 xmlSchemaPIllegalAttrErr(ctxt, 9426 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9427 } 9428 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9429 xmlSchemaPIllegalAttrErr(ctxt, 9430 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9431 } 9432 attr = attr->next; 9433 } 9434 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9435 item = xmlSchemaAddParticle(ctxt, node, min, max); 9436 if (item == NULL) 9437 return (NULL); 9438 /* 9439 * Create a qname-reference and set as the term; it will be substituted 9440 * for the model group after the reference has been resolved. 9441 */ 9442 item->children = (xmlSchemaTreeItemPtr) 9443 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9444 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9445 /* 9446 * And now for the children... 9447 */ 9448 child = node->children; 9449 /* TODO: Is annotation even allowed for a model group reference? */ 9450 if (IS_SCHEMA(child, "annotation")) { 9451 /* 9452 * TODO: What to do exactly with the annotation? 9453 */ 9454 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9455 child = child->next; 9456 } 9457 if (child != NULL) { 9458 xmlSchemaPContentErr(ctxt, 9459 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9460 NULL, node, child, NULL, 9461 "(annotation?)"); 9462 } 9463 /* 9464 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9465 */ 9466 if ((min == 0) && (max == 0)) 9467 return (NULL); 9468 9469 return ((xmlSchemaTreeItemPtr) item); 9470 } 9471 9472 /** 9473 * xmlSchemaParseModelGroupDefinition: 9474 * @ctxt: a schema validation context 9475 * @schema: the schema being built 9476 * @node: a subtree containing XML Schema informations 9477 * 9478 * Parses a XML schema model group definition. 9479 * 9480 * Note that the contraint src-redefine (6.2) can't be applied until 9481 * references have been resolved. So we will do this at the 9482 * component fixup level. 9483 * 9484 * *WARNING* this interface is highly subject to change 9485 * 9486 * Returns -1 in case of error, 0 if the declaration is improper and 9487 * 1 in case of success. 9488 */ 9489 static xmlSchemaModelGroupDefPtr 9490 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9491 xmlSchemaPtr schema, 9492 xmlNodePtr node) 9493 { 9494 xmlSchemaModelGroupDefPtr item; 9495 xmlNodePtr child = NULL; 9496 xmlAttrPtr attr; 9497 const xmlChar *name; 9498 9499 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9500 return (NULL); 9501 9502 attr = xmlSchemaGetPropNode(node, "name"); 9503 if (attr == NULL) { 9504 xmlSchemaPMissingAttrErr(ctxt, 9505 XML_SCHEMAP_S4S_ATTR_MISSING, 9506 NULL, node, 9507 "name", NULL); 9508 return (NULL); 9509 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9510 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9511 return (NULL); 9512 } 9513 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9514 ctxt->targetNamespace, node); 9515 if (item == NULL) 9516 return (NULL); 9517 /* 9518 * Check for illegal attributes. 9519 */ 9520 attr = node->properties; 9521 while (attr != NULL) { 9522 if (attr->ns == NULL) { 9523 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9524 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9525 xmlSchemaPIllegalAttrErr(ctxt, 9526 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9527 } 9528 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9529 xmlSchemaPIllegalAttrErr(ctxt, 9530 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9531 } 9532 attr = attr->next; 9533 } 9534 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9535 /* 9536 * And now for the children... 9537 */ 9538 child = node->children; 9539 if (IS_SCHEMA(child, "annotation")) { 9540 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9541 child = child->next; 9542 } 9543 if (IS_SCHEMA(child, "all")) { 9544 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9545 XML_SCHEMA_TYPE_ALL, 0); 9546 child = child->next; 9547 } else if (IS_SCHEMA(child, "choice")) { 9548 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9549 XML_SCHEMA_TYPE_CHOICE, 0); 9550 child = child->next; 9551 } else if (IS_SCHEMA(child, "sequence")) { 9552 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9553 XML_SCHEMA_TYPE_SEQUENCE, 0); 9554 child = child->next; 9555 } 9556 9557 9558 9559 if (child != NULL) { 9560 xmlSchemaPContentErr(ctxt, 9561 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9562 NULL, node, child, NULL, 9563 "(annotation?, (all | choice | sequence)?)"); 9564 } 9565 return (item); 9566 } 9567 9568 /** 9569 * xmlSchemaCleanupDoc: 9570 * @ctxt: a schema validation context 9571 * @node: the root of the document. 9572 * 9573 * removes unwanted nodes in a schemas document tree 9574 */ 9575 static void 9576 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9577 { 9578 xmlNodePtr delete, cur; 9579 9580 if ((ctxt == NULL) || (root == NULL)) return; 9581 9582 /* 9583 * Remove all the blank text nodes 9584 */ 9585 delete = NULL; 9586 cur = root; 9587 while (cur != NULL) { 9588 if (delete != NULL) { 9589 xmlUnlinkNode(delete); 9590 xmlFreeNode(delete); 9591 delete = NULL; 9592 } 9593 if (cur->type == XML_TEXT_NODE) { 9594 if (IS_BLANK_NODE(cur)) { 9595 if (xmlNodeGetSpacePreserve(cur) != 1) { 9596 delete = cur; 9597 } 9598 } 9599 } else if ((cur->type != XML_ELEMENT_NODE) && 9600 (cur->type != XML_CDATA_SECTION_NODE)) { 9601 delete = cur; 9602 goto skip_children; 9603 } 9604 9605 /* 9606 * Skip to next node 9607 */ 9608 if (cur->children != NULL) { 9609 if ((cur->children->type != XML_ENTITY_DECL) && 9610 (cur->children->type != XML_ENTITY_REF_NODE) && 9611 (cur->children->type != XML_ENTITY_NODE)) { 9612 cur = cur->children; 9613 continue; 9614 } 9615 } 9616 skip_children: 9617 if (cur->next != NULL) { 9618 cur = cur->next; 9619 continue; 9620 } 9621 9622 do { 9623 cur = cur->parent; 9624 if (cur == NULL) 9625 break; 9626 if (cur == root) { 9627 cur = NULL; 9628 break; 9629 } 9630 if (cur->next != NULL) { 9631 cur = cur->next; 9632 break; 9633 } 9634 } while (cur != NULL); 9635 } 9636 if (delete != NULL) { 9637 xmlUnlinkNode(delete); 9638 xmlFreeNode(delete); 9639 delete = NULL; 9640 } 9641 } 9642 9643 9644 static void 9645 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9646 { 9647 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9648 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9649 9650 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9651 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9652 9653 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9654 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9655 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9656 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9657 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9658 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9660 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9661 9662 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9663 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9664 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9665 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9666 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9667 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9668 } 9669 9670 static int 9671 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9672 xmlSchemaPtr schema, 9673 xmlNodePtr node) 9674 { 9675 xmlAttrPtr attr; 9676 const xmlChar *val; 9677 int res = 0, oldErrs = ctxt->nberrors; 9678 9679 /* 9680 * Those flags should be moved to the parser context flags, 9681 * since they are not visible at the component level. I.e. 9682 * they are used if processing schema *documents* only. 9683 */ 9684 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9685 HFAILURE; 9686 9687 /* 9688 * Since the version is of type xs:token, we won't bother to 9689 * check it. 9690 */ 9691 /* REMOVED: 9692 attr = xmlSchemaGetPropNode(node, "version"); 9693 if (attr != NULL) { 9694 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9695 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9696 HFAILURE; 9697 } 9698 */ 9699 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9700 if (attr != NULL) { 9701 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9702 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9703 HFAILURE; 9704 if (res != 0) { 9705 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9706 goto exit; 9707 } 9708 } 9709 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9710 if (attr != NULL) { 9711 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9712 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9713 XML_SCHEMAS_QUALIF_ELEM); 9714 HFAILURE; 9715 if (res != 0) { 9716 xmlSchemaPSimpleTypeErr(ctxt, 9717 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9718 NULL, (xmlNodePtr) attr, NULL, 9719 "(qualified | unqualified)", val, NULL, NULL, NULL); 9720 } 9721 } 9722 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9723 if (attr != NULL) { 9724 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9725 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9726 XML_SCHEMAS_QUALIF_ATTR); 9727 HFAILURE; 9728 if (res != 0) { 9729 xmlSchemaPSimpleTypeErr(ctxt, 9730 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9731 NULL, (xmlNodePtr) attr, NULL, 9732 "(qualified | unqualified)", val, NULL, NULL, NULL); 9733 } 9734 } 9735 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9736 if (attr != NULL) { 9737 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9738 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9739 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9740 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9741 -1, 9742 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9743 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9744 HFAILURE; 9745 if (res != 0) { 9746 xmlSchemaPSimpleTypeErr(ctxt, 9747 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9748 NULL, (xmlNodePtr) attr, NULL, 9749 "(#all | List of (extension | restriction | list | union))", 9750 val, NULL, NULL, NULL); 9751 } 9752 } 9753 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9754 if (attr != NULL) { 9755 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9756 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9757 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9758 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9759 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9760 HFAILURE; 9761 if (res != 0) { 9762 xmlSchemaPSimpleTypeErr(ctxt, 9763 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9764 NULL, (xmlNodePtr) attr, NULL, 9765 "(#all | List of (extension | restriction | substitution))", 9766 val, NULL, NULL, NULL); 9767 } 9768 } 9769 9770 exit: 9771 if (oldErrs != ctxt->nberrors) 9772 res = ctxt->err; 9773 return(res); 9774 exit_failure: 9775 return(-1); 9776 } 9777 9778 /** 9779 * xmlSchemaParseSchemaTopLevel: 9780 * @ctxt: a schema validation context 9781 * @schema: the schemas 9782 * @nodes: the list of top level nodes 9783 * 9784 * Returns the internal XML Schema structure built from the resource or 9785 * NULL in case of error 9786 */ 9787 static int 9788 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9789 xmlSchemaPtr schema, xmlNodePtr nodes) 9790 { 9791 xmlNodePtr child; 9792 xmlSchemaAnnotPtr annot; 9793 int res = 0, oldErrs, tmpOldErrs; 9794 9795 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9796 return(-1); 9797 9798 oldErrs = ctxt->nberrors; 9799 child = nodes; 9800 while ((IS_SCHEMA(child, "include")) || 9801 (IS_SCHEMA(child, "import")) || 9802 (IS_SCHEMA(child, "redefine")) || 9803 (IS_SCHEMA(child, "annotation"))) { 9804 if (IS_SCHEMA(child, "annotation")) { 9805 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9806 if (schema->annot == NULL) 9807 schema->annot = annot; 9808 else 9809 xmlSchemaFreeAnnot(annot); 9810 } else if (IS_SCHEMA(child, "import")) { 9811 tmpOldErrs = ctxt->nberrors; 9812 res = xmlSchemaParseImport(ctxt, schema, child); 9813 HFAILURE; 9814 HSTOP(ctxt); 9815 if (tmpOldErrs != ctxt->nberrors) 9816 goto exit; 9817 } else if (IS_SCHEMA(child, "include")) { 9818 tmpOldErrs = ctxt->nberrors; 9819 res = xmlSchemaParseInclude(ctxt, schema, child); 9820 HFAILURE; 9821 HSTOP(ctxt); 9822 if (tmpOldErrs != ctxt->nberrors) 9823 goto exit; 9824 } else if (IS_SCHEMA(child, "redefine")) { 9825 tmpOldErrs = ctxt->nberrors; 9826 res = xmlSchemaParseRedefine(ctxt, schema, child); 9827 HFAILURE; 9828 HSTOP(ctxt); 9829 if (tmpOldErrs != ctxt->nberrors) 9830 goto exit; 9831 } 9832 child = child->next; 9833 } 9834 /* 9835 * URGENT TODO: Change the functions to return int results. 9836 * We need especially to catch internal errors. 9837 */ 9838 while (child != NULL) { 9839 if (IS_SCHEMA(child, "complexType")) { 9840 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9841 child = child->next; 9842 } else if (IS_SCHEMA(child, "simpleType")) { 9843 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9844 child = child->next; 9845 } else if (IS_SCHEMA(child, "element")) { 9846 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9847 child = child->next; 9848 } else if (IS_SCHEMA(child, "attribute")) { 9849 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9850 child = child->next; 9851 } else if (IS_SCHEMA(child, "attributeGroup")) { 9852 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9853 child = child->next; 9854 } else if (IS_SCHEMA(child, "group")) { 9855 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9856 child = child->next; 9857 } else if (IS_SCHEMA(child, "notation")) { 9858 xmlSchemaParseNotation(ctxt, schema, child); 9859 child = child->next; 9860 } else { 9861 xmlSchemaPContentErr(ctxt, 9862 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9863 NULL, child->parent, child, 9864 NULL, "((include | import | redefine | annotation)*, " 9865 "(((simpleType | complexType | group | attributeGroup) " 9866 "| element | attribute | notation), annotation*)*)"); 9867 child = child->next; 9868 } 9869 while (IS_SCHEMA(child, "annotation")) { 9870 /* 9871 * TODO: We should add all annotations. 9872 */ 9873 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9874 if (schema->annot == NULL) 9875 schema->annot = annot; 9876 else 9877 xmlSchemaFreeAnnot(annot); 9878 child = child->next; 9879 } 9880 } 9881 exit: 9882 ctxt->ctxtType = NULL; 9883 if (oldErrs != ctxt->nberrors) 9884 res = ctxt->err; 9885 return(res); 9886 exit_failure: 9887 return(-1); 9888 } 9889 9890 static xmlSchemaSchemaRelationPtr 9891 xmlSchemaSchemaRelationCreate(void) 9892 { 9893 xmlSchemaSchemaRelationPtr ret; 9894 9895 ret = (xmlSchemaSchemaRelationPtr) 9896 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9897 if (ret == NULL) { 9898 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9899 return(NULL); 9900 } 9901 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9902 return(ret); 9903 } 9904 9905 #if 0 9906 static void 9907 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9908 { 9909 xmlFree(rel); 9910 } 9911 #endif 9912 9913 static void 9914 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9915 { 9916 xmlSchemaRedefPtr prev; 9917 9918 while (redef != NULL) { 9919 prev = redef; 9920 redef = redef->next; 9921 xmlFree(prev); 9922 } 9923 } 9924 9925 static void 9926 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9927 { 9928 /* 9929 * After the construction context has been freed, there will be 9930 * no schema graph available any more. Only the schema buckets 9931 * will stay alive, which are put into the "schemasImports" and 9932 * "includes" slots of the xmlSchema. 9933 */ 9934 if (con->buckets != NULL) 9935 xmlSchemaItemListFree(con->buckets); 9936 if (con->pending != NULL) 9937 xmlSchemaItemListFree(con->pending); 9938 if (con->substGroups != NULL) 9939 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); 9940 if (con->redefs != NULL) 9941 xmlSchemaRedefListFree(con->redefs); 9942 if (con->dict != NULL) 9943 xmlDictFree(con->dict); 9944 xmlFree(con); 9945 } 9946 9947 static xmlSchemaConstructionCtxtPtr 9948 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9949 { 9950 xmlSchemaConstructionCtxtPtr ret; 9951 9952 ret = (xmlSchemaConstructionCtxtPtr) 9953 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9954 if (ret == NULL) { 9955 xmlSchemaPErrMemory(NULL, 9956 "allocating schema construction context", NULL); 9957 return (NULL); 9958 } 9959 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9960 9961 ret->buckets = xmlSchemaItemListCreate(); 9962 if (ret->buckets == NULL) { 9963 xmlSchemaPErrMemory(NULL, 9964 "allocating list of schema buckets", NULL); 9965 xmlFree(ret); 9966 return (NULL); 9967 } 9968 ret->pending = xmlSchemaItemListCreate(); 9969 if (ret->pending == NULL) { 9970 xmlSchemaPErrMemory(NULL, 9971 "allocating list of pending global components", NULL); 9972 xmlSchemaConstructionCtxtFree(ret); 9973 return (NULL); 9974 } 9975 ret->dict = dict; 9976 xmlDictReference(dict); 9977 return(ret); 9978 } 9979 9980 static xmlSchemaParserCtxtPtr 9981 xmlSchemaParserCtxtCreate(void) 9982 { 9983 xmlSchemaParserCtxtPtr ret; 9984 9985 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9986 if (ret == NULL) { 9987 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9988 NULL); 9989 return (NULL); 9990 } 9991 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9992 ret->type = XML_SCHEMA_CTXT_PARSER; 9993 ret->attrProhibs = xmlSchemaItemListCreate(); 9994 if (ret->attrProhibs == NULL) { 9995 xmlFree(ret); 9996 return(NULL); 9997 } 9998 return(ret); 9999 } 10000 10001 /** 10002 * xmlSchemaNewParserCtxtUseDict: 10003 * @URL: the location of the schema 10004 * @dict: the dictionary to be used 10005 * 10006 * Create an XML Schemas parse context for that file/resource expected 10007 * to contain an XML Schemas file. 10008 * 10009 * Returns the parser context or NULL in case of error 10010 */ 10011 static xmlSchemaParserCtxtPtr 10012 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 10013 { 10014 xmlSchemaParserCtxtPtr ret; 10015 10016 ret = xmlSchemaParserCtxtCreate(); 10017 if (ret == NULL) 10018 return (NULL); 10019 ret->dict = dict; 10020 xmlDictReference(dict); 10021 if (URL != NULL) 10022 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 10023 return (ret); 10024 } 10025 10026 static int 10027 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 10028 { 10029 if (vctxt->pctxt == NULL) { 10030 if (vctxt->schema != NULL) 10031 vctxt->pctxt = 10032 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 10033 else 10034 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 10035 if (vctxt->pctxt == NULL) { 10036 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 10037 "failed to create a temp. parser context"); 10038 return (-1); 10039 } 10040 /* TODO: Pass user data. */ 10041 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10042 vctxt->warning, vctxt->errCtxt); 10043 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10044 vctxt->errCtxt); 10045 } 10046 return (0); 10047 } 10048 10049 /** 10050 * xmlSchemaGetSchemaBucket: 10051 * @pctxt: the schema parser context 10052 * @schemaLocation: the URI of the schema document 10053 * 10054 * Returns a schema bucket if it was already parsed. 10055 * 10056 * Returns a schema bucket if it was already parsed from 10057 * @schemaLocation, NULL otherwise. 10058 */ 10059 static xmlSchemaBucketPtr 10060 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10061 const xmlChar *schemaLocation) 10062 { 10063 xmlSchemaBucketPtr cur; 10064 xmlSchemaItemListPtr list; 10065 10066 list = pctxt->constructor->buckets; 10067 if (list->nbItems == 0) 10068 return(NULL); 10069 else { 10070 int i; 10071 for (i = 0; i < list->nbItems; i++) { 10072 cur = (xmlSchemaBucketPtr) list->items[i]; 10073 /* Pointer comparison! */ 10074 if (cur->schemaLocation == schemaLocation) 10075 return(cur); 10076 } 10077 } 10078 return(NULL); 10079 } 10080 10081 static xmlSchemaBucketPtr 10082 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10083 const xmlChar *schemaLocation, 10084 const xmlChar *targetNamespace) 10085 { 10086 xmlSchemaBucketPtr cur; 10087 xmlSchemaItemListPtr list; 10088 10089 list = pctxt->constructor->buckets; 10090 if (list->nbItems == 0) 10091 return(NULL); 10092 else { 10093 int i; 10094 for (i = 0; i < list->nbItems; i++) { 10095 cur = (xmlSchemaBucketPtr) list->items[i]; 10096 /* Pointer comparison! */ 10097 if ((cur->origTargetNamespace == NULL) && 10098 (cur->schemaLocation == schemaLocation) && 10099 (cur->targetNamespace == targetNamespace)) 10100 return(cur); 10101 } 10102 } 10103 return(NULL); 10104 } 10105 10106 10107 #define IS_BAD_SCHEMA_DOC(b) \ 10108 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10109 10110 static xmlSchemaBucketPtr 10111 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10112 const xmlChar *targetNamespace, 10113 int imported) 10114 { 10115 xmlSchemaBucketPtr cur; 10116 xmlSchemaItemListPtr list; 10117 10118 list = pctxt->constructor->buckets; 10119 if (list->nbItems == 0) 10120 return(NULL); 10121 else { 10122 int i; 10123 for (i = 0; i < list->nbItems; i++) { 10124 cur = (xmlSchemaBucketPtr) list->items[i]; 10125 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10126 (cur->origTargetNamespace == targetNamespace) && 10127 ((imported && cur->imported) || 10128 ((!imported) && (!cur->imported)))) 10129 return(cur); 10130 } 10131 } 10132 return(NULL); 10133 } 10134 10135 static int 10136 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10137 xmlSchemaPtr schema, 10138 xmlSchemaBucketPtr bucket) 10139 { 10140 int oldFlags; 10141 xmlDocPtr oldDoc; 10142 xmlNodePtr node; 10143 int ret, oldErrs; 10144 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10145 10146 /* 10147 * Save old values; reset the *main* schema. 10148 * URGENT TODO: This is not good; move the per-document information 10149 * to the parser. Get rid of passing the main schema to the 10150 * parsing functions. 10151 */ 10152 oldFlags = schema->flags; 10153 oldDoc = schema->doc; 10154 if (schema->flags != 0) 10155 xmlSchemaClearSchemaDefaults(schema); 10156 schema->doc = bucket->doc; 10157 pctxt->schema = schema; 10158 /* 10159 * Keep the current target namespace on the parser *not* on the 10160 * main schema. 10161 */ 10162 pctxt->targetNamespace = bucket->targetNamespace; 10163 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10164 10165 if ((bucket->targetNamespace != NULL) && 10166 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10167 /* 10168 * We are parsing the schema for schemas! 10169 */ 10170 pctxt->isS4S = 1; 10171 } 10172 /* Mark it as parsed, even if parsing fails. */ 10173 bucket->parsed++; 10174 /* Compile the schema doc. */ 10175 node = xmlDocGetRootElement(bucket->doc); 10176 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10177 if (ret != 0) 10178 goto exit; 10179 /* An empty schema; just get out. */ 10180 if (node->children == NULL) 10181 goto exit; 10182 oldErrs = pctxt->nberrors; 10183 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10184 if (ret != 0) 10185 goto exit; 10186 /* 10187 * TODO: Not nice, but I'm not 100% sure we will get always an error 10188 * as a result of the obove functions; so better rely on pctxt->err 10189 * as well. 10190 */ 10191 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10192 ret = pctxt->err; 10193 goto exit; 10194 } 10195 10196 exit: 10197 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10198 /* Restore schema values. */ 10199 schema->doc = oldDoc; 10200 schema->flags = oldFlags; 10201 return(ret); 10202 } 10203 10204 static int 10205 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10206 xmlSchemaPtr schema, 10207 xmlSchemaBucketPtr bucket) 10208 { 10209 xmlSchemaParserCtxtPtr newpctxt; 10210 int res = 0; 10211 10212 if (bucket == NULL) 10213 return(0); 10214 if (bucket->parsed) { 10215 PERROR_INT("xmlSchemaParseNewDoc", 10216 "reparsing a schema doc"); 10217 return(-1); 10218 } 10219 if (bucket->doc == NULL) { 10220 PERROR_INT("xmlSchemaParseNewDoc", 10221 "parsing a schema doc, but there's no doc"); 10222 return(-1); 10223 } 10224 if (pctxt->constructor == NULL) { 10225 PERROR_INT("xmlSchemaParseNewDoc", 10226 "no constructor"); 10227 return(-1); 10228 } 10229 /* Create and init the temporary parser context. */ 10230 newpctxt = xmlSchemaNewParserCtxtUseDict( 10231 (const char *) bucket->schemaLocation, pctxt->dict); 10232 if (newpctxt == NULL) 10233 return(-1); 10234 newpctxt->constructor = pctxt->constructor; 10235 /* 10236 * TODO: Can we avoid that the parser knows about the main schema? 10237 * It would be better if he knows about the current schema bucket 10238 * only. 10239 */ 10240 newpctxt->schema = schema; 10241 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10242 pctxt->errCtxt); 10243 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10244 pctxt->errCtxt); 10245 newpctxt->counter = pctxt->counter; 10246 10247 10248 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10249 10250 /* Channel back errors and cleanup the temporary parser context. */ 10251 if (res != 0) 10252 pctxt->err = res; 10253 pctxt->nberrors += newpctxt->nberrors; 10254 pctxt->counter = newpctxt->counter; 10255 newpctxt->constructor = NULL; 10256 /* Free the parser context. */ 10257 xmlSchemaFreeParserCtxt(newpctxt); 10258 return(res); 10259 } 10260 10261 static void 10262 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10263 xmlSchemaSchemaRelationPtr rel) 10264 { 10265 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10266 10267 if (cur == NULL) { 10268 bucket->relations = rel; 10269 return; 10270 } 10271 while (cur->next != NULL) 10272 cur = cur->next; 10273 cur->next = rel; 10274 } 10275 10276 10277 static const xmlChar * 10278 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10279 xmlNodePtr ctxtNode) 10280 { 10281 /* 10282 * Build an absolue location URI. 10283 */ 10284 if (location != NULL) { 10285 if (ctxtNode == NULL) 10286 return(location); 10287 else { 10288 xmlChar *base, *URI; 10289 const xmlChar *ret = NULL; 10290 10291 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10292 if (base == NULL) { 10293 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10294 } else { 10295 URI = xmlBuildURI(location, base); 10296 xmlFree(base); 10297 } 10298 if (URI != NULL) { 10299 ret = xmlDictLookup(dict, URI, -1); 10300 xmlFree(URI); 10301 return(ret); 10302 } 10303 } 10304 } 10305 return(NULL); 10306 } 10307 10308 10309 10310 /** 10311 * xmlSchemaAddSchemaDoc: 10312 * @pctxt: a schema validation context 10313 * @schema: the schema being built 10314 * @node: a subtree containing XML Schema informations 10315 * 10316 * Parse an included (and to-be-redefined) XML schema document. 10317 * 10318 * Returns 0 on success, a positive error code on errors and 10319 * -1 in case of an internal or API error. 10320 */ 10321 10322 static int 10323 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10324 int type, /* import or include or redefine */ 10325 const xmlChar *schemaLocation, 10326 xmlDocPtr schemaDoc, 10327 const char *schemaBuffer, 10328 int schemaBufferLen, 10329 xmlNodePtr invokingNode, 10330 const xmlChar *sourceTargetNamespace, 10331 const xmlChar *importNamespace, 10332 xmlSchemaBucketPtr *bucket) 10333 { 10334 const xmlChar *targetNamespace = NULL; 10335 xmlSchemaSchemaRelationPtr relation = NULL; 10336 xmlDocPtr doc = NULL; 10337 int res = 0, err = 0, located = 0, preserveDoc = 0; 10338 xmlSchemaBucketPtr bkt = NULL; 10339 10340 if (bucket != NULL) 10341 *bucket = NULL; 10342 10343 switch (type) { 10344 case XML_SCHEMA_SCHEMA_IMPORT: 10345 case XML_SCHEMA_SCHEMA_MAIN: 10346 err = XML_SCHEMAP_SRC_IMPORT; 10347 break; 10348 case XML_SCHEMA_SCHEMA_INCLUDE: 10349 err = XML_SCHEMAP_SRC_INCLUDE; 10350 break; 10351 case XML_SCHEMA_SCHEMA_REDEFINE: 10352 err = XML_SCHEMAP_SRC_REDEFINE; 10353 break; 10354 } 10355 10356 10357 /* Special handling for the main schema: 10358 * skip the location and relation logic and just parse the doc. 10359 * We need just a bucket to be returned in this case. 10360 */ 10361 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10362 goto doc_load; 10363 10364 /* Note that we expect the location to be an absulute URI. */ 10365 if (schemaLocation != NULL) { 10366 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10367 if ((bkt != NULL) && 10368 (pctxt->constructor->bucket == bkt)) { 10369 /* Report self-imports/inclusions/redefinitions. */ 10370 10371 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10372 invokingNode, NULL, 10373 "The schema must not import/include/redefine itself", 10374 NULL, NULL); 10375 goto exit; 10376 } 10377 } 10378 /* 10379 * Create a relation for the graph of schemas. 10380 */ 10381 relation = xmlSchemaSchemaRelationCreate(); 10382 if (relation == NULL) 10383 return(-1); 10384 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10385 relation); 10386 relation->type = type; 10387 10388 /* 10389 * Save the namespace import information. 10390 */ 10391 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10392 relation->importNamespace = importNamespace; 10393 if (schemaLocation == NULL) { 10394 /* 10395 * No location; this is just an import of the namespace. 10396 * Note that we don't assign a bucket to the relation 10397 * in this case. 10398 */ 10399 goto exit; 10400 } 10401 targetNamespace = importNamespace; 10402 } 10403 10404 /* Did we already fetch the doc? */ 10405 if (bkt != NULL) { 10406 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10407 /* 10408 * We included/redefined and then try to import a schema, 10409 * but the new location provided for import was different. 10410 */ 10411 if (schemaLocation == NULL) 10412 schemaLocation = BAD_CAST "in_memory_buffer"; 10413 if (!xmlStrEqual(schemaLocation, 10414 bkt->schemaLocation)) { 10415 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10416 invokingNode, NULL, 10417 "The schema document '%s' cannot be imported, since " 10418 "it was already included or redefined", 10419 schemaLocation, NULL); 10420 goto exit; 10421 } 10422 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10423 /* 10424 * We imported and then try to include/redefine a schema, 10425 * but the new location provided for the include/redefine 10426 * was different. 10427 */ 10428 if (schemaLocation == NULL) 10429 schemaLocation = BAD_CAST "in_memory_buffer"; 10430 if (!xmlStrEqual(schemaLocation, 10431 bkt->schemaLocation)) { 10432 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10433 invokingNode, NULL, 10434 "The schema document '%s' cannot be included or " 10435 "redefined, since it was already imported", 10436 schemaLocation, NULL); 10437 goto exit; 10438 } 10439 } 10440 } 10441 10442 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10443 /* 10444 * Given that the schemaLocation [attribute] is only a hint, it is open 10445 * to applications to ignore all but the first <import> for a given 10446 * namespace, regardless of the `actual value` of schemaLocation, but 10447 * such a strategy risks missing useful information when new 10448 * schemaLocations are offered. 10449 * 10450 * We will use the first <import> that comes with a location. 10451 * Further <import>s *with* a location, will result in an error. 10452 * TODO: Better would be to just report a warning here, but 10453 * we'll try it this way until someone complains. 10454 * 10455 * Schema Document Location Strategy: 10456 * 3 Based on the namespace name, identify an existing schema document, 10457 * either as a resource which is an XML document or a <schema> element 10458 * information item, in some local schema repository; 10459 * 5 Attempt to resolve the namespace name to locate such a resource. 10460 * 10461 * NOTE: (3) and (5) are not supported. 10462 */ 10463 if (bkt != NULL) { 10464 relation->bucket = bkt; 10465 goto exit; 10466 } 10467 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10468 importNamespace, 1); 10469 10470 if (bkt != NULL) { 10471 relation->bucket = bkt; 10472 if (bkt->schemaLocation == NULL) { 10473 /* First given location of the schema; load the doc. */ 10474 bkt->schemaLocation = schemaLocation; 10475 } else { 10476 if (!xmlStrEqual(schemaLocation, 10477 bkt->schemaLocation)) { 10478 /* 10479 * Additional location given; just skip it. 10480 * URGENT TODO: We should report a warning here. 10481 * res = XML_SCHEMAP_SRC_IMPORT; 10482 */ 10483 if (schemaLocation == NULL) 10484 schemaLocation = BAD_CAST "in_memory_buffer"; 10485 10486 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10487 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10488 invokingNode, NULL, 10489 "Skipping import of schema located at '%s' for the " 10490 "namespace '%s', since this namespace was already " 10491 "imported with the schema located at '%s'", 10492 schemaLocation, importNamespace, bkt->schemaLocation); 10493 } 10494 goto exit; 10495 } 10496 } 10497 /* 10498 * No bucket + first location: load the doc and create a 10499 * bucket. 10500 */ 10501 } else { 10502 /* <include> and <redefine> */ 10503 if (bkt != NULL) { 10504 10505 if ((bkt->origTargetNamespace == NULL) && 10506 (bkt->targetNamespace != sourceTargetNamespace)) { 10507 xmlSchemaBucketPtr chamel; 10508 10509 /* 10510 * Chameleon include/redefine: skip loading only if it was 10511 * aleady build for the targetNamespace of the including 10512 * schema. 10513 */ 10514 /* 10515 * URGENT TODO: If the schema is a chameleon-include then copy 10516 * the components into the including schema and modify the 10517 * targetNamespace of those components, do nothing otherwise. 10518 * NOTE: This is currently worked-around by compiling the 10519 * chameleon for every destinct including targetNamespace; thus 10520 * not performant at the moment. 10521 * TODO: Check when the namespace in wildcards for chameleons 10522 * needs to be converted: before we built wildcard intersections 10523 * or after. 10524 * Answer: after! 10525 */ 10526 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10527 schemaLocation, sourceTargetNamespace); 10528 if (chamel != NULL) { 10529 /* A fitting chameleon was already parsed; NOP. */ 10530 relation->bucket = chamel; 10531 goto exit; 10532 } 10533 /* 10534 * We need to parse the chameleon again for a different 10535 * targetNamespace. 10536 * CHAMELEON TODO: Optimize this by only parsing the 10537 * chameleon once, and then copying the components to 10538 * the new targetNamespace. 10539 */ 10540 bkt = NULL; 10541 } else { 10542 relation->bucket = bkt; 10543 goto exit; 10544 } 10545 } 10546 } 10547 if ((bkt != NULL) && (bkt->doc != NULL)) { 10548 PERROR_INT("xmlSchemaAddSchemaDoc", 10549 "trying to load a schema doc, but a doc is already " 10550 "assigned to the schema bucket"); 10551 goto exit_failure; 10552 } 10553 10554 doc_load: 10555 /* 10556 * Load the document. 10557 */ 10558 if (schemaDoc != NULL) { 10559 doc = schemaDoc; 10560 /* Don' free this one, since it was provided by the caller. */ 10561 preserveDoc = 1; 10562 /* TODO: Does the context or the doc hold the location? */ 10563 if (schemaDoc->URL != NULL) 10564 schemaLocation = xmlDictLookup(pctxt->dict, 10565 schemaDoc->URL, -1); 10566 else 10567 schemaLocation = BAD_CAST "in_memory_buffer"; 10568 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10569 xmlParserCtxtPtr parserCtxt; 10570 10571 parserCtxt = xmlNewParserCtxt(); 10572 if (parserCtxt == NULL) { 10573 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10574 "allocating a parser context", NULL); 10575 goto exit_failure; 10576 } 10577 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10578 /* 10579 * TODO: Do we have to burden the schema parser dict with all 10580 * the content of the schema doc? 10581 */ 10582 xmlDictFree(parserCtxt->dict); 10583 parserCtxt->dict = pctxt->dict; 10584 xmlDictReference(parserCtxt->dict); 10585 } 10586 if (schemaLocation != NULL) { 10587 /* Parse from file. */ 10588 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10589 NULL, SCHEMAS_PARSE_OPTIONS); 10590 } else if (schemaBuffer != NULL) { 10591 /* Parse from memory buffer. */ 10592 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10593 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10594 schemaLocation = BAD_CAST "in_memory_buffer"; 10595 if (doc != NULL) 10596 doc->URL = xmlStrdup(schemaLocation); 10597 } 10598 /* 10599 * For <import>: 10600 * 2.1 The referent is (a fragment of) a resource which is an 10601 * XML document (see clause 1.1), which in turn corresponds to 10602 * a <schema> element information item in a well-formed information 10603 * set, which in turn corresponds to a valid schema. 10604 * TODO: (2.1) fragments of XML documents are not supported. 10605 * 10606 * 2.2 The referent is a <schema> element information item in 10607 * a well-formed information set, which in turn corresponds 10608 * to a valid schema. 10609 * TODO: (2.2) is not supported. 10610 */ 10611 if (doc == NULL) { 10612 xmlErrorPtr lerr; 10613 lerr = xmlGetLastError(); 10614 /* 10615 * Check if this a parser error, or if the document could 10616 * just not be located. 10617 * TODO: Try to find specific error codes to react only on 10618 * localisation failures. 10619 */ 10620 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10621 /* 10622 * We assume a parser error here. 10623 */ 10624 located = 1; 10625 /* TODO: Error code ?? */ 10626 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10627 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10628 invokingNode, NULL, 10629 "Failed to parse the XML resource '%s'", 10630 schemaLocation, NULL); 10631 } 10632 } 10633 xmlFreeParserCtxt(parserCtxt); 10634 if ((doc == NULL) && located) 10635 goto exit_error; 10636 } else { 10637 xmlSchemaPErr(pctxt, NULL, 10638 XML_SCHEMAP_NOTHING_TO_PARSE, 10639 "No information for parsing was provided with the " 10640 "given schema parser context.\n", 10641 NULL, NULL); 10642 goto exit_failure; 10643 } 10644 /* 10645 * Preprocess the document. 10646 */ 10647 if (doc != NULL) { 10648 xmlNodePtr docElem = NULL; 10649 10650 located = 1; 10651 docElem = xmlDocGetRootElement(doc); 10652 if (docElem == NULL) { 10653 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10654 invokingNode, NULL, 10655 "The document '%s' has no document element", 10656 schemaLocation, NULL); 10657 goto exit_error; 10658 } 10659 /* 10660 * Remove all the blank text nodes. 10661 */ 10662 xmlSchemaCleanupDoc(pctxt, docElem); 10663 /* 10664 * Check the schema's top level element. 10665 */ 10666 if (!IS_SCHEMA(docElem, "schema")) { 10667 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10668 invokingNode, NULL, 10669 "The XML document '%s' is not a schema document", 10670 schemaLocation, NULL); 10671 goto exit_error; 10672 } 10673 /* 10674 * Note that we don't apply a type check for the 10675 * targetNamespace value here. 10676 */ 10677 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10678 "targetNamespace"); 10679 } 10680 10681 /* after_doc_loading: */ 10682 if ((bkt == NULL) && located) { 10683 /* Only create a bucket if the schema was located. */ 10684 bkt = xmlSchemaBucketCreate(pctxt, type, 10685 targetNamespace); 10686 if (bkt == NULL) 10687 goto exit_failure; 10688 } 10689 if (bkt != NULL) { 10690 bkt->schemaLocation = schemaLocation; 10691 bkt->located = located; 10692 if (doc != NULL) { 10693 bkt->doc = doc; 10694 bkt->targetNamespace = targetNamespace; 10695 bkt->origTargetNamespace = targetNamespace; 10696 if (preserveDoc) 10697 bkt->preserveDoc = 1; 10698 } 10699 if (WXS_IS_BUCKET_IMPMAIN(type)) 10700 bkt->imported++; 10701 /* 10702 * Add it to the graph of schemas. 10703 */ 10704 if (relation != NULL) 10705 relation->bucket = bkt; 10706 } 10707 10708 exit: 10709 /* 10710 * Return the bucket explicitely; this is needed for the 10711 * main schema. 10712 */ 10713 if (bucket != NULL) 10714 *bucket = bkt; 10715 return (0); 10716 10717 exit_error: 10718 if ((doc != NULL) && (! preserveDoc)) { 10719 xmlFreeDoc(doc); 10720 if (bkt != NULL) 10721 bkt->doc = NULL; 10722 } 10723 return(pctxt->err); 10724 10725 exit_failure: 10726 if ((doc != NULL) && (! preserveDoc)) { 10727 xmlFreeDoc(doc); 10728 if (bkt != NULL) 10729 bkt->doc = NULL; 10730 } 10731 return (-1); 10732 } 10733 10734 /** 10735 * xmlSchemaParseImport: 10736 * @ctxt: a schema validation context 10737 * @schema: the schema being built 10738 * @node: a subtree containing XML Schema informations 10739 * 10740 * parse a XML schema Import definition 10741 * *WARNING* this interface is highly subject to change 10742 * 10743 * Returns 0 in case of success, a positive error code if 10744 * not valid and -1 in case of an internal error. 10745 */ 10746 static int 10747 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10748 xmlNodePtr node) 10749 { 10750 xmlNodePtr child; 10751 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10752 const xmlChar *thisTargetNamespace; 10753 xmlAttrPtr attr; 10754 int ret = 0; 10755 xmlSchemaBucketPtr bucket = NULL; 10756 10757 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10758 return (-1); 10759 10760 /* 10761 * Check for illegal attributes. 10762 */ 10763 attr = node->properties; 10764 while (attr != NULL) { 10765 if (attr->ns == NULL) { 10766 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10767 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10768 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10769 xmlSchemaPIllegalAttrErr(pctxt, 10770 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10771 } 10772 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10773 xmlSchemaPIllegalAttrErr(pctxt, 10774 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10775 } 10776 attr = attr->next; 10777 } 10778 /* 10779 * Extract and validate attributes. 10780 */ 10781 if (xmlSchemaPValAttr(pctxt, NULL, node, 10782 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10783 &namespaceName) != 0) { 10784 xmlSchemaPSimpleTypeErr(pctxt, 10785 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10786 NULL, node, 10787 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10788 NULL, namespaceName, NULL, NULL, NULL); 10789 return (pctxt->err); 10790 } 10791 10792 if (xmlSchemaPValAttr(pctxt, NULL, node, 10793 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10794 &schemaLocation) != 0) { 10795 xmlSchemaPSimpleTypeErr(pctxt, 10796 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10797 NULL, node, 10798 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10799 NULL, schemaLocation, NULL, NULL, NULL); 10800 return (pctxt->err); 10801 } 10802 /* 10803 * And now for the children... 10804 */ 10805 child = node->children; 10806 if (IS_SCHEMA(child, "annotation")) { 10807 /* 10808 * the annotation here is simply discarded ... 10809 * TODO: really? 10810 */ 10811 child = child->next; 10812 } 10813 if (child != NULL) { 10814 xmlSchemaPContentErr(pctxt, 10815 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10816 NULL, node, child, NULL, 10817 "(annotation?)"); 10818 } 10819 /* 10820 * Apply additional constraints. 10821 * 10822 * Note that it is important to use the original @targetNamespace 10823 * (or none at all), to rule out imports of schemas _with_ a 10824 * @targetNamespace if the importing schema is a chameleon schema 10825 * (with no @targetNamespace). 10826 */ 10827 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10828 if (namespaceName != NULL) { 10829 /* 10830 * 1.1 If the namespace [attribute] is present, then its `actual value` 10831 * must not match the `actual value` of the enclosing <schema>'s 10832 * targetNamespace [attribute]. 10833 */ 10834 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10835 xmlSchemaPCustomErr(pctxt, 10836 XML_SCHEMAP_SRC_IMPORT_1_1, 10837 NULL, node, 10838 "The value of the attribute 'namespace' must not match " 10839 "the target namespace '%s' of the importing schema", 10840 thisTargetNamespace); 10841 return (pctxt->err); 10842 } 10843 } else { 10844 /* 10845 * 1.2 If the namespace [attribute] is not present, then the enclosing 10846 * <schema> must have a targetNamespace [attribute]. 10847 */ 10848 if (thisTargetNamespace == NULL) { 10849 xmlSchemaPCustomErr(pctxt, 10850 XML_SCHEMAP_SRC_IMPORT_1_2, 10851 NULL, node, 10852 "The attribute 'namespace' must be existent if " 10853 "the importing schema has no target namespace", 10854 NULL); 10855 return (pctxt->err); 10856 } 10857 } 10858 /* 10859 * Locate and acquire the schema document. 10860 */ 10861 if (schemaLocation != NULL) 10862 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10863 schemaLocation, node); 10864 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10865 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10866 namespaceName, &bucket); 10867 10868 if (ret != 0) 10869 return(ret); 10870 10871 /* 10872 * For <import>: "It is *not* an error for the application 10873 * schema reference strategy to fail." 10874 * So just don't parse if no schema document was found. 10875 * Note that we will get no bucket if the schema could not be 10876 * located or if there was no schemaLocation. 10877 */ 10878 if ((bucket == NULL) && (schemaLocation != NULL)) { 10879 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10880 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10881 node, NULL, 10882 "Failed to locate a schema at location '%s'. " 10883 "Skipping the import", schemaLocation, NULL, NULL); 10884 } 10885 10886 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10887 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10888 } 10889 10890 return (ret); 10891 } 10892 10893 static int 10894 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10895 xmlSchemaPtr schema, 10896 xmlNodePtr node, 10897 xmlChar **schemaLocation, 10898 int type) 10899 { 10900 xmlAttrPtr attr; 10901 10902 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10903 (schemaLocation == NULL)) 10904 return (-1); 10905 10906 *schemaLocation = NULL; 10907 /* 10908 * Check for illegal attributes. 10909 * Applies for both <include> and <redefine>. 10910 */ 10911 attr = node->properties; 10912 while (attr != NULL) { 10913 if (attr->ns == NULL) { 10914 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10915 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10916 xmlSchemaPIllegalAttrErr(pctxt, 10917 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10918 } 10919 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10920 xmlSchemaPIllegalAttrErr(pctxt, 10921 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10922 } 10923 attr = attr->next; 10924 } 10925 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10926 /* 10927 * Preliminary step, extract the URI-Reference and make an URI 10928 * from the base. 10929 */ 10930 /* 10931 * Attribute "schemaLocation" is mandatory. 10932 */ 10933 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10934 if (attr != NULL) { 10935 xmlChar *base = NULL; 10936 xmlChar *uri = NULL; 10937 10938 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10939 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10940 (const xmlChar **) schemaLocation) != 0) 10941 goto exit_error; 10942 base = xmlNodeGetBase(node->doc, node); 10943 if (base == NULL) { 10944 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10945 } else { 10946 uri = xmlBuildURI(*schemaLocation, base); 10947 xmlFree(base); 10948 } 10949 if (uri == NULL) { 10950 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10951 "could not build an URI from the schemaLocation") 10952 goto exit_failure; 10953 } 10954 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10955 xmlFree(uri); 10956 } else { 10957 xmlSchemaPMissingAttrErr(pctxt, 10958 XML_SCHEMAP_S4S_ATTR_MISSING, 10959 NULL, node, "schemaLocation", NULL); 10960 goto exit_error; 10961 } 10962 /* 10963 * Report self-inclusion and self-redefinition. 10964 */ 10965 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10966 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10967 xmlSchemaPCustomErr(pctxt, 10968 XML_SCHEMAP_SRC_REDEFINE, 10969 NULL, node, 10970 "The schema document '%s' cannot redefine itself.", 10971 *schemaLocation); 10972 } else { 10973 xmlSchemaPCustomErr(pctxt, 10974 XML_SCHEMAP_SRC_INCLUDE, 10975 NULL, node, 10976 "The schema document '%s' cannot include itself.", 10977 *schemaLocation); 10978 } 10979 goto exit_error; 10980 } 10981 10982 return(0); 10983 exit_error: 10984 return(pctxt->err); 10985 exit_failure: 10986 return(-1); 10987 } 10988 10989 static int 10990 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10991 xmlSchemaPtr schema, 10992 xmlNodePtr node, 10993 int type) 10994 { 10995 xmlNodePtr child = NULL; 10996 const xmlChar *schemaLocation = NULL; 10997 int res = 0; /* hasRedefinitions = 0 */ 10998 int isChameleon = 0, wasChameleon = 0; 10999 xmlSchemaBucketPtr bucket = NULL; 11000 11001 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 11002 return (-1); 11003 11004 /* 11005 * Parse attributes. Note that the returned schemaLocation will 11006 * be already converted to an absolute URI. 11007 */ 11008 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 11009 node, (xmlChar **) (&schemaLocation), type); 11010 if (res != 0) 11011 return(res); 11012 /* 11013 * Load and add the schema document. 11014 */ 11015 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 11016 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 11017 if (res != 0) 11018 return(res); 11019 /* 11020 * If we get no schema bucket back, then this means that the schema 11021 * document could not be located or was broken XML or was not 11022 * a schema document. 11023 */ 11024 if ((bucket == NULL) || (bucket->doc == NULL)) { 11025 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 11026 /* 11027 * WARNING for <include>: 11028 * We will raise an error if the schema cannot be located 11029 * for inclusions, since the that was the feedback from the 11030 * schema people. I.e. the following spec piece will *not* be 11031 * satisfied: 11032 * SPEC src-include: "It is not an error for the `actual value` of the 11033 * schemaLocation [attribute] to fail to resolve it all, in which 11034 * case no corresponding inclusion is performed. 11035 * So do we need a warning report here?" 11036 */ 11037 res = XML_SCHEMAP_SRC_INCLUDE; 11038 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11039 node, NULL, 11040 "Failed to load the document '%s' for inclusion", 11041 schemaLocation, NULL); 11042 } else { 11043 /* 11044 * NOTE: This was changed to raise an error even if no redefinitions 11045 * are specified. 11046 * 11047 * SPEC src-redefine (1) 11048 * "If there are any element information items among the [children] 11049 * other than <annotation> then the `actual value` of the 11050 * schemaLocation [attribute] must successfully resolve." 11051 * TODO: Ask the WG if a the location has always to resolve 11052 * here as well! 11053 */ 11054 res = XML_SCHEMAP_SRC_REDEFINE; 11055 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11056 node, NULL, 11057 "Failed to load the document '%s' for redefinition", 11058 schemaLocation, NULL); 11059 } 11060 } else { 11061 /* 11062 * Check targetNamespace sanity before parsing the new schema. 11063 * TODO: Note that we won't check further content if the 11064 * targetNamespace was bad. 11065 */ 11066 if (bucket->origTargetNamespace != NULL) { 11067 /* 11068 * SPEC src-include (2.1) 11069 * "SII has a targetNamespace [attribute], and its `actual 11070 * value` is identical to the `actual value` of the targetNamespace 11071 * [attribute] of SII' (which must have such an [attribute])." 11072 */ 11073 if (pctxt->targetNamespace == NULL) { 11074 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11075 XML_SCHEMAP_SRC_INCLUDE, 11076 node, NULL, 11077 "The target namespace of the included/redefined schema " 11078 "'%s' has to be absent, since the including/redefining " 11079 "schema has no target namespace", 11080 schemaLocation, NULL); 11081 goto exit_error; 11082 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11083 pctxt->targetNamespace)) { 11084 /* TODO: Change error function. */ 11085 xmlSchemaPCustomErrExt(pctxt, 11086 XML_SCHEMAP_SRC_INCLUDE, 11087 NULL, node, 11088 "The target namespace '%s' of the included/redefined " 11089 "schema '%s' differs from '%s' of the " 11090 "including/redefining schema", 11091 bucket->origTargetNamespace, schemaLocation, 11092 pctxt->targetNamespace); 11093 goto exit_error; 11094 } 11095 } else if (pctxt->targetNamespace != NULL) { 11096 /* 11097 * Chameleons: the original target namespace will 11098 * differ from the resulting namespace. 11099 */ 11100 isChameleon = 1; 11101 if (bucket->parsed && 11102 bucket->origTargetNamespace != NULL) { 11103 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11104 XML_SCHEMAP_SRC_INCLUDE, 11105 node, NULL, 11106 "The target namespace of the included/redefined schema " 11107 "'%s' has to be absent or the same as the " 11108 "including/redefining schema's target namespace", 11109 schemaLocation, NULL); 11110 goto exit_error; 11111 } 11112 bucket->targetNamespace = pctxt->targetNamespace; 11113 } 11114 } 11115 /* 11116 * Parse the schema. 11117 */ 11118 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11119 if (isChameleon) { 11120 /* TODO: Get rid of this flag on the schema itself. */ 11121 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11122 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11123 } else 11124 wasChameleon = 1; 11125 } 11126 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11127 /* Restore chameleon flag. */ 11128 if (isChameleon && (!wasChameleon)) 11129 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11130 } 11131 /* 11132 * And now for the children... 11133 */ 11134 child = node->children; 11135 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11136 /* 11137 * Parse (simpleType | complexType | group | attributeGroup))* 11138 */ 11139 pctxt->redefined = bucket; 11140 /* 11141 * How to proceed if the redefined schema was not located? 11142 */ 11143 pctxt->isRedefine = 1; 11144 while (IS_SCHEMA(child, "annotation") || 11145 IS_SCHEMA(child, "simpleType") || 11146 IS_SCHEMA(child, "complexType") || 11147 IS_SCHEMA(child, "group") || 11148 IS_SCHEMA(child, "attributeGroup")) { 11149 if (IS_SCHEMA(child, "annotation")) { 11150 /* 11151 * TODO: discard or not? 11152 */ 11153 } else if (IS_SCHEMA(child, "simpleType")) { 11154 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11155 } else if (IS_SCHEMA(child, "complexType")) { 11156 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11157 /* hasRedefinitions = 1; */ 11158 } else if (IS_SCHEMA(child, "group")) { 11159 /* hasRedefinitions = 1; */ 11160 xmlSchemaParseModelGroupDefinition(pctxt, 11161 schema, child); 11162 } else if (IS_SCHEMA(child, "attributeGroup")) { 11163 /* hasRedefinitions = 1; */ 11164 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11165 child); 11166 } 11167 child = child->next; 11168 } 11169 pctxt->redefined = NULL; 11170 pctxt->isRedefine = 0; 11171 } else { 11172 if (IS_SCHEMA(child, "annotation")) { 11173 /* 11174 * TODO: discard or not? 11175 */ 11176 child = child->next; 11177 } 11178 } 11179 if (child != NULL) { 11180 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11181 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11182 xmlSchemaPContentErr(pctxt, res, 11183 NULL, node, child, NULL, 11184 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11185 } else { 11186 xmlSchemaPContentErr(pctxt, res, 11187 NULL, node, child, NULL, 11188 "(annotation?)"); 11189 } 11190 } 11191 return(res); 11192 11193 exit_error: 11194 return(pctxt->err); 11195 } 11196 11197 static int 11198 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11199 xmlNodePtr node) 11200 { 11201 int res; 11202 #ifndef ENABLE_REDEFINE 11203 TODO 11204 return(0); 11205 #endif 11206 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11207 XML_SCHEMA_SCHEMA_REDEFINE); 11208 if (res != 0) 11209 return(res); 11210 return(0); 11211 } 11212 11213 static int 11214 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11215 xmlNodePtr node) 11216 { 11217 int res; 11218 11219 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11220 XML_SCHEMA_SCHEMA_INCLUDE); 11221 if (res != 0) 11222 return(res); 11223 return(0); 11224 } 11225 11226 /** 11227 * xmlSchemaParseModelGroup: 11228 * @ctxt: a schema validation context 11229 * @schema: the schema being built 11230 * @node: a subtree containing XML Schema informations 11231 * @type: the "compositor" type 11232 * @particleNeeded: if a a model group with a particle 11233 * 11234 * parse a XML schema Sequence definition. 11235 * Applies parts of: 11236 * Schema Representation Constraint: 11237 * Redefinition Constraints and Semantics (src-redefine) 11238 * (6.1), (6.1.1), (6.1.2) 11239 * 11240 * Schema Component Constraint: 11241 * All Group Limited (cos-all-limited) (2) 11242 * TODO: Actually this should go to component-level checks, 11243 * but is done here due to performance. Move it to an other layer 11244 * is schema construction via an API is implemented. 11245 * 11246 * *WARNING* this interface is highly subject to change 11247 * 11248 * Returns -1 in case of error, 0 if the declaration is improper and 11249 * 1 in case of success. 11250 */ 11251 static xmlSchemaTreeItemPtr 11252 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11253 xmlNodePtr node, xmlSchemaTypeType type, 11254 int withParticle) 11255 { 11256 xmlSchemaModelGroupPtr item; 11257 xmlSchemaParticlePtr particle = NULL; 11258 xmlNodePtr child = NULL; 11259 xmlAttrPtr attr; 11260 int min = 1, max = 1, isElemRef, hasRefs = 0; 11261 11262 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11263 return (NULL); 11264 /* 11265 * Create a model group with the given compositor. 11266 */ 11267 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11268 if (item == NULL) 11269 return (NULL); 11270 11271 if (withParticle) { 11272 if (type == XML_SCHEMA_TYPE_ALL) { 11273 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11274 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11275 } else { 11276 /* choice + sequence */ 11277 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11278 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11279 "(xs:nonNegativeInteger | unbounded)"); 11280 } 11281 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11282 /* 11283 * Create a particle 11284 */ 11285 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11286 if (particle == NULL) 11287 return (NULL); 11288 particle->children = (xmlSchemaTreeItemPtr) item; 11289 /* 11290 * Check for illegal attributes. 11291 */ 11292 attr = node->properties; 11293 while (attr != NULL) { 11294 if (attr->ns == NULL) { 11295 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11296 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11297 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11298 xmlSchemaPIllegalAttrErr(ctxt, 11299 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11300 } 11301 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11302 xmlSchemaPIllegalAttrErr(ctxt, 11303 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11304 } 11305 attr = attr->next; 11306 } 11307 } else { 11308 /* 11309 * Check for illegal attributes. 11310 */ 11311 attr = node->properties; 11312 while (attr != NULL) { 11313 if (attr->ns == NULL) { 11314 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11315 xmlSchemaPIllegalAttrErr(ctxt, 11316 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11317 } 11318 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11319 xmlSchemaPIllegalAttrErr(ctxt, 11320 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11321 } 11322 attr = attr->next; 11323 } 11324 } 11325 11326 /* 11327 * Extract and validate attributes. 11328 */ 11329 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11330 /* 11331 * And now for the children... 11332 */ 11333 child = node->children; 11334 if (IS_SCHEMA(child, "annotation")) { 11335 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11336 child = child->next; 11337 } 11338 if (type == XML_SCHEMA_TYPE_ALL) { 11339 xmlSchemaParticlePtr part, last = NULL; 11340 11341 while (IS_SCHEMA(child, "element")) { 11342 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11343 schema, child, &isElemRef, 0); 11344 /* 11345 * SPEC cos-all-limited (2) 11346 * "The {max occurs} of all the particles in the {particles} 11347 * of the ('all') group must be 0 or 1. 11348 */ 11349 if (part != NULL) { 11350 if (isElemRef) 11351 hasRefs++; 11352 if (part->minOccurs > 1) { 11353 xmlSchemaPCustomErr(ctxt, 11354 XML_SCHEMAP_COS_ALL_LIMITED, 11355 NULL, child, 11356 "Invalid value for minOccurs (must be 0 or 1)", 11357 NULL); 11358 /* Reset to 1. */ 11359 part->minOccurs = 1; 11360 } 11361 if (part->maxOccurs > 1) { 11362 xmlSchemaPCustomErr(ctxt, 11363 XML_SCHEMAP_COS_ALL_LIMITED, 11364 NULL, child, 11365 "Invalid value for maxOccurs (must be 0 or 1)", 11366 NULL); 11367 /* Reset to 1. */ 11368 part->maxOccurs = 1; 11369 } 11370 if (last == NULL) 11371 item->children = (xmlSchemaTreeItemPtr) part; 11372 else 11373 last->next = (xmlSchemaTreeItemPtr) part; 11374 last = part; 11375 } 11376 child = child->next; 11377 } 11378 if (child != NULL) { 11379 xmlSchemaPContentErr(ctxt, 11380 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11381 NULL, node, child, NULL, 11382 "(annotation?, (annotation?, element*)"); 11383 } 11384 } else { 11385 /* choice + sequence */ 11386 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11387 11388 while ((IS_SCHEMA(child, "element")) || 11389 (IS_SCHEMA(child, "group")) || 11390 (IS_SCHEMA(child, "any")) || 11391 (IS_SCHEMA(child, "choice")) || 11392 (IS_SCHEMA(child, "sequence"))) { 11393 11394 if (IS_SCHEMA(child, "element")) { 11395 part = (xmlSchemaTreeItemPtr) 11396 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11397 if (part && isElemRef) 11398 hasRefs++; 11399 } else if (IS_SCHEMA(child, "group")) { 11400 part = 11401 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11402 if (part != NULL) 11403 hasRefs++; 11404 /* 11405 * Handle redefinitions. 11406 */ 11407 if (ctxt->isRedefine && ctxt->redef && 11408 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11409 part && part->children) 11410 { 11411 if ((xmlSchemaGetQNameRefName(part->children) == 11412 ctxt->redef->refName) && 11413 (xmlSchemaGetQNameRefTargetNs(part->children) == 11414 ctxt->redef->refTargetNs)) 11415 { 11416 /* 11417 * SPEC src-redefine: 11418 * (6.1) "If it has a <group> among its contents at 11419 * some level the `actual value` of whose ref 11420 * [attribute] is the same as the `actual value` of 11421 * its own name attribute plus target namespace, then 11422 * all of the following must be true:" 11423 * (6.1.1) "It must have exactly one such group." 11424 */ 11425 if (ctxt->redefCounter != 0) { 11426 xmlChar *str = NULL; 11427 11428 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11429 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11430 "The redefining model group definition " 11431 "'%s' must not contain more than one " 11432 "reference to the redefined definition", 11433 xmlSchemaFormatQName(&str, 11434 ctxt->redef->refTargetNs, 11435 ctxt->redef->refName), 11436 NULL); 11437 FREE_AND_NULL(str) 11438 part = NULL; 11439 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11440 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11441 { 11442 xmlChar *str = NULL; 11443 /* 11444 * SPEC src-redefine: 11445 * (6.1.2) "The `actual value` of both that 11446 * group's minOccurs and maxOccurs [attribute] 11447 * must be 1 (or `absent`). 11448 */ 11449 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11450 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11451 "The redefining model group definition " 11452 "'%s' must not contain a reference to the " 11453 "redefined definition with a " 11454 "maxOccurs/minOccurs other than 1", 11455 xmlSchemaFormatQName(&str, 11456 ctxt->redef->refTargetNs, 11457 ctxt->redef->refName), 11458 NULL); 11459 FREE_AND_NULL(str) 11460 part = NULL; 11461 } 11462 ctxt->redef->reference = WXS_BASIC_CAST part; 11463 ctxt->redefCounter++; 11464 } 11465 } 11466 } else if (IS_SCHEMA(child, "any")) { 11467 part = (xmlSchemaTreeItemPtr) 11468 xmlSchemaParseAny(ctxt, schema, child); 11469 } else if (IS_SCHEMA(child, "choice")) { 11470 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11471 XML_SCHEMA_TYPE_CHOICE, 1); 11472 } else if (IS_SCHEMA(child, "sequence")) { 11473 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11474 XML_SCHEMA_TYPE_SEQUENCE, 1); 11475 } 11476 if (part != NULL) { 11477 if (last == NULL) 11478 item->children = part; 11479 else 11480 last->next = part; 11481 last = part; 11482 } 11483 child = child->next; 11484 } 11485 if (child != NULL) { 11486 xmlSchemaPContentErr(ctxt, 11487 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11488 NULL, node, child, NULL, 11489 "(annotation?, (element | group | choice | sequence | any)*)"); 11490 } 11491 } 11492 if ((max == 0) && (min == 0)) 11493 return (NULL); 11494 if (hasRefs) { 11495 /* 11496 * We need to resolve references. 11497 */ 11498 WXS_ADD_PENDING(ctxt, item); 11499 } 11500 if (withParticle) 11501 return ((xmlSchemaTreeItemPtr) particle); 11502 else 11503 return ((xmlSchemaTreeItemPtr) item); 11504 } 11505 11506 /** 11507 * xmlSchemaParseRestriction: 11508 * @ctxt: a schema validation context 11509 * @schema: the schema being built 11510 * @node: a subtree containing XML Schema informations 11511 * 11512 * parse a XML schema Restriction definition 11513 * *WARNING* this interface is highly subject to change 11514 * 11515 * Returns the type definition or NULL in case of error 11516 */ 11517 static xmlSchemaTypePtr 11518 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11519 xmlNodePtr node, xmlSchemaTypeType parentType) 11520 { 11521 xmlSchemaTypePtr type; 11522 xmlNodePtr child = NULL; 11523 xmlAttrPtr attr; 11524 11525 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11526 return (NULL); 11527 /* Not a component, don't create it. */ 11528 type = ctxt->ctxtType; 11529 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11530 11531 /* 11532 * Check for illegal attributes. 11533 */ 11534 attr = node->properties; 11535 while (attr != NULL) { 11536 if (attr->ns == NULL) { 11537 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11538 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11539 xmlSchemaPIllegalAttrErr(ctxt, 11540 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11541 } 11542 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11543 xmlSchemaPIllegalAttrErr(ctxt, 11544 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11545 } 11546 attr = attr->next; 11547 } 11548 /* 11549 * Extract and validate attributes. 11550 */ 11551 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11552 /* 11553 * Attribute 11554 */ 11555 /* 11556 * Extract the base type. The "base" attribute is mandatory if inside 11557 * a complex type or if redefining. 11558 * 11559 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11560 * among its [children]), the simple type definition which is 11561 * the {content type} of the type definition `resolved` to by 11562 * the `actual value` of the base [attribute]" 11563 */ 11564 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11565 &(type->baseNs), &(type->base)) == 0) 11566 { 11567 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11568 xmlSchemaPMissingAttrErr(ctxt, 11569 XML_SCHEMAP_S4S_ATTR_MISSING, 11570 NULL, node, "base", NULL); 11571 } else if ((ctxt->isRedefine) && 11572 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11573 { 11574 if (type->base == NULL) { 11575 xmlSchemaPMissingAttrErr(ctxt, 11576 XML_SCHEMAP_S4S_ATTR_MISSING, 11577 NULL, node, "base", NULL); 11578 } else if ((! xmlStrEqual(type->base, type->name)) || 11579 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11580 { 11581 xmlChar *str1 = NULL, *str2 = NULL; 11582 /* 11583 * REDEFINE: SPEC src-redefine (5) 11584 * "Within the [children], each <simpleType> must have a 11585 * <restriction> among its [children] ... the `actual value` of 11586 * whose base [attribute] must be the same as the `actual value` 11587 * of its own name attribute plus target namespace;" 11588 */ 11589 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11590 NULL, node, "This is a redefinition, but the QName " 11591 "value '%s' of the 'base' attribute does not match the " 11592 "type's designation '%s'", 11593 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11594 xmlSchemaFormatQName(&str2, type->targetNamespace, 11595 type->name), NULL); 11596 FREE_AND_NULL(str1); 11597 FREE_AND_NULL(str2); 11598 /* Avoid confusion and erase the values. */ 11599 type->base = NULL; 11600 type->baseNs = NULL; 11601 } 11602 } 11603 } 11604 /* 11605 * And now for the children... 11606 */ 11607 child = node->children; 11608 if (IS_SCHEMA(child, "annotation")) { 11609 /* 11610 * Add the annotation to the simple type ancestor. 11611 */ 11612 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11613 xmlSchemaParseAnnotation(ctxt, child, 1)); 11614 child = child->next; 11615 } 11616 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11617 /* 11618 * Corresponds to <simpleType><restriction><simpleType>. 11619 */ 11620 if (IS_SCHEMA(child, "simpleType")) { 11621 if (type->base != NULL) { 11622 /* 11623 * src-restriction-base-or-simpleType 11624 * Either the base [attribute] or the simpleType [child] of the 11625 * <restriction> element must be present, but not both. 11626 */ 11627 xmlSchemaPContentErr(ctxt, 11628 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11629 NULL, node, child, 11630 "The attribute 'base' and the <simpleType> child are " 11631 "mutually exclusive", NULL); 11632 } else { 11633 type->baseType = (xmlSchemaTypePtr) 11634 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11635 } 11636 child = child->next; 11637 } else if (type->base == NULL) { 11638 xmlSchemaPContentErr(ctxt, 11639 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11640 NULL, node, child, 11641 "Either the attribute 'base' or a <simpleType> child " 11642 "must be present", NULL); 11643 } 11644 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11645 /* 11646 * Corresponds to <complexType><complexContent><restriction>... 11647 * followed by: 11648 * 11649 * Model groups <all>, <choice> and <sequence>. 11650 */ 11651 if (IS_SCHEMA(child, "all")) { 11652 type->subtypes = (xmlSchemaTypePtr) 11653 xmlSchemaParseModelGroup(ctxt, schema, child, 11654 XML_SCHEMA_TYPE_ALL, 1); 11655 child = child->next; 11656 } else if (IS_SCHEMA(child, "choice")) { 11657 type->subtypes = (xmlSchemaTypePtr) 11658 xmlSchemaParseModelGroup(ctxt, 11659 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11660 child = child->next; 11661 } else if (IS_SCHEMA(child, "sequence")) { 11662 type->subtypes = (xmlSchemaTypePtr) 11663 xmlSchemaParseModelGroup(ctxt, schema, child, 11664 XML_SCHEMA_TYPE_SEQUENCE, 1); 11665 child = child->next; 11666 /* 11667 * Model group reference <group>. 11668 */ 11669 } else if (IS_SCHEMA(child, "group")) { 11670 type->subtypes = (xmlSchemaTypePtr) 11671 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11672 /* 11673 * Note that the reference will be resolved in 11674 * xmlSchemaResolveTypeReferences(); 11675 */ 11676 child = child->next; 11677 } 11678 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11679 /* 11680 * Corresponds to <complexType><simpleContent><restriction>... 11681 * 11682 * "1.1 the simple type definition corresponding to the <simpleType> 11683 * among the [children] of <restriction> if there is one;" 11684 */ 11685 if (IS_SCHEMA(child, "simpleType")) { 11686 /* 11687 * We will store the to-be-restricted simple type in 11688 * type->contentTypeDef *temporarily*. 11689 */ 11690 type->contentTypeDef = (xmlSchemaTypePtr) 11691 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11692 if ( type->contentTypeDef == NULL) 11693 return (NULL); 11694 child = child->next; 11695 } 11696 } 11697 11698 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11699 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11700 xmlSchemaFacetPtr facet, lastfacet = NULL; 11701 /* 11702 * Corresponds to <complexType><simpleContent><restriction>... 11703 * <simpleType><restriction>... 11704 */ 11705 11706 /* 11707 * Add the facets to the simple type ancestor. 11708 */ 11709 /* 11710 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11711 * Simple Type Definition Schema Representation Constraint: 11712 * *Single Facet Value* 11713 */ 11714 while ((IS_SCHEMA(child, "minInclusive")) || 11715 (IS_SCHEMA(child, "minExclusive")) || 11716 (IS_SCHEMA(child, "maxInclusive")) || 11717 (IS_SCHEMA(child, "maxExclusive")) || 11718 (IS_SCHEMA(child, "totalDigits")) || 11719 (IS_SCHEMA(child, "fractionDigits")) || 11720 (IS_SCHEMA(child, "pattern")) || 11721 (IS_SCHEMA(child, "enumeration")) || 11722 (IS_SCHEMA(child, "whiteSpace")) || 11723 (IS_SCHEMA(child, "length")) || 11724 (IS_SCHEMA(child, "maxLength")) || 11725 (IS_SCHEMA(child, "minLength"))) { 11726 facet = xmlSchemaParseFacet(ctxt, schema, child); 11727 if (facet != NULL) { 11728 if (lastfacet == NULL) 11729 type->facets = facet; 11730 else 11731 lastfacet->next = facet; 11732 lastfacet = facet; 11733 lastfacet->next = NULL; 11734 } 11735 child = child->next; 11736 } 11737 /* 11738 * Create links for derivation and validation. 11739 */ 11740 if (type->facets != NULL) { 11741 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11742 11743 facet = type->facets; 11744 do { 11745 facetLink = (xmlSchemaFacetLinkPtr) 11746 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11747 if (facetLink == NULL) { 11748 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11749 xmlFree(facetLink); 11750 return (NULL); 11751 } 11752 facetLink->facet = facet; 11753 facetLink->next = NULL; 11754 if (lastFacetLink == NULL) 11755 type->facetSet = facetLink; 11756 else 11757 lastFacetLink->next = facetLink; 11758 lastFacetLink = facetLink; 11759 facet = facet->next; 11760 } while (facet != NULL); 11761 } 11762 } 11763 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11764 /* 11765 * Attribute uses/declarations. 11766 */ 11767 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11768 (xmlSchemaItemListPtr *) &(type->attrUses), 11769 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11770 return(NULL); 11771 /* 11772 * Attribute wildcard. 11773 */ 11774 if (IS_SCHEMA(child, "anyAttribute")) { 11775 type->attributeWildcard = 11776 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11777 child = child->next; 11778 } 11779 } 11780 if (child != NULL) { 11781 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11782 xmlSchemaPContentErr(ctxt, 11783 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11784 NULL, node, child, NULL, 11785 "annotation?, (group | all | choice | sequence)?, " 11786 "((attribute | attributeGroup)*, anyAttribute?))"); 11787 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11788 xmlSchemaPContentErr(ctxt, 11789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11790 NULL, node, child, NULL, 11791 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11792 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11793 "length | minLength | maxLength | enumeration | whiteSpace | " 11794 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11795 } else { 11796 /* Simple type */ 11797 xmlSchemaPContentErr(ctxt, 11798 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11799 NULL, node, child, NULL, 11800 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11801 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11802 "length | minLength | maxLength | enumeration | whiteSpace | " 11803 "pattern)*))"); 11804 } 11805 } 11806 return (NULL); 11807 } 11808 11809 /** 11810 * xmlSchemaParseExtension: 11811 * @ctxt: a schema validation context 11812 * @schema: the schema being built 11813 * @node: a subtree containing XML Schema informations 11814 * 11815 * Parses an <extension>, which is found inside a 11816 * <simpleContent> or <complexContent>. 11817 * *WARNING* this interface is highly subject to change. 11818 * 11819 * TODO: Returns the type definition or NULL in case of error 11820 */ 11821 static xmlSchemaTypePtr 11822 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11823 xmlNodePtr node, xmlSchemaTypeType parentType) 11824 { 11825 xmlSchemaTypePtr type; 11826 xmlNodePtr child = NULL; 11827 xmlAttrPtr attr; 11828 11829 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11830 return (NULL); 11831 /* Not a component, don't create it. */ 11832 type = ctxt->ctxtType; 11833 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11834 11835 /* 11836 * Check for illegal attributes. 11837 */ 11838 attr = node->properties; 11839 while (attr != NULL) { 11840 if (attr->ns == NULL) { 11841 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11842 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11843 xmlSchemaPIllegalAttrErr(ctxt, 11844 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11845 } 11846 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11847 xmlSchemaPIllegalAttrErr(ctxt, 11848 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11849 } 11850 attr = attr->next; 11851 } 11852 11853 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11854 11855 /* 11856 * Attribute "base" - mandatory. 11857 */ 11858 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11859 "base", &(type->baseNs), &(type->base)) == 0) && 11860 (type->base == NULL)) { 11861 xmlSchemaPMissingAttrErr(ctxt, 11862 XML_SCHEMAP_S4S_ATTR_MISSING, 11863 NULL, node, "base", NULL); 11864 } 11865 /* 11866 * And now for the children... 11867 */ 11868 child = node->children; 11869 if (IS_SCHEMA(child, "annotation")) { 11870 /* 11871 * Add the annotation to the type ancestor. 11872 */ 11873 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11874 xmlSchemaParseAnnotation(ctxt, child, 1)); 11875 child = child->next; 11876 } 11877 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11878 /* 11879 * Corresponds to <complexType><complexContent><extension>... and: 11880 * 11881 * Model groups <all>, <choice>, <sequence> and <group>. 11882 */ 11883 if (IS_SCHEMA(child, "all")) { 11884 type->subtypes = (xmlSchemaTypePtr) 11885 xmlSchemaParseModelGroup(ctxt, schema, 11886 child, XML_SCHEMA_TYPE_ALL, 1); 11887 child = child->next; 11888 } else if (IS_SCHEMA(child, "choice")) { 11889 type->subtypes = (xmlSchemaTypePtr) 11890 xmlSchemaParseModelGroup(ctxt, schema, 11891 child, XML_SCHEMA_TYPE_CHOICE, 1); 11892 child = child->next; 11893 } else if (IS_SCHEMA(child, "sequence")) { 11894 type->subtypes = (xmlSchemaTypePtr) 11895 xmlSchemaParseModelGroup(ctxt, schema, 11896 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11897 child = child->next; 11898 } else if (IS_SCHEMA(child, "group")) { 11899 type->subtypes = (xmlSchemaTypePtr) 11900 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11901 /* 11902 * Note that the reference will be resolved in 11903 * xmlSchemaResolveTypeReferences(); 11904 */ 11905 child = child->next; 11906 } 11907 } 11908 if (child != NULL) { 11909 /* 11910 * Attribute uses/declarations. 11911 */ 11912 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11913 (xmlSchemaItemListPtr *) &(type->attrUses), 11914 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11915 return(NULL); 11916 /* 11917 * Attribute wildcard. 11918 */ 11919 if (IS_SCHEMA(child, "anyAttribute")) { 11920 ctxt->ctxtType->attributeWildcard = 11921 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11922 child = child->next; 11923 } 11924 } 11925 if (child != NULL) { 11926 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11927 /* Complex content extension. */ 11928 xmlSchemaPContentErr(ctxt, 11929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11930 NULL, node, child, NULL, 11931 "(annotation?, ((group | all | choice | sequence)?, " 11932 "((attribute | attributeGroup)*, anyAttribute?)))"); 11933 } else { 11934 /* Simple content extension. */ 11935 xmlSchemaPContentErr(ctxt, 11936 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11937 NULL, node, child, NULL, 11938 "(annotation?, ((attribute | attributeGroup)*, " 11939 "anyAttribute?))"); 11940 } 11941 } 11942 return (NULL); 11943 } 11944 11945 /** 11946 * xmlSchemaParseSimpleContent: 11947 * @ctxt: a schema validation context 11948 * @schema: the schema being built 11949 * @node: a subtree containing XML Schema informations 11950 * 11951 * parse a XML schema SimpleContent definition 11952 * *WARNING* this interface is highly subject to change 11953 * 11954 * Returns the type definition or NULL in case of error 11955 */ 11956 static int 11957 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11958 xmlSchemaPtr schema, xmlNodePtr node, 11959 int *hasRestrictionOrExtension) 11960 { 11961 xmlSchemaTypePtr type; 11962 xmlNodePtr child = NULL; 11963 xmlAttrPtr attr; 11964 11965 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11966 (hasRestrictionOrExtension == NULL)) 11967 return (-1); 11968 *hasRestrictionOrExtension = 0; 11969 /* Not a component, don't create it. */ 11970 type = ctxt->ctxtType; 11971 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11972 /* 11973 * Check for illegal attributes. 11974 */ 11975 attr = node->properties; 11976 while (attr != NULL) { 11977 if (attr->ns == NULL) { 11978 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11979 xmlSchemaPIllegalAttrErr(ctxt, 11980 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11981 } 11982 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11983 xmlSchemaPIllegalAttrErr(ctxt, 11984 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11985 } 11986 attr = attr->next; 11987 } 11988 11989 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11990 11991 /* 11992 * And now for the children... 11993 */ 11994 child = node->children; 11995 if (IS_SCHEMA(child, "annotation")) { 11996 /* 11997 * Add the annotation to the complex type ancestor. 11998 */ 11999 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12000 xmlSchemaParseAnnotation(ctxt, child, 1)); 12001 child = child->next; 12002 } 12003 if (child == NULL) { 12004 xmlSchemaPContentErr(ctxt, 12005 XML_SCHEMAP_S4S_ELEM_MISSING, 12006 NULL, node, NULL, NULL, 12007 "(annotation?, (restriction | extension))"); 12008 } 12009 if (child == NULL) { 12010 xmlSchemaPContentErr(ctxt, 12011 XML_SCHEMAP_S4S_ELEM_MISSING, 12012 NULL, node, NULL, NULL, 12013 "(annotation?, (restriction | extension))"); 12014 } 12015 if (IS_SCHEMA(child, "restriction")) { 12016 xmlSchemaParseRestriction(ctxt, schema, child, 12017 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12018 (*hasRestrictionOrExtension) = 1; 12019 child = child->next; 12020 } else if (IS_SCHEMA(child, "extension")) { 12021 xmlSchemaParseExtension(ctxt, schema, child, 12022 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12023 (*hasRestrictionOrExtension) = 1; 12024 child = child->next; 12025 } 12026 if (child != NULL) { 12027 xmlSchemaPContentErr(ctxt, 12028 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12029 NULL, node, child, NULL, 12030 "(annotation?, (restriction | extension))"); 12031 } 12032 return (0); 12033 } 12034 12035 /** 12036 * xmlSchemaParseComplexContent: 12037 * @ctxt: a schema validation context 12038 * @schema: the schema being built 12039 * @node: a subtree containing XML Schema informations 12040 * 12041 * parse a XML schema ComplexContent definition 12042 * *WARNING* this interface is highly subject to change 12043 * 12044 * Returns the type definition or NULL in case of error 12045 */ 12046 static int 12047 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12048 xmlSchemaPtr schema, xmlNodePtr node, 12049 int *hasRestrictionOrExtension) 12050 { 12051 xmlSchemaTypePtr type; 12052 xmlNodePtr child = NULL; 12053 xmlAttrPtr attr; 12054 12055 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12056 (hasRestrictionOrExtension == NULL)) 12057 return (-1); 12058 *hasRestrictionOrExtension = 0; 12059 /* Not a component, don't create it. */ 12060 type = ctxt->ctxtType; 12061 /* 12062 * Check for illegal attributes. 12063 */ 12064 attr = node->properties; 12065 while (attr != NULL) { 12066 if (attr->ns == NULL) { 12067 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12068 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12069 { 12070 xmlSchemaPIllegalAttrErr(ctxt, 12071 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12072 } 12073 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12074 xmlSchemaPIllegalAttrErr(ctxt, 12075 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12076 } 12077 attr = attr->next; 12078 } 12079 12080 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12081 12082 /* 12083 * Set the 'mixed' on the complex type ancestor. 12084 */ 12085 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12086 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12087 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12088 } 12089 child = node->children; 12090 if (IS_SCHEMA(child, "annotation")) { 12091 /* 12092 * Add the annotation to the complex type ancestor. 12093 */ 12094 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12095 xmlSchemaParseAnnotation(ctxt, child, 1)); 12096 child = child->next; 12097 } 12098 if (child == NULL) { 12099 xmlSchemaPContentErr(ctxt, 12100 XML_SCHEMAP_S4S_ELEM_MISSING, 12101 NULL, node, NULL, 12102 NULL, "(annotation?, (restriction | extension))"); 12103 } 12104 if (child == NULL) { 12105 xmlSchemaPContentErr(ctxt, 12106 XML_SCHEMAP_S4S_ELEM_MISSING, 12107 NULL, node, NULL, 12108 NULL, "(annotation?, (restriction | extension))"); 12109 } 12110 if (IS_SCHEMA(child, "restriction")) { 12111 xmlSchemaParseRestriction(ctxt, schema, child, 12112 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12113 (*hasRestrictionOrExtension) = 1; 12114 child = child->next; 12115 } else if (IS_SCHEMA(child, "extension")) { 12116 xmlSchemaParseExtension(ctxt, schema, child, 12117 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12118 (*hasRestrictionOrExtension) = 1; 12119 child = child->next; 12120 } 12121 if (child != NULL) { 12122 xmlSchemaPContentErr(ctxt, 12123 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12124 NULL, node, child, 12125 NULL, "(annotation?, (restriction | extension))"); 12126 } 12127 return (0); 12128 } 12129 12130 /** 12131 * xmlSchemaParseComplexType: 12132 * @ctxt: a schema validation context 12133 * @schema: the schema being built 12134 * @node: a subtree containing XML Schema informations 12135 * 12136 * parse a XML schema Complex Type definition 12137 * *WARNING* this interface is highly subject to change 12138 * 12139 * Returns the type definition or NULL in case of error 12140 */ 12141 static xmlSchemaTypePtr 12142 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12143 xmlNodePtr node, int topLevel) 12144 { 12145 xmlSchemaTypePtr type, ctxtType; 12146 xmlNodePtr child = NULL; 12147 const xmlChar *name = NULL; 12148 xmlAttrPtr attr; 12149 const xmlChar *attrValue; 12150 #ifdef ENABLE_NAMED_LOCALS 12151 char buf[40]; 12152 #endif 12153 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12154 12155 12156 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12157 return (NULL); 12158 12159 ctxtType = ctxt->ctxtType; 12160 12161 if (topLevel) { 12162 attr = xmlSchemaGetPropNode(node, "name"); 12163 if (attr == NULL) { 12164 xmlSchemaPMissingAttrErr(ctxt, 12165 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12166 return (NULL); 12167 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12168 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12169 return (NULL); 12170 } 12171 } 12172 12173 if (topLevel == 0) { 12174 /* 12175 * Parse as local complex type definition. 12176 */ 12177 #ifdef ENABLE_NAMED_LOCALS 12178 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12179 type = xmlSchemaAddType(ctxt, schema, 12180 XML_SCHEMA_TYPE_COMPLEX, 12181 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12182 ctxt->targetNamespace, node, 0); 12183 #else 12184 type = xmlSchemaAddType(ctxt, schema, 12185 XML_SCHEMA_TYPE_COMPLEX, 12186 NULL, ctxt->targetNamespace, node, 0); 12187 #endif 12188 if (type == NULL) 12189 return (NULL); 12190 name = type->name; 12191 type->node = node; 12192 type->type = XML_SCHEMA_TYPE_COMPLEX; 12193 /* 12194 * TODO: We need the target namespace. 12195 */ 12196 } else { 12197 /* 12198 * Parse as global complex type definition. 12199 */ 12200 type = xmlSchemaAddType(ctxt, schema, 12201 XML_SCHEMA_TYPE_COMPLEX, 12202 name, ctxt->targetNamespace, node, 1); 12203 if (type == NULL) 12204 return (NULL); 12205 type->node = node; 12206 type->type = XML_SCHEMA_TYPE_COMPLEX; 12207 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12208 } 12209 type->targetNamespace = ctxt->targetNamespace; 12210 /* 12211 * Handle attributes. 12212 */ 12213 attr = node->properties; 12214 while (attr != NULL) { 12215 if (attr->ns == NULL) { 12216 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12217 /* 12218 * Attribute "id". 12219 */ 12220 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12221 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12222 /* 12223 * Attribute "mixed". 12224 */ 12225 if (xmlSchemaPGetBoolNodeValue(ctxt, 12226 NULL, (xmlNodePtr) attr)) 12227 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12228 } else if (topLevel) { 12229 /* 12230 * Attributes of global complex type definitions. 12231 */ 12232 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12233 /* Pass. */ 12234 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12235 /* 12236 * Attribute "abstract". 12237 */ 12238 if (xmlSchemaPGetBoolNodeValue(ctxt, 12239 NULL, (xmlNodePtr) attr)) 12240 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12241 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12242 /* 12243 * Attribute "final". 12244 */ 12245 attrValue = xmlSchemaGetNodeContent(ctxt, 12246 (xmlNodePtr) attr); 12247 if (xmlSchemaPValAttrBlockFinal(attrValue, 12248 &(type->flags), 12249 -1, 12250 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12251 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12252 -1, -1, -1) != 0) 12253 { 12254 xmlSchemaPSimpleTypeErr(ctxt, 12255 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12256 NULL, (xmlNodePtr) attr, NULL, 12257 "(#all | List of (extension | restriction))", 12258 attrValue, NULL, NULL, NULL); 12259 } else 12260 final = 1; 12261 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12262 /* 12263 * Attribute "block". 12264 */ 12265 attrValue = xmlSchemaGetNodeContent(ctxt, 12266 (xmlNodePtr) attr); 12267 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12268 -1, 12269 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12270 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12271 -1, -1, -1) != 0) { 12272 xmlSchemaPSimpleTypeErr(ctxt, 12273 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12274 NULL, (xmlNodePtr) attr, NULL, 12275 "(#all | List of (extension | restriction)) ", 12276 attrValue, NULL, NULL, NULL); 12277 } else 12278 block = 1; 12279 } else { 12280 xmlSchemaPIllegalAttrErr(ctxt, 12281 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12282 } 12283 } else { 12284 xmlSchemaPIllegalAttrErr(ctxt, 12285 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12286 } 12287 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12288 xmlSchemaPIllegalAttrErr(ctxt, 12289 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12290 } 12291 attr = attr->next; 12292 } 12293 if (! block) { 12294 /* 12295 * Apply default "block" values. 12296 */ 12297 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12298 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12299 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12300 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12301 } 12302 if (! final) { 12303 /* 12304 * Apply default "block" values. 12305 */ 12306 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12307 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12308 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12309 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12310 } 12311 /* 12312 * And now for the children... 12313 */ 12314 child = node->children; 12315 if (IS_SCHEMA(child, "annotation")) { 12316 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12317 child = child->next; 12318 } 12319 ctxt->ctxtType = type; 12320 if (IS_SCHEMA(child, "simpleContent")) { 12321 /* 12322 * <complexType><simpleContent>... 12323 * 3.4.3 : 2.2 12324 * Specifying mixed='true' when the <simpleContent> 12325 * alternative is chosen has no effect 12326 */ 12327 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12328 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12329 xmlSchemaParseSimpleContent(ctxt, schema, child, 12330 &hasRestrictionOrExtension); 12331 child = child->next; 12332 } else if (IS_SCHEMA(child, "complexContent")) { 12333 /* 12334 * <complexType><complexContent>... 12335 */ 12336 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12337 xmlSchemaParseComplexContent(ctxt, schema, child, 12338 &hasRestrictionOrExtension); 12339 child = child->next; 12340 } else { 12341 /* 12342 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12343 * 12344 * SPEC 12345 * "...the third alternative (neither <simpleContent> nor 12346 * <complexContent>) is chosen. This case is understood as shorthand 12347 * for complex content restricting the `ur-type definition`, and the 12348 * details of the mappings should be modified as necessary. 12349 */ 12350 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12351 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12352 /* 12353 * Parse model groups. 12354 */ 12355 if (IS_SCHEMA(child, "all")) { 12356 type->subtypes = (xmlSchemaTypePtr) 12357 xmlSchemaParseModelGroup(ctxt, schema, child, 12358 XML_SCHEMA_TYPE_ALL, 1); 12359 child = child->next; 12360 } else if (IS_SCHEMA(child, "choice")) { 12361 type->subtypes = (xmlSchemaTypePtr) 12362 xmlSchemaParseModelGroup(ctxt, schema, child, 12363 XML_SCHEMA_TYPE_CHOICE, 1); 12364 child = child->next; 12365 } else if (IS_SCHEMA(child, "sequence")) { 12366 type->subtypes = (xmlSchemaTypePtr) 12367 xmlSchemaParseModelGroup(ctxt, schema, child, 12368 XML_SCHEMA_TYPE_SEQUENCE, 1); 12369 child = child->next; 12370 } else if (IS_SCHEMA(child, "group")) { 12371 type->subtypes = (xmlSchemaTypePtr) 12372 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12373 /* 12374 * Note that the reference will be resolved in 12375 * xmlSchemaResolveTypeReferences(); 12376 */ 12377 child = child->next; 12378 } 12379 /* 12380 * Parse attribute decls/refs. 12381 */ 12382 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12383 (xmlSchemaItemListPtr *) &(type->attrUses), 12384 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12385 return(NULL); 12386 /* 12387 * Parse attribute wildcard. 12388 */ 12389 if (IS_SCHEMA(child, "anyAttribute")) { 12390 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12391 child = child->next; 12392 } 12393 } 12394 if (child != NULL) { 12395 xmlSchemaPContentErr(ctxt, 12396 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12397 NULL, node, child, 12398 NULL, "(annotation?, (simpleContent | complexContent | " 12399 "((group | all | choice | sequence)?, ((attribute | " 12400 "attributeGroup)*, anyAttribute?))))"); 12401 } 12402 /* 12403 * REDEFINE: SPEC src-redefine (5) 12404 */ 12405 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12406 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12407 NULL, node, "This is a redefinition, thus the " 12408 "<complexType> must have a <restriction> or <extension> " 12409 "grand-child", NULL); 12410 } 12411 ctxt->ctxtType = ctxtType; 12412 return (type); 12413 } 12414 12415 /************************************************************************ 12416 * * 12417 * Validating using Schemas * 12418 * * 12419 ************************************************************************/ 12420 12421 /************************************************************************ 12422 * * 12423 * Reading/Writing Schemas * 12424 * * 12425 ************************************************************************/ 12426 12427 #if 0 /* Will be enabled if it is clear what options are needed. */ 12428 /** 12429 * xmlSchemaParserCtxtSetOptions: 12430 * @ctxt: a schema parser context 12431 * @options: a combination of xmlSchemaParserOption 12432 * 12433 * Sets the options to be used during the parse. 12434 * 12435 * Returns 0 in case of success, -1 in case of an 12436 * API error. 12437 */ 12438 static int 12439 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12440 int options) 12441 12442 { 12443 int i; 12444 12445 if (ctxt == NULL) 12446 return (-1); 12447 /* 12448 * WARNING: Change the start value if adding to the 12449 * xmlSchemaParseOption. 12450 */ 12451 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12452 if (options & 1<<i) { 12453 return (-1); 12454 } 12455 } 12456 ctxt->options = options; 12457 return (0); 12458 } 12459 12460 /** 12461 * xmlSchemaValidCtxtGetOptions: 12462 * @ctxt: a schema parser context 12463 * 12464 * Returns the option combination of the parser context. 12465 */ 12466 static int 12467 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12468 12469 { 12470 if (ctxt == NULL) 12471 return (-1); 12472 else 12473 return (ctxt->options); 12474 } 12475 #endif 12476 12477 /** 12478 * xmlSchemaNewParserCtxt: 12479 * @URL: the location of the schema 12480 * 12481 * Create an XML Schemas parse context for that file/resource expected 12482 * to contain an XML Schemas file. 12483 * 12484 * Returns the parser context or NULL in case of error 12485 */ 12486 xmlSchemaParserCtxtPtr 12487 xmlSchemaNewParserCtxt(const char *URL) 12488 { 12489 xmlSchemaParserCtxtPtr ret; 12490 12491 if (URL == NULL) 12492 return (NULL); 12493 12494 ret = xmlSchemaParserCtxtCreate(); 12495 if (ret == NULL) 12496 return(NULL); 12497 ret->dict = xmlDictCreate(); 12498 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12499 return (ret); 12500 } 12501 12502 /** 12503 * xmlSchemaNewMemParserCtxt: 12504 * @buffer: a pointer to a char array containing the schemas 12505 * @size: the size of the array 12506 * 12507 * Create an XML Schemas parse context for that memory buffer expected 12508 * to contain an XML Schemas file. 12509 * 12510 * Returns the parser context or NULL in case of error 12511 */ 12512 xmlSchemaParserCtxtPtr 12513 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12514 { 12515 xmlSchemaParserCtxtPtr ret; 12516 12517 if ((buffer == NULL) || (size <= 0)) 12518 return (NULL); 12519 ret = xmlSchemaParserCtxtCreate(); 12520 if (ret == NULL) 12521 return(NULL); 12522 ret->buffer = buffer; 12523 ret->size = size; 12524 ret->dict = xmlDictCreate(); 12525 return (ret); 12526 } 12527 12528 /** 12529 * xmlSchemaNewDocParserCtxt: 12530 * @doc: a preparsed document tree 12531 * 12532 * Create an XML Schemas parse context for that document. 12533 * NB. The document may be modified during the parsing process. 12534 * 12535 * Returns the parser context or NULL in case of error 12536 */ 12537 xmlSchemaParserCtxtPtr 12538 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12539 { 12540 xmlSchemaParserCtxtPtr ret; 12541 12542 if (doc == NULL) 12543 return (NULL); 12544 ret = xmlSchemaParserCtxtCreate(); 12545 if (ret == NULL) 12546 return(NULL); 12547 ret->doc = doc; 12548 ret->dict = xmlDictCreate(); 12549 /* The application has responsibility for the document */ 12550 ret->preserve = 1; 12551 12552 return (ret); 12553 } 12554 12555 /** 12556 * xmlSchemaFreeParserCtxt: 12557 * @ctxt: the schema parser context 12558 * 12559 * Free the resources associated to the schema parser context 12560 */ 12561 void 12562 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12563 { 12564 if (ctxt == NULL) 12565 return; 12566 if (ctxt->doc != NULL && !ctxt->preserve) 12567 xmlFreeDoc(ctxt->doc); 12568 if (ctxt->vctxt != NULL) { 12569 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12570 } 12571 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12572 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12573 ctxt->constructor = NULL; 12574 ctxt->ownsConstructor = 0; 12575 } 12576 if (ctxt->attrProhibs != NULL) 12577 xmlSchemaItemListFree(ctxt->attrProhibs); 12578 xmlDictFree(ctxt->dict); 12579 xmlFree(ctxt); 12580 } 12581 12582 /************************************************************************ 12583 * * 12584 * Building the content models * 12585 * * 12586 ************************************************************************/ 12587 12588 /** 12589 * xmlSchemaBuildContentModelForSubstGroup: 12590 * 12591 * Returns 1 if nillable, 0 otherwise 12592 */ 12593 static int 12594 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12595 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12596 { 12597 xmlAutomataStatePtr start, tmp; 12598 xmlSchemaElementPtr elemDecl, member; 12599 xmlSchemaSubstGroupPtr substGroup; 12600 int i; 12601 int ret = 0; 12602 12603 elemDecl = (xmlSchemaElementPtr) particle->children; 12604 /* 12605 * Wrap the substitution group with a CHOICE. 12606 */ 12607 start = pctxt->state; 12608 if (end == NULL) 12609 end = xmlAutomataNewState(pctxt->am); 12610 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12611 if (substGroup == NULL) { 12612 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12613 XML_SCHEMAP_INTERNAL, 12614 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12615 "declaration is marked having a subst. group but none " 12616 "available.\n", elemDecl->name, NULL); 12617 return(0); 12618 } 12619 if (counter >= 0) { 12620 /* 12621 * NOTE that we put the declaration in, even if it's abstract. 12622 * However, an error will be raised during *validation* if an element 12623 * information item shall be validated against an abstract element 12624 * declaration. 12625 */ 12626 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12627 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12628 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12629 /* 12630 * Add subst. group members. 12631 */ 12632 for (i = 0; i < substGroup->members->nbItems; i++) { 12633 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12634 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12635 member->name, member->targetNamespace, member); 12636 } 12637 } else if (particle->maxOccurs == 1) { 12638 /* 12639 * NOTE that we put the declaration in, even if it's abstract, 12640 */ 12641 xmlAutomataNewEpsilon(pctxt->am, 12642 xmlAutomataNewTransition2(pctxt->am, 12643 start, NULL, 12644 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12645 /* 12646 * Add subst. group members. 12647 */ 12648 for (i = 0; i < substGroup->members->nbItems; i++) { 12649 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12650 /* 12651 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12652 * was incorrectly used instead of xmlAutomataNewTransition2() 12653 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12654 * section in xmlSchemaBuildAContentModel() ). 12655 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12656 * intended for the above "counter" section originally. I.e., 12657 * check xs:all with subst-groups. 12658 * 12659 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12660 * member->name, member->targetNamespace, 12661 * 1, 1, member); 12662 */ 12663 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12664 member->name, member->targetNamespace, member); 12665 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12666 } 12667 } else { 12668 xmlAutomataStatePtr hop; 12669 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12670 UNBOUNDED : particle->maxOccurs - 1; 12671 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12672 12673 counter = 12674 xmlAutomataNewCounter(pctxt->am, minOccurs, 12675 maxOccurs); 12676 hop = xmlAutomataNewState(pctxt->am); 12677 12678 xmlAutomataNewEpsilon(pctxt->am, 12679 xmlAutomataNewTransition2(pctxt->am, 12680 start, NULL, 12681 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12682 hop); 12683 /* 12684 * Add subst. group members. 12685 */ 12686 for (i = 0; i < substGroup->members->nbItems; i++) { 12687 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12688 xmlAutomataNewEpsilon(pctxt->am, 12689 xmlAutomataNewTransition2(pctxt->am, 12690 start, NULL, 12691 member->name, member->targetNamespace, member), 12692 hop); 12693 } 12694 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12695 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12696 } 12697 if (particle->minOccurs == 0) { 12698 xmlAutomataNewEpsilon(pctxt->am, start, end); 12699 ret = 1; 12700 } 12701 pctxt->state = end; 12702 return(ret); 12703 } 12704 12705 /** 12706 * xmlSchemaBuildContentModelForElement: 12707 * 12708 * Returns 1 if nillable, 0 otherwise 12709 */ 12710 static int 12711 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12712 xmlSchemaParticlePtr particle) 12713 { 12714 int ret = 0; 12715 12716 if (((xmlSchemaElementPtr) particle->children)->flags & 12717 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12718 /* 12719 * Substitution groups. 12720 */ 12721 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12722 } else { 12723 xmlSchemaElementPtr elemDecl; 12724 xmlAutomataStatePtr start; 12725 12726 elemDecl = (xmlSchemaElementPtr) particle->children; 12727 12728 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12729 return(0); 12730 if (particle->maxOccurs == 1) { 12731 start = ctxt->state; 12732 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12733 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12734 } else if ((particle->maxOccurs >= UNBOUNDED) && 12735 (particle->minOccurs < 2)) { 12736 /* Special case. */ 12737 start = ctxt->state; 12738 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12739 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12740 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12741 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12742 } else { 12743 int counter; 12744 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12745 UNBOUNDED : particle->maxOccurs - 1; 12746 int minOccurs = particle->minOccurs < 1 ? 12747 0 : particle->minOccurs - 1; 12748 12749 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12750 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12751 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12752 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12753 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12754 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12755 NULL, counter); 12756 } 12757 if (particle->minOccurs == 0) { 12758 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12759 ret = 1; 12760 } 12761 } 12762 return(ret); 12763 } 12764 12765 /** 12766 * xmlSchemaBuildAContentModel: 12767 * @ctxt: the schema parser context 12768 * @particle: the particle component 12769 * @name: the complex type's name whose content is being built 12770 * 12771 * Create the automaton for the {content type} of a complex type. 12772 * 12773 * Returns 1 if the content is nillable, 0 otherwise 12774 */ 12775 static int 12776 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12777 xmlSchemaParticlePtr particle) 12778 { 12779 int ret = 0, tmp2; 12780 12781 if (particle == NULL) { 12782 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12783 return(1); 12784 } 12785 if (particle->children == NULL) { 12786 /* 12787 * Just return in this case. A missing "term" of the particle 12788 * might arise due to an invalid "term" component. 12789 */ 12790 return(1); 12791 } 12792 12793 switch (particle->children->type) { 12794 case XML_SCHEMA_TYPE_ANY: { 12795 xmlAutomataStatePtr start, end; 12796 xmlSchemaWildcardPtr wild; 12797 xmlSchemaWildcardNsPtr ns; 12798 12799 wild = (xmlSchemaWildcardPtr) particle->children; 12800 12801 start = pctxt->state; 12802 end = xmlAutomataNewState(pctxt->am); 12803 12804 if (particle->maxOccurs == 1) { 12805 if (wild->any == 1) { 12806 /* 12807 * We need to add both transitions: 12808 * 12809 * 1. the {"*", "*"} for elements in a namespace. 12810 */ 12811 pctxt->state = 12812 xmlAutomataNewTransition2(pctxt->am, 12813 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12814 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12815 /* 12816 * 2. the {"*"} for elements in no namespace. 12817 */ 12818 pctxt->state = 12819 xmlAutomataNewTransition2(pctxt->am, 12820 start, NULL, BAD_CAST "*", NULL, wild); 12821 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12822 12823 } else if (wild->nsSet != NULL) { 12824 ns = wild->nsSet; 12825 do { 12826 pctxt->state = start; 12827 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12828 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12829 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12830 ns = ns->next; 12831 } while (ns != NULL); 12832 12833 } else if (wild->negNsSet != NULL) { 12834 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12835 start, end, BAD_CAST "*", wild->negNsSet->value, 12836 wild); 12837 } 12838 } else { 12839 int counter; 12840 xmlAutomataStatePtr hop; 12841 int maxOccurs = 12842 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12843 particle->maxOccurs - 1; 12844 int minOccurs = 12845 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12846 12847 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12848 hop = xmlAutomataNewState(pctxt->am); 12849 if (wild->any == 1) { 12850 pctxt->state = 12851 xmlAutomataNewTransition2(pctxt->am, 12852 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12853 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12854 pctxt->state = 12855 xmlAutomataNewTransition2(pctxt->am, 12856 start, NULL, BAD_CAST "*", NULL, wild); 12857 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12858 } else if (wild->nsSet != NULL) { 12859 ns = wild->nsSet; 12860 do { 12861 pctxt->state = 12862 xmlAutomataNewTransition2(pctxt->am, 12863 start, NULL, BAD_CAST "*", ns->value, wild); 12864 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12865 ns = ns->next; 12866 } while (ns != NULL); 12867 12868 } else if (wild->negNsSet != NULL) { 12869 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12870 start, hop, BAD_CAST "*", wild->negNsSet->value, 12871 wild); 12872 } 12873 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12874 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12875 } 12876 if (particle->minOccurs == 0) { 12877 xmlAutomataNewEpsilon(pctxt->am, start, end); 12878 ret = 1; 12879 } 12880 pctxt->state = end; 12881 break; 12882 } 12883 case XML_SCHEMA_TYPE_ELEMENT: 12884 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12885 break; 12886 case XML_SCHEMA_TYPE_SEQUENCE:{ 12887 xmlSchemaTreeItemPtr sub; 12888 12889 ret = 1; 12890 /* 12891 * If max and min occurances are default (1) then 12892 * simply iterate over the particles of the <sequence>. 12893 */ 12894 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12895 sub = particle->children->children; 12896 12897 while (sub != NULL) { 12898 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12899 (xmlSchemaParticlePtr) sub); 12900 if (tmp2 != 1) ret = 0; 12901 sub = sub->next; 12902 } 12903 } else { 12904 xmlAutomataStatePtr oldstate = pctxt->state; 12905 12906 if (particle->maxOccurs >= UNBOUNDED) { 12907 if (particle->minOccurs > 1) { 12908 xmlAutomataStatePtr tmp; 12909 int counter; 12910 12911 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12912 oldstate, NULL); 12913 oldstate = pctxt->state; 12914 12915 counter = xmlAutomataNewCounter(pctxt->am, 12916 particle->minOccurs - 1, UNBOUNDED); 12917 12918 sub = particle->children->children; 12919 while (sub != NULL) { 12920 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12921 (xmlSchemaParticlePtr) sub); 12922 if (tmp2 != 1) ret = 0; 12923 sub = sub->next; 12924 } 12925 tmp = pctxt->state; 12926 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12927 oldstate, counter); 12928 pctxt->state = 12929 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12930 NULL, counter); 12931 if (ret == 1) 12932 xmlAutomataNewEpsilon(pctxt->am, 12933 oldstate, pctxt->state); 12934 12935 } else { 12936 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12937 oldstate, NULL); 12938 oldstate = pctxt->state; 12939 12940 sub = particle->children->children; 12941 while (sub != NULL) { 12942 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12943 (xmlSchemaParticlePtr) sub); 12944 if (tmp2 != 1) ret = 0; 12945 sub = sub->next; 12946 } 12947 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12948 oldstate); 12949 /* 12950 * epsilon needed to block previous trans from 12951 * being allowed to enter back from another 12952 * construct 12953 */ 12954 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12955 pctxt->state, NULL); 12956 if (particle->minOccurs == 0) { 12957 xmlAutomataNewEpsilon(pctxt->am, 12958 oldstate, pctxt->state); 12959 ret = 1; 12960 } 12961 } 12962 } else if ((particle->maxOccurs > 1) 12963 || (particle->minOccurs > 1)) { 12964 xmlAutomataStatePtr tmp; 12965 int counter; 12966 12967 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12968 oldstate, NULL); 12969 oldstate = pctxt->state; 12970 12971 counter = xmlAutomataNewCounter(pctxt->am, 12972 particle->minOccurs - 1, 12973 particle->maxOccurs - 1); 12974 12975 sub = particle->children->children; 12976 while (sub != NULL) { 12977 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12978 (xmlSchemaParticlePtr) sub); 12979 if (tmp2 != 1) ret = 0; 12980 sub = sub->next; 12981 } 12982 tmp = pctxt->state; 12983 xmlAutomataNewCountedTrans(pctxt->am, 12984 tmp, oldstate, counter); 12985 pctxt->state = 12986 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12987 counter); 12988 if ((particle->minOccurs == 0) || (ret == 1)) { 12989 xmlAutomataNewEpsilon(pctxt->am, 12990 oldstate, pctxt->state); 12991 ret = 1; 12992 } 12993 } else { 12994 sub = particle->children->children; 12995 while (sub != NULL) { 12996 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12997 (xmlSchemaParticlePtr) sub); 12998 if (tmp2 != 1) ret = 0; 12999 sub = sub->next; 13000 } 13001 13002 /* 13003 * epsilon needed to block previous trans from 13004 * being allowed to enter back from another 13005 * construct 13006 */ 13007 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 13008 pctxt->state, NULL); 13009 13010 if (particle->minOccurs == 0) { 13011 xmlAutomataNewEpsilon(pctxt->am, oldstate, 13012 pctxt->state); 13013 ret = 1; 13014 } 13015 } 13016 } 13017 break; 13018 } 13019 case XML_SCHEMA_TYPE_CHOICE:{ 13020 xmlSchemaTreeItemPtr sub; 13021 xmlAutomataStatePtr start, end; 13022 13023 ret = 0; 13024 start = pctxt->state; 13025 end = xmlAutomataNewState(pctxt->am); 13026 13027 /* 13028 * iterate over the subtypes and remerge the end with an 13029 * epsilon transition 13030 */ 13031 if (particle->maxOccurs == 1) { 13032 sub = particle->children->children; 13033 while (sub != NULL) { 13034 pctxt->state = start; 13035 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13036 (xmlSchemaParticlePtr) sub); 13037 if (tmp2 == 1) ret = 1; 13038 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13039 sub = sub->next; 13040 } 13041 } else { 13042 int counter; 13043 xmlAutomataStatePtr hop, base; 13044 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13045 UNBOUNDED : particle->maxOccurs - 1; 13046 int minOccurs = 13047 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13048 13049 /* 13050 * use a counter to keep track of the number of transtions 13051 * which went through the choice. 13052 */ 13053 counter = 13054 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13055 hop = xmlAutomataNewState(pctxt->am); 13056 base = xmlAutomataNewState(pctxt->am); 13057 13058 sub = particle->children->children; 13059 while (sub != NULL) { 13060 pctxt->state = base; 13061 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13062 (xmlSchemaParticlePtr) sub); 13063 if (tmp2 == 1) ret = 1; 13064 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13065 sub = sub->next; 13066 } 13067 xmlAutomataNewEpsilon(pctxt->am, start, base); 13068 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13069 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13070 if (ret == 1) 13071 xmlAutomataNewEpsilon(pctxt->am, base, end); 13072 } 13073 if (particle->minOccurs == 0) { 13074 xmlAutomataNewEpsilon(pctxt->am, start, end); 13075 ret = 1; 13076 } 13077 pctxt->state = end; 13078 break; 13079 } 13080 case XML_SCHEMA_TYPE_ALL:{ 13081 xmlAutomataStatePtr start, tmp; 13082 xmlSchemaParticlePtr sub; 13083 xmlSchemaElementPtr elemDecl; 13084 13085 ret = 1; 13086 13087 sub = (xmlSchemaParticlePtr) particle->children->children; 13088 if (sub == NULL) 13089 break; 13090 13091 ret = 0; 13092 13093 start = pctxt->state; 13094 tmp = xmlAutomataNewState(pctxt->am); 13095 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13096 pctxt->state = tmp; 13097 while (sub != NULL) { 13098 pctxt->state = tmp; 13099 13100 elemDecl = (xmlSchemaElementPtr) sub->children; 13101 if (elemDecl == NULL) { 13102 PERROR_INT("xmlSchemaBuildAContentModel", 13103 "<element> particle has no term"); 13104 return(ret); 13105 }; 13106 /* 13107 * NOTE: The {max occurs} of all the particles in the 13108 * {particles} of the group must be 0 or 1; this is 13109 * already ensured during the parse of the content of 13110 * <all>. 13111 */ 13112 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13113 int counter; 13114 13115 /* 13116 * This is an abstract group, we need to share 13117 * the same counter for all the element transitions 13118 * derived from the group 13119 */ 13120 counter = xmlAutomataNewCounter(pctxt->am, 13121 sub->minOccurs, sub->maxOccurs); 13122 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13123 sub, counter, pctxt->state); 13124 } else { 13125 if ((sub->minOccurs == 1) && 13126 (sub->maxOccurs == 1)) { 13127 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13128 pctxt->state, 13129 elemDecl->name, 13130 elemDecl->targetNamespace, 13131 1, 1, elemDecl); 13132 } else if ((sub->minOccurs == 0) && 13133 (sub->maxOccurs == 1)) { 13134 13135 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13136 pctxt->state, 13137 elemDecl->name, 13138 elemDecl->targetNamespace, 13139 0, 13140 1, 13141 elemDecl); 13142 } 13143 } 13144 sub = (xmlSchemaParticlePtr) sub->next; 13145 } 13146 pctxt->state = 13147 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13148 if (particle->minOccurs == 0) { 13149 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13150 ret = 1; 13151 } 13152 break; 13153 } 13154 case XML_SCHEMA_TYPE_GROUP: 13155 /* 13156 * If we hit a model group definition, then this means that 13157 * it was empty, thus was not substituted for the containing 13158 * model group. Just do nothing in this case. 13159 * TODO: But the group should be substituted and not occur at 13160 * all in the content model at this point. Fix this. 13161 */ 13162 ret = 1; 13163 break; 13164 default: 13165 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13166 "xmlSchemaBuildAContentModel", 13167 "found unexpected term of type '%s' in content model", 13168 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13169 return(ret); 13170 } 13171 return(ret); 13172 } 13173 13174 /** 13175 * xmlSchemaBuildContentModel: 13176 * @ctxt: the schema parser context 13177 * @type: the complex type definition 13178 * @name: the element name 13179 * 13180 * Builds the content model of the complex type. 13181 */ 13182 static void 13183 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13184 xmlSchemaParserCtxtPtr ctxt) 13185 { 13186 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13187 (type->contModel != NULL) || 13188 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13189 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13190 return; 13191 13192 #ifdef DEBUG_CONTENT 13193 xmlGenericError(xmlGenericErrorContext, 13194 "Building content model for %s\n", name); 13195 #endif 13196 ctxt->am = NULL; 13197 ctxt->am = xmlNewAutomata(); 13198 if (ctxt->am == NULL) { 13199 xmlGenericError(xmlGenericErrorContext, 13200 "Cannot create automata for complex type %s\n", type->name); 13201 return; 13202 } 13203 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13204 /* 13205 * Build the automaton. 13206 */ 13207 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13208 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13209 type->contModel = xmlAutomataCompile(ctxt->am); 13210 if (type->contModel == NULL) { 13211 xmlSchemaPCustomErr(ctxt, 13212 XML_SCHEMAP_INTERNAL, 13213 WXS_BASIC_CAST type, type->node, 13214 "Failed to compile the content model", NULL); 13215 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13216 xmlSchemaPCustomErr(ctxt, 13217 XML_SCHEMAP_NOT_DETERMINISTIC, 13218 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13219 WXS_BASIC_CAST type, type->node, 13220 "The content model is not determinist", NULL); 13221 } else { 13222 #ifdef DEBUG_CONTENT_REGEXP 13223 xmlGenericError(xmlGenericErrorContext, 13224 "Content model of %s:\n", type->name); 13225 xmlRegexpPrint(stderr, type->contModel); 13226 #endif 13227 } 13228 ctxt->state = NULL; 13229 xmlFreeAutomata(ctxt->am); 13230 ctxt->am = NULL; 13231 } 13232 13233 /** 13234 * xmlSchemaResolveElementReferences: 13235 * @elem: the schema element context 13236 * @ctxt: the schema parser context 13237 * 13238 * Resolves the references of an element declaration 13239 * or particle, which has an element declaration as it's 13240 * term. 13241 */ 13242 static void 13243 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13244 xmlSchemaParserCtxtPtr ctxt) 13245 { 13246 if ((ctxt == NULL) || (elemDecl == NULL) || 13247 ((elemDecl != NULL) && 13248 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13249 return; 13250 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13251 13252 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13253 xmlSchemaTypePtr type; 13254 13255 /* (type definition) ... otherwise the type definition `resolved` 13256 * to by the `actual value` of the type [attribute] ... 13257 */ 13258 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13259 elemDecl->namedTypeNs); 13260 if (type == NULL) { 13261 xmlSchemaPResCompAttrErr(ctxt, 13262 XML_SCHEMAP_SRC_RESOLVE, 13263 WXS_BASIC_CAST elemDecl, elemDecl->node, 13264 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13265 XML_SCHEMA_TYPE_BASIC, "type definition"); 13266 } else 13267 elemDecl->subtypes = type; 13268 } 13269 if (elemDecl->substGroup != NULL) { 13270 xmlSchemaElementPtr substHead; 13271 13272 /* 13273 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13274 * substitutionGroup? 13275 */ 13276 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13277 elemDecl->substGroupNs); 13278 if (substHead == NULL) { 13279 xmlSchemaPResCompAttrErr(ctxt, 13280 XML_SCHEMAP_SRC_RESOLVE, 13281 WXS_BASIC_CAST elemDecl, NULL, 13282 "substitutionGroup", elemDecl->substGroup, 13283 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13284 } else { 13285 xmlSchemaResolveElementReferences(substHead, ctxt); 13286 /* 13287 * Set the "substitution group affiliation". 13288 * NOTE that now we use the "refDecl" field for this. 13289 */ 13290 WXS_SUBST_HEAD(elemDecl) = substHead; 13291 /* 13292 * The type definitions is set to: 13293 * SPEC "...the {type definition} of the element 13294 * declaration `resolved` to by the `actual value` 13295 * of the substitutionGroup [attribute], if present" 13296 */ 13297 if (elemDecl->subtypes == NULL) 13298 elemDecl->subtypes = substHead->subtypes; 13299 } 13300 } 13301 /* 13302 * SPEC "The definition of anyType serves as the default type definition 13303 * for element declarations whose XML representation does not specify one." 13304 */ 13305 if ((elemDecl->subtypes == NULL) && 13306 (elemDecl->namedType == NULL) && 13307 (elemDecl->substGroup == NULL)) 13308 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13309 } 13310 13311 /** 13312 * xmlSchemaResolveUnionMemberTypes: 13313 * @ctxt: the schema parser context 13314 * @type: the schema simple type definition 13315 * 13316 * Checks and builds the "member type definitions" property of the union 13317 * simple type. This handles part (1), part (2) is done in 13318 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13319 * 13320 * Returns -1 in case of an internal error, 0 otherwise. 13321 */ 13322 static int 13323 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13324 xmlSchemaTypePtr type) 13325 { 13326 13327 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13328 xmlSchemaTypePtr memberType; 13329 13330 /* 13331 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13332 * define the explicit members as the type definitions `resolved` 13333 * to by the items in the `actual value` of the memberTypes [attribute], 13334 * if any, followed by the type definitions corresponding to the 13335 * <simpleType>s among the [children] of <union>, if any." 13336 */ 13337 /* 13338 * Resolve references. 13339 */ 13340 link = type->memberTypes; 13341 lastLink = NULL; 13342 while (link != NULL) { 13343 const xmlChar *name, *nsName; 13344 13345 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13346 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13347 13348 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13349 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13350 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13351 WXS_BASIC_CAST type, type->node, "memberTypes", 13352 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13353 /* 13354 * Remove the member type link. 13355 */ 13356 if (lastLink == NULL) 13357 type->memberTypes = link->next; 13358 else 13359 lastLink->next = link->next; 13360 newLink = link; 13361 link = link->next; 13362 xmlFree(newLink); 13363 } else { 13364 link->type = memberType; 13365 lastLink = link; 13366 link = link->next; 13367 } 13368 } 13369 /* 13370 * Add local simple types, 13371 */ 13372 memberType = type->subtypes; 13373 while (memberType != NULL) { 13374 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13375 if (link == NULL) { 13376 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13377 return (-1); 13378 } 13379 link->type = memberType; 13380 link->next = NULL; 13381 if (lastLink == NULL) 13382 type->memberTypes = link; 13383 else 13384 lastLink->next = link; 13385 lastLink = link; 13386 memberType = memberType->next; 13387 } 13388 return (0); 13389 } 13390 13391 /** 13392 * xmlSchemaIsDerivedFromBuiltInType: 13393 * @ctxt: the schema parser context 13394 * @type: the type definition 13395 * @valType: the value type 13396 * 13397 * 13398 * Returns 1 if the type has the given value type, or 13399 * is derived from such a type. 13400 */ 13401 static int 13402 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13403 { 13404 if (type == NULL) 13405 return (0); 13406 if (WXS_IS_COMPLEX(type)) 13407 return (0); 13408 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13409 if (type->builtInType == valType) 13410 return(1); 13411 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13412 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13413 return (0); 13414 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13415 } 13416 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13417 } 13418 13419 #if 0 13420 /** 13421 * xmlSchemaIsDerivedFromBuiltInType: 13422 * @ctxt: the schema parser context 13423 * @type: the type definition 13424 * @valType: the value type 13425 * 13426 * 13427 * Returns 1 if the type has the given value type, or 13428 * is derived from such a type. 13429 */ 13430 static int 13431 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13432 { 13433 if (type == NULL) 13434 return (0); 13435 if (WXS_IS_COMPLEX(type)) 13436 return (0); 13437 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13438 if (type->builtInType == valType) 13439 return(1); 13440 return (0); 13441 } else 13442 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13443 13444 return (0); 13445 } 13446 13447 static xmlSchemaTypePtr 13448 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13449 { 13450 if (type == NULL) 13451 return (NULL); 13452 if (WXS_IS_COMPLEX(type)) 13453 return (NULL); 13454 if (type->type == XML_SCHEMA_TYPE_BASIC) 13455 return(type); 13456 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13457 } 13458 #endif 13459 13460 /** 13461 * xmlSchemaGetPrimitiveType: 13462 * @type: the simpleType definition 13463 * 13464 * Returns the primitive type of the given type or 13465 * NULL in case of error. 13466 */ 13467 static xmlSchemaTypePtr 13468 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13469 { 13470 13471 while (type != NULL) { 13472 /* 13473 * Note that anySimpleType is actually not a primitive type 13474 * but we need that here. 13475 */ 13476 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13477 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13478 return (type); 13479 type = type->baseType; 13480 } 13481 13482 return (NULL); 13483 } 13484 13485 #if 0 13486 /** 13487 * xmlSchemaGetBuiltInTypeAncestor: 13488 * @type: the simpleType definition 13489 * 13490 * Returns the primitive type of the given type or 13491 * NULL in case of error. 13492 */ 13493 static xmlSchemaTypePtr 13494 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13495 { 13496 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13497 return (0); 13498 while (type != NULL) { 13499 if (type->type == XML_SCHEMA_TYPE_BASIC) 13500 return (type); 13501 type = type->baseType; 13502 } 13503 13504 return (NULL); 13505 } 13506 #endif 13507 13508 /** 13509 * xmlSchemaCloneWildcardNsConstraints: 13510 * @ctxt: the schema parser context 13511 * @dest: the destination wildcard 13512 * @source: the source wildcard 13513 * 13514 * Clones the namespace constraints of source 13515 * and assignes them to dest. 13516 * Returns -1 on internal error, 0 otherwise. 13517 */ 13518 static int 13519 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13520 xmlSchemaWildcardPtr dest, 13521 xmlSchemaWildcardPtr source) 13522 { 13523 xmlSchemaWildcardNsPtr cur, tmp, last; 13524 13525 if ((source == NULL) || (dest == NULL)) 13526 return(-1); 13527 dest->any = source->any; 13528 cur = source->nsSet; 13529 last = NULL; 13530 while (cur != NULL) { 13531 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13532 if (tmp == NULL) 13533 return(-1); 13534 tmp->value = cur->value; 13535 if (last == NULL) 13536 dest->nsSet = tmp; 13537 else 13538 last->next = tmp; 13539 last = tmp; 13540 cur = cur->next; 13541 } 13542 if (dest->negNsSet != NULL) 13543 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13544 if (source->negNsSet != NULL) { 13545 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13546 if (dest->negNsSet == NULL) 13547 return(-1); 13548 dest->negNsSet->value = source->negNsSet->value; 13549 } else 13550 dest->negNsSet = NULL; 13551 return(0); 13552 } 13553 13554 /** 13555 * xmlSchemaUnionWildcards: 13556 * @ctxt: the schema parser context 13557 * @completeWild: the first wildcard 13558 * @curWild: the second wildcard 13559 * 13560 * Unions the namespace constraints of the given wildcards. 13561 * @completeWild will hold the resulting union. 13562 * Returns a positive error code on failure, -1 in case of an 13563 * internal error, 0 otherwise. 13564 */ 13565 static int 13566 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13567 xmlSchemaWildcardPtr completeWild, 13568 xmlSchemaWildcardPtr curWild) 13569 { 13570 xmlSchemaWildcardNsPtr cur, curB, tmp; 13571 13572 /* 13573 * 1 If O1 and O2 are the same value, then that value must be the 13574 * value. 13575 */ 13576 if ((completeWild->any == curWild->any) && 13577 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13578 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13579 13580 if ((completeWild->negNsSet == NULL) || 13581 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13582 13583 if (completeWild->nsSet != NULL) { 13584 int found = 0; 13585 13586 /* 13587 * Check equality of sets. 13588 */ 13589 cur = completeWild->nsSet; 13590 while (cur != NULL) { 13591 found = 0; 13592 curB = curWild->nsSet; 13593 while (curB != NULL) { 13594 if (cur->value == curB->value) { 13595 found = 1; 13596 break; 13597 } 13598 curB = curB->next; 13599 } 13600 if (!found) 13601 break; 13602 cur = cur->next; 13603 } 13604 if (found) 13605 return(0); 13606 } else 13607 return(0); 13608 } 13609 } 13610 /* 13611 * 2 If either O1 or O2 is any, then any must be the value 13612 */ 13613 if (completeWild->any != curWild->any) { 13614 if (completeWild->any == 0) { 13615 completeWild->any = 1; 13616 if (completeWild->nsSet != NULL) { 13617 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13618 completeWild->nsSet = NULL; 13619 } 13620 if (completeWild->negNsSet != NULL) { 13621 xmlFree(completeWild->negNsSet); 13622 completeWild->negNsSet = NULL; 13623 } 13624 } 13625 return (0); 13626 } 13627 /* 13628 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13629 * then the union of those sets must be the value. 13630 */ 13631 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13632 int found; 13633 xmlSchemaWildcardNsPtr start; 13634 13635 cur = curWild->nsSet; 13636 start = completeWild->nsSet; 13637 while (cur != NULL) { 13638 found = 0; 13639 curB = start; 13640 while (curB != NULL) { 13641 if (cur->value == curB->value) { 13642 found = 1; 13643 break; 13644 } 13645 curB = curB->next; 13646 } 13647 if (!found) { 13648 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13649 if (tmp == NULL) 13650 return (-1); 13651 tmp->value = cur->value; 13652 tmp->next = completeWild->nsSet; 13653 completeWild->nsSet = tmp; 13654 } 13655 cur = cur->next; 13656 } 13657 13658 return(0); 13659 } 13660 /* 13661 * 4 If the two are negations of different values (namespace names 13662 * or `absent`), then a pair of not and `absent` must be the value. 13663 */ 13664 if ((completeWild->negNsSet != NULL) && 13665 (curWild->negNsSet != NULL) && 13666 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13667 completeWild->negNsSet->value = NULL; 13668 13669 return(0); 13670 } 13671 /* 13672 * 5. 13673 */ 13674 if (((completeWild->negNsSet != NULL) && 13675 (completeWild->negNsSet->value != NULL) && 13676 (curWild->nsSet != NULL)) || 13677 ((curWild->negNsSet != NULL) && 13678 (curWild->negNsSet->value != NULL) && 13679 (completeWild->nsSet != NULL))) { 13680 13681 int nsFound, absentFound = 0; 13682 13683 if (completeWild->nsSet != NULL) { 13684 cur = completeWild->nsSet; 13685 curB = curWild->negNsSet; 13686 } else { 13687 cur = curWild->nsSet; 13688 curB = completeWild->negNsSet; 13689 } 13690 nsFound = 0; 13691 while (cur != NULL) { 13692 if (cur->value == NULL) 13693 absentFound = 1; 13694 else if (cur->value == curB->value) 13695 nsFound = 1; 13696 if (nsFound && absentFound) 13697 break; 13698 cur = cur->next; 13699 } 13700 13701 if (nsFound && absentFound) { 13702 /* 13703 * 5.1 If the set S includes both the negated namespace 13704 * name and `absent`, then any must be the value. 13705 */ 13706 completeWild->any = 1; 13707 if (completeWild->nsSet != NULL) { 13708 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13709 completeWild->nsSet = NULL; 13710 } 13711 if (completeWild->negNsSet != NULL) { 13712 xmlFree(completeWild->negNsSet); 13713 completeWild->negNsSet = NULL; 13714 } 13715 } else if (nsFound && (!absentFound)) { 13716 /* 13717 * 5.2 If the set S includes the negated namespace name 13718 * but not `absent`, then a pair of not and `absent` must 13719 * be the value. 13720 */ 13721 if (completeWild->nsSet != NULL) { 13722 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13723 completeWild->nsSet = NULL; 13724 } 13725 if (completeWild->negNsSet == NULL) { 13726 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13727 if (completeWild->negNsSet == NULL) 13728 return (-1); 13729 } 13730 completeWild->negNsSet->value = NULL; 13731 } else if ((!nsFound) && absentFound) { 13732 /* 13733 * 5.3 If the set S includes `absent` but not the negated 13734 * namespace name, then the union is not expressible. 13735 */ 13736 xmlSchemaPErr(ctxt, completeWild->node, 13737 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13738 "The union of the wilcard is not expressible.\n", 13739 NULL, NULL); 13740 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13741 } else if ((!nsFound) && (!absentFound)) { 13742 /* 13743 * 5.4 If the set S does not include either the negated namespace 13744 * name or `absent`, then whichever of O1 or O2 is a pair of not 13745 * and a namespace name must be the value. 13746 */ 13747 if (completeWild->negNsSet == NULL) { 13748 if (completeWild->nsSet != NULL) { 13749 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13750 completeWild->nsSet = NULL; 13751 } 13752 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13753 if (completeWild->negNsSet == NULL) 13754 return (-1); 13755 completeWild->negNsSet->value = curWild->negNsSet->value; 13756 } 13757 } 13758 return (0); 13759 } 13760 /* 13761 * 6. 13762 */ 13763 if (((completeWild->negNsSet != NULL) && 13764 (completeWild->negNsSet->value == NULL) && 13765 (curWild->nsSet != NULL)) || 13766 ((curWild->negNsSet != NULL) && 13767 (curWild->negNsSet->value == NULL) && 13768 (completeWild->nsSet != NULL))) { 13769 13770 if (completeWild->nsSet != NULL) { 13771 cur = completeWild->nsSet; 13772 } else { 13773 cur = curWild->nsSet; 13774 } 13775 while (cur != NULL) { 13776 if (cur->value == NULL) { 13777 /* 13778 * 6.1 If the set S includes `absent`, then any must be the 13779 * value. 13780 */ 13781 completeWild->any = 1; 13782 if (completeWild->nsSet != NULL) { 13783 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13784 completeWild->nsSet = NULL; 13785 } 13786 if (completeWild->negNsSet != NULL) { 13787 xmlFree(completeWild->negNsSet); 13788 completeWild->negNsSet = NULL; 13789 } 13790 return (0); 13791 } 13792 cur = cur->next; 13793 } 13794 if (completeWild->negNsSet == NULL) { 13795 /* 13796 * 6.2 If the set S does not include `absent`, then a pair of not 13797 * and `absent` must be the value. 13798 */ 13799 if (completeWild->nsSet != NULL) { 13800 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13801 completeWild->nsSet = NULL; 13802 } 13803 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13804 if (completeWild->negNsSet == NULL) 13805 return (-1); 13806 completeWild->negNsSet->value = NULL; 13807 } 13808 return (0); 13809 } 13810 return (0); 13811 13812 } 13813 13814 /** 13815 * xmlSchemaIntersectWildcards: 13816 * @ctxt: the schema parser context 13817 * @completeWild: the first wildcard 13818 * @curWild: the second wildcard 13819 * 13820 * Intersects the namespace constraints of the given wildcards. 13821 * @completeWild will hold the resulting intersection. 13822 * Returns a positive error code on failure, -1 in case of an 13823 * internal error, 0 otherwise. 13824 */ 13825 static int 13826 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13827 xmlSchemaWildcardPtr completeWild, 13828 xmlSchemaWildcardPtr curWild) 13829 { 13830 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13831 13832 /* 13833 * 1 If O1 and O2 are the same value, then that value must be the 13834 * value. 13835 */ 13836 if ((completeWild->any == curWild->any) && 13837 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13838 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13839 13840 if ((completeWild->negNsSet == NULL) || 13841 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13842 13843 if (completeWild->nsSet != NULL) { 13844 int found = 0; 13845 13846 /* 13847 * Check equality of sets. 13848 */ 13849 cur = completeWild->nsSet; 13850 while (cur != NULL) { 13851 found = 0; 13852 curB = curWild->nsSet; 13853 while (curB != NULL) { 13854 if (cur->value == curB->value) { 13855 found = 1; 13856 break; 13857 } 13858 curB = curB->next; 13859 } 13860 if (!found) 13861 break; 13862 cur = cur->next; 13863 } 13864 if (found) 13865 return(0); 13866 } else 13867 return(0); 13868 } 13869 } 13870 /* 13871 * 2 If either O1 or O2 is any, then the other must be the value. 13872 */ 13873 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13874 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13875 return(-1); 13876 return(0); 13877 } 13878 /* 13879 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13880 * name or `absent`) and the other is a set of (namespace names or 13881 * `absent`), then that set, minus the negated value if it was in 13882 * the set, minus `absent` if it was in the set, must be the value. 13883 */ 13884 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13885 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13886 const xmlChar *neg; 13887 13888 if (completeWild->nsSet == NULL) { 13889 neg = completeWild->negNsSet->value; 13890 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13891 return(-1); 13892 } else 13893 neg = curWild->negNsSet->value; 13894 /* 13895 * Remove absent and negated. 13896 */ 13897 prev = NULL; 13898 cur = completeWild->nsSet; 13899 while (cur != NULL) { 13900 if (cur->value == NULL) { 13901 if (prev == NULL) 13902 completeWild->nsSet = cur->next; 13903 else 13904 prev->next = cur->next; 13905 xmlFree(cur); 13906 break; 13907 } 13908 prev = cur; 13909 cur = cur->next; 13910 } 13911 if (neg != NULL) { 13912 prev = NULL; 13913 cur = completeWild->nsSet; 13914 while (cur != NULL) { 13915 if (cur->value == neg) { 13916 if (prev == NULL) 13917 completeWild->nsSet = cur->next; 13918 else 13919 prev->next = cur->next; 13920 xmlFree(cur); 13921 break; 13922 } 13923 prev = cur; 13924 cur = cur->next; 13925 } 13926 } 13927 13928 return(0); 13929 } 13930 /* 13931 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13932 * then the intersection of those sets must be the value. 13933 */ 13934 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13935 int found; 13936 13937 cur = completeWild->nsSet; 13938 prev = NULL; 13939 while (cur != NULL) { 13940 found = 0; 13941 curB = curWild->nsSet; 13942 while (curB != NULL) { 13943 if (cur->value == curB->value) { 13944 found = 1; 13945 break; 13946 } 13947 curB = curB->next; 13948 } 13949 if (!found) { 13950 if (prev == NULL) 13951 completeWild->nsSet = cur->next; 13952 else 13953 prev->next = cur->next; 13954 tmp = cur->next; 13955 xmlFree(cur); 13956 cur = tmp; 13957 continue; 13958 } 13959 prev = cur; 13960 cur = cur->next; 13961 } 13962 13963 return(0); 13964 } 13965 /* 5 If the two are negations of different namespace names, 13966 * then the intersection is not expressible 13967 */ 13968 if ((completeWild->negNsSet != NULL) && 13969 (curWild->negNsSet != NULL) && 13970 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13971 (completeWild->negNsSet->value != NULL) && 13972 (curWild->negNsSet->value != NULL)) { 13973 13974 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13975 "The intersection of the wilcard is not expressible.\n", 13976 NULL, NULL); 13977 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13978 } 13979 /* 13980 * 6 If the one is a negation of a namespace name and the other 13981 * is a negation of `absent`, then the one which is the negation 13982 * of a namespace name must be the value. 13983 */ 13984 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13985 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13986 (completeWild->negNsSet->value == NULL)) { 13987 completeWild->negNsSet->value = curWild->negNsSet->value; 13988 } 13989 return(0); 13990 } 13991 13992 /** 13993 * xmlSchemaIsWildcardNsConstraintSubset: 13994 * @ctxt: the schema parser context 13995 * @sub: the first wildcard 13996 * @super: the second wildcard 13997 * 13998 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13999 * 14000 * Returns 0 if the namespace constraint of @sub is an intensional 14001 * subset of @super, 1 otherwise. 14002 */ 14003 static int 14004 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 14005 xmlSchemaWildcardPtr super) 14006 { 14007 /* 14008 * 1 super must be any. 14009 */ 14010 if (super->any) 14011 return (0); 14012 /* 14013 * 2.1 sub must be a pair of not and a namespace name or `absent`. 14014 * 2.2 super must be a pair of not and the same value. 14015 */ 14016 if ((sub->negNsSet != NULL) && 14017 (super->negNsSet != NULL) && 14018 (sub->negNsSet->value == super->negNsSet->value)) 14019 return (0); 14020 /* 14021 * 3.1 sub must be a set whose members are either namespace names or `absent`. 14022 */ 14023 if (sub->nsSet != NULL) { 14024 /* 14025 * 3.2.1 super must be the same set or a superset thereof. 14026 */ 14027 if (super->nsSet != NULL) { 14028 xmlSchemaWildcardNsPtr cur, curB; 14029 int found = 0; 14030 14031 cur = sub->nsSet; 14032 while (cur != NULL) { 14033 found = 0; 14034 curB = super->nsSet; 14035 while (curB != NULL) { 14036 if (cur->value == curB->value) { 14037 found = 1; 14038 break; 14039 } 14040 curB = curB->next; 14041 } 14042 if (!found) 14043 return (1); 14044 cur = cur->next; 14045 } 14046 if (found) 14047 return (0); 14048 } else if (super->negNsSet != NULL) { 14049 xmlSchemaWildcardNsPtr cur; 14050 /* 14051 * 3.2.2 super must be a pair of not and a namespace name or 14052 * `absent` and that value must not be in sub's set. 14053 */ 14054 cur = sub->nsSet; 14055 while (cur != NULL) { 14056 if (cur->value == super->negNsSet->value) 14057 return (1); 14058 cur = cur->next; 14059 } 14060 return (0); 14061 } 14062 } 14063 return (1); 14064 } 14065 14066 static int 14067 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14068 int *fixed, 14069 const xmlChar **value, 14070 xmlSchemaValPtr *val) 14071 { 14072 *fixed = 0; 14073 *value = NULL; 14074 if (val != 0) 14075 *val = NULL; 14076 14077 if (attruse->defValue != NULL) { 14078 *value = attruse->defValue; 14079 if (val != NULL) 14080 *val = attruse->defVal; 14081 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14082 *fixed = 1; 14083 return(1); 14084 } else if ((attruse->attrDecl != NULL) && 14085 (attruse->attrDecl->defValue != NULL)) { 14086 *value = attruse->attrDecl->defValue; 14087 if (val != NULL) 14088 *val = attruse->attrDecl->defVal; 14089 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14090 *fixed = 1; 14091 return(1); 14092 } 14093 return(0); 14094 } 14095 /** 14096 * xmlSchemaCheckCVCWildcardNamespace: 14097 * @wild: the wildcard 14098 * @ns: the namespace 14099 * 14100 * Validation Rule: Wildcard allows Namespace Name 14101 * (cvc-wildcard-namespace) 14102 * 14103 * Returns 0 if the given namespace matches the wildcard, 14104 * 1 otherwise and -1 on API errors. 14105 */ 14106 static int 14107 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14108 const xmlChar* ns) 14109 { 14110 if (wild == NULL) 14111 return(-1); 14112 14113 if (wild->any) 14114 return(0); 14115 else if (wild->nsSet != NULL) { 14116 xmlSchemaWildcardNsPtr cur; 14117 14118 cur = wild->nsSet; 14119 while (cur != NULL) { 14120 if (xmlStrEqual(cur->value, ns)) 14121 return(0); 14122 cur = cur->next; 14123 } 14124 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14125 (!xmlStrEqual(wild->negNsSet->value, ns))) 14126 return(0); 14127 14128 return(1); 14129 } 14130 14131 #define XML_SCHEMA_ACTION_DERIVE 0 14132 #define XML_SCHEMA_ACTION_REDEFINE 1 14133 14134 #define WXS_ACTION_STR(a) \ 14135 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14136 14137 /* 14138 * Schema Component Constraint: 14139 * Derivation Valid (Restriction, Complex) 14140 * derivation-ok-restriction (2) - (4) 14141 * 14142 * ATTENTION: 14143 * In XML Schema 1.1 this will be: 14144 * Validation Rule: 14145 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14146 * 14147 */ 14148 static int 14149 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14150 int action, 14151 xmlSchemaBasicItemPtr item, 14152 xmlSchemaBasicItemPtr baseItem, 14153 xmlSchemaItemListPtr uses, 14154 xmlSchemaItemListPtr baseUses, 14155 xmlSchemaWildcardPtr wild, 14156 xmlSchemaWildcardPtr baseWild) 14157 { 14158 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14159 int i, j, found; /* err = 0; */ 14160 const xmlChar *bEffValue; 14161 int effFixed; 14162 14163 if (uses != NULL) { 14164 for (i = 0; i < uses->nbItems; i++) { 14165 cur = uses->items[i]; 14166 found = 0; 14167 if (baseUses == NULL) 14168 goto not_found; 14169 for (j = 0; j < baseUses->nbItems; j++) { 14170 bcur = baseUses->items[j]; 14171 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14172 WXS_ATTRUSE_DECL_NAME(bcur)) && 14173 (WXS_ATTRUSE_DECL_TNS(cur) == 14174 WXS_ATTRUSE_DECL_TNS(bcur))) 14175 { 14176 /* 14177 * (2.1) "If there is an attribute use in the {attribute 14178 * uses} of the {base type definition} (call this B) whose 14179 * {attribute declaration} has the same {name} and {target 14180 * namespace}, then all of the following must be true:" 14181 */ 14182 found = 1; 14183 14184 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14185 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14186 { 14187 xmlChar *str = NULL; 14188 /* 14189 * (2.1.1) "one of the following must be true:" 14190 * (2.1.1.1) "B's {required} is false." 14191 * (2.1.1.2) "R's {required} is true." 14192 */ 14193 xmlSchemaPAttrUseErr4(pctxt, 14194 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14195 WXS_ITEM_NODE(item), item, cur, 14196 "The 'optional' attribute use is inconsistent " 14197 "with the corresponding 'required' attribute use of " 14198 "the %s %s", 14199 WXS_ACTION_STR(action), 14200 xmlSchemaGetComponentDesignation(&str, baseItem), 14201 NULL, NULL); 14202 FREE_AND_NULL(str); 14203 /* err = pctxt->err; */ 14204 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14205 WXS_ATTRUSE_TYPEDEF(cur), 14206 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14207 { 14208 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14209 14210 /* 14211 * SPEC (2.1.2) "R's {attribute declaration}'s 14212 * {type definition} must be validly derived from 14213 * B's {type definition} given the empty set as 14214 * defined in Type Derivation OK (Simple) ($3.14.6)." 14215 */ 14216 xmlSchemaPAttrUseErr4(pctxt, 14217 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14218 WXS_ITEM_NODE(item), item, cur, 14219 "The attribute declaration's %s " 14220 "is not validly derived from " 14221 "the corresponding %s of the " 14222 "attribute declaration in the %s %s", 14223 xmlSchemaGetComponentDesignation(&strA, 14224 WXS_ATTRUSE_TYPEDEF(cur)), 14225 xmlSchemaGetComponentDesignation(&strB, 14226 WXS_ATTRUSE_TYPEDEF(bcur)), 14227 WXS_ACTION_STR(action), 14228 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14229 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14230 FREE_AND_NULL(strA); 14231 FREE_AND_NULL(strB); 14232 FREE_AND_NULL(strC); 14233 /* err = pctxt->err; */ 14234 } else { 14235 /* 14236 * 2.1.3 [Definition:] Let the effective value 14237 * constraint of an attribute use be its {value 14238 * constraint}, if present, otherwise its {attribute 14239 * declaration}'s {value constraint} . 14240 */ 14241 xmlSchemaGetEffectiveValueConstraint(bcur, 14242 &effFixed, &bEffValue, NULL); 14243 /* 14244 * 2.1.3 ... one of the following must be true 14245 * 14246 * 2.1.3.1 B's `effective value constraint` is 14247 * `absent` or default. 14248 */ 14249 if ((bEffValue != NULL) && 14250 (effFixed == 1)) { 14251 const xmlChar *rEffValue = NULL; 14252 14253 xmlSchemaGetEffectiveValueConstraint(bcur, 14254 &effFixed, &rEffValue, NULL); 14255 /* 14256 * 2.1.3.2 R's `effective value constraint` is 14257 * fixed with the same string as B's. 14258 * MAYBE TODO: Compare the computed values. 14259 * Hmm, it says "same string" so 14260 * string-equality might really be sufficient. 14261 */ 14262 if ((effFixed == 0) || 14263 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14264 { 14265 xmlChar *str = NULL; 14266 14267 xmlSchemaPAttrUseErr4(pctxt, 14268 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14269 WXS_ITEM_NODE(item), item, cur, 14270 "The effective value constraint of the " 14271 "attribute use is inconsistent with " 14272 "its correspondent in the %s %s", 14273 WXS_ACTION_STR(action), 14274 xmlSchemaGetComponentDesignation(&str, 14275 baseItem), 14276 NULL, NULL); 14277 FREE_AND_NULL(str); 14278 /* err = pctxt->err; */ 14279 } 14280 } 14281 } 14282 break; 14283 } 14284 } 14285 not_found: 14286 if (!found) { 14287 /* 14288 * (2.2) "otherwise the {base type definition} must have an 14289 * {attribute wildcard} and the {target namespace} of the 14290 * R's {attribute declaration} must be `valid` with respect 14291 * to that wildcard, as defined in Wildcard allows Namespace 14292 * Name ($3.10.4)." 14293 */ 14294 if ((baseWild == NULL) || 14295 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14296 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14297 { 14298 xmlChar *str = NULL; 14299 14300 xmlSchemaPAttrUseErr4(pctxt, 14301 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14302 WXS_ITEM_NODE(item), item, cur, 14303 "Neither a matching attribute use, " 14304 "nor a matching wildcard exists in the %s %s", 14305 WXS_ACTION_STR(action), 14306 xmlSchemaGetComponentDesignation(&str, baseItem), 14307 NULL, NULL); 14308 FREE_AND_NULL(str); 14309 /* err = pctxt->err; */ 14310 } 14311 } 14312 } 14313 } 14314 /* 14315 * SPEC derivation-ok-restriction (3): 14316 * (3) "For each attribute use in the {attribute uses} of the {base type 14317 * definition} whose {required} is true, there must be an attribute 14318 * use with an {attribute declaration} with the same {name} and 14319 * {target namespace} as its {attribute declaration} in the {attribute 14320 * uses} of the complex type definition itself whose {required} is true. 14321 */ 14322 if (baseUses != NULL) { 14323 for (j = 0; j < baseUses->nbItems; j++) { 14324 bcur = baseUses->items[j]; 14325 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14326 continue; 14327 found = 0; 14328 if (uses != NULL) { 14329 for (i = 0; i < uses->nbItems; i++) { 14330 cur = uses->items[i]; 14331 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14332 WXS_ATTRUSE_DECL_NAME(bcur)) && 14333 (WXS_ATTRUSE_DECL_TNS(cur) == 14334 WXS_ATTRUSE_DECL_TNS(bcur))) { 14335 found = 1; 14336 break; 14337 } 14338 } 14339 } 14340 if (!found) { 14341 xmlChar *strA = NULL, *strB = NULL; 14342 14343 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14344 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14345 NULL, item, 14346 "A matching attribute use for the " 14347 "'required' %s of the %s %s is missing", 14348 xmlSchemaGetComponentDesignation(&strA, bcur), 14349 WXS_ACTION_STR(action), 14350 xmlSchemaGetComponentDesignation(&strB, baseItem), 14351 NULL); 14352 FREE_AND_NULL(strA); 14353 FREE_AND_NULL(strB); 14354 } 14355 } 14356 } 14357 /* 14358 * derivation-ok-restriction (4) 14359 */ 14360 if (wild != NULL) { 14361 /* 14362 * (4) "If there is an {attribute wildcard}, all of the 14363 * following must be true:" 14364 */ 14365 if (baseWild == NULL) { 14366 xmlChar *str = NULL; 14367 14368 /* 14369 * (4.1) "The {base type definition} must also have one." 14370 */ 14371 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14372 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14373 NULL, item, 14374 "The %s has an attribute wildcard, " 14375 "but the %s %s '%s' does not have one", 14376 WXS_ITEM_TYPE_NAME(item), 14377 WXS_ACTION_STR(action), 14378 WXS_ITEM_TYPE_NAME(baseItem), 14379 xmlSchemaGetComponentQName(&str, baseItem)); 14380 FREE_AND_NULL(str); 14381 return(pctxt->err); 14382 } else if ((baseWild->any == 0) && 14383 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14384 { 14385 xmlChar *str = NULL; 14386 /* 14387 * (4.2) "The complex type definition's {attribute wildcard}'s 14388 * {namespace constraint} must be a subset of the {base type 14389 * definition}'s {attribute wildcard}'s {namespace constraint}, 14390 * as defined by Wildcard Subset ($3.10.6)." 14391 */ 14392 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14393 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14394 NULL, item, 14395 "The attribute wildcard is not a valid " 14396 "subset of the wildcard in the %s %s '%s'", 14397 WXS_ACTION_STR(action), 14398 WXS_ITEM_TYPE_NAME(baseItem), 14399 xmlSchemaGetComponentQName(&str, baseItem), 14400 NULL); 14401 FREE_AND_NULL(str); 14402 return(pctxt->err); 14403 } 14404 /* 4.3 Unless the {base type definition} is the `ur-type 14405 * definition`, the complex type definition's {attribute 14406 * wildcard}'s {process contents} must be identical to or 14407 * stronger than the {base type definition}'s {attribute 14408 * wildcard}'s {process contents}, where strict is stronger 14409 * than lax is stronger than skip. 14410 */ 14411 if ((! WXS_IS_ANYTYPE(baseItem)) && 14412 (wild->processContents < baseWild->processContents)) { 14413 xmlChar *str = NULL; 14414 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14415 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14416 NULL, baseItem, 14417 "The {process contents} of the attribute wildcard is " 14418 "weaker than the one in the %s %s '%s'", 14419 WXS_ACTION_STR(action), 14420 WXS_ITEM_TYPE_NAME(baseItem), 14421 xmlSchemaGetComponentQName(&str, baseItem), 14422 NULL); 14423 FREE_AND_NULL(str) 14424 return(pctxt->err); 14425 } 14426 } 14427 return(0); 14428 } 14429 14430 14431 static int 14432 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14433 xmlSchemaBasicItemPtr item, 14434 xmlSchemaWildcardPtr *completeWild, 14435 xmlSchemaItemListPtr list, 14436 xmlSchemaItemListPtr prohibs); 14437 /** 14438 * xmlSchemaFixupTypeAttributeUses: 14439 * @ctxt: the schema parser context 14440 * @type: the complex type definition 14441 * 14442 * 14443 * Builds the wildcard and the attribute uses on the given complex type. 14444 * Returns -1 if an internal error occurs, 0 otherwise. 14445 * 14446 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14447 * strings, so recheck this if we start to hardcode some schemata, since 14448 * they might not be in the same dict. 14449 * NOTE: It is allowed to "extend" the xs:anyType type. 14450 */ 14451 static int 14452 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14453 xmlSchemaTypePtr type) 14454 { 14455 xmlSchemaTypePtr baseType = NULL; 14456 xmlSchemaAttributeUsePtr use; 14457 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14458 14459 if (type->baseType == NULL) { 14460 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14461 "no base type"); 14462 return (-1); 14463 } 14464 baseType = type->baseType; 14465 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14466 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14467 return(-1); 14468 14469 uses = type->attrUses; 14470 baseUses = baseType->attrUses; 14471 /* 14472 * Expand attribute group references. And build the 'complete' 14473 * wildcard, i.e. intersect multiple wildcards. 14474 * Move attribute prohibitions into a separate list. 14475 */ 14476 if (uses != NULL) { 14477 if (WXS_IS_RESTRICTION(type)) { 14478 /* 14479 * This one will transfer all attr. prohibitions 14480 * into pctxt->attrProhibs. 14481 */ 14482 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14483 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14484 pctxt->attrProhibs) == -1) 14485 { 14486 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14487 "failed to expand attributes"); 14488 } 14489 if (pctxt->attrProhibs->nbItems != 0) 14490 prohibs = pctxt->attrProhibs; 14491 } else { 14492 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14493 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14494 NULL) == -1) 14495 { 14496 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14497 "failed to expand attributes"); 14498 } 14499 } 14500 } 14501 /* 14502 * Inherit the attribute uses of the base type. 14503 */ 14504 if (baseUses != NULL) { 14505 int i, j; 14506 xmlSchemaAttributeUseProhibPtr pro; 14507 14508 if (WXS_IS_RESTRICTION(type)) { 14509 int usesCount; 14510 xmlSchemaAttributeUsePtr tmp; 14511 14512 if (uses != NULL) 14513 usesCount = uses->nbItems; 14514 else 14515 usesCount = 0; 14516 14517 /* Restriction. */ 14518 for (i = 0; i < baseUses->nbItems; i++) { 14519 use = baseUses->items[i]; 14520 if (prohibs) { 14521 /* 14522 * Filter out prohibited uses. 14523 */ 14524 for (j = 0; j < prohibs->nbItems; j++) { 14525 pro = prohibs->items[j]; 14526 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14527 (WXS_ATTRUSE_DECL_TNS(use) == 14528 pro->targetNamespace)) 14529 { 14530 goto inherit_next; 14531 } 14532 } 14533 } 14534 if (usesCount) { 14535 /* 14536 * Filter out existing uses. 14537 */ 14538 for (j = 0; j < usesCount; j++) { 14539 tmp = uses->items[j]; 14540 if ((WXS_ATTRUSE_DECL_NAME(use) == 14541 WXS_ATTRUSE_DECL_NAME(tmp)) && 14542 (WXS_ATTRUSE_DECL_TNS(use) == 14543 WXS_ATTRUSE_DECL_TNS(tmp))) 14544 { 14545 goto inherit_next; 14546 } 14547 } 14548 } 14549 if (uses == NULL) { 14550 type->attrUses = xmlSchemaItemListCreate(); 14551 if (type->attrUses == NULL) 14552 goto exit_failure; 14553 uses = type->attrUses; 14554 } 14555 xmlSchemaItemListAddSize(uses, 2, use); 14556 inherit_next: {} 14557 } 14558 } else { 14559 /* Extension. */ 14560 for (i = 0; i < baseUses->nbItems; i++) { 14561 use = baseUses->items[i]; 14562 if (uses == NULL) { 14563 type->attrUses = xmlSchemaItemListCreate(); 14564 if (type->attrUses == NULL) 14565 goto exit_failure; 14566 uses = type->attrUses; 14567 } 14568 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14569 } 14570 } 14571 } 14572 /* 14573 * Shrink attr. uses. 14574 */ 14575 if (uses) { 14576 if (uses->nbItems == 0) { 14577 xmlSchemaItemListFree(uses); 14578 type->attrUses = NULL; 14579 } 14580 /* 14581 * TODO: We could shrink the size of the array 14582 * to fit the actual number of items. 14583 */ 14584 } 14585 /* 14586 * Compute the complete wildcard. 14587 */ 14588 if (WXS_IS_EXTENSION(type)) { 14589 if (baseType->attributeWildcard != NULL) { 14590 /* 14591 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14592 * the appropriate case among the following:" 14593 */ 14594 if (type->attributeWildcard != NULL) { 14595 /* 14596 * Union the complete wildcard with the base wildcard. 14597 * SPEC {attribute wildcard} 14598 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14599 * and {annotation} are those of the `complete wildcard`, 14600 * and whose {namespace constraint} is the intensional union 14601 * of the {namespace constraint} of the `complete wildcard` 14602 * and of the `base wildcard`, as defined in Attribute 14603 * Wildcard Union ($3.10.6)." 14604 */ 14605 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14606 baseType->attributeWildcard) == -1) 14607 goto exit_failure; 14608 } else { 14609 /* 14610 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14611 * then the `base wildcard`." 14612 */ 14613 type->attributeWildcard = baseType->attributeWildcard; 14614 } 14615 } else { 14616 /* 14617 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14618 * `complete wildcard`" 14619 * NOOP 14620 */ 14621 } 14622 } else { 14623 /* 14624 * SPEC {attribute wildcard} 14625 * (3.1) "If the <restriction> alternative is chosen, then the 14626 * `complete wildcard`;" 14627 * NOOP 14628 */ 14629 } 14630 14631 return (0); 14632 14633 exit_failure: 14634 return(-1); 14635 } 14636 14637 /** 14638 * xmlSchemaTypeFinalContains: 14639 * @schema: the schema 14640 * @type: the type definition 14641 * @final: the final 14642 * 14643 * Evaluates if a type definition contains the given "final". 14644 * This does take "finalDefault" into account as well. 14645 * 14646 * Returns 1 if the type does containt the given "final", 14647 * 0 otherwise. 14648 */ 14649 static int 14650 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14651 { 14652 if (type == NULL) 14653 return (0); 14654 if (type->flags & final) 14655 return (1); 14656 else 14657 return (0); 14658 } 14659 14660 /** 14661 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14662 * @type: the Union Simple Type 14663 * 14664 * Returns a list of member types of @type if existing, 14665 * returns NULL otherwise. 14666 */ 14667 static xmlSchemaTypeLinkPtr 14668 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14669 { 14670 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14671 if (type->memberTypes != NULL) 14672 return (type->memberTypes); 14673 else 14674 type = type->baseType; 14675 } 14676 return (NULL); 14677 } 14678 14679 /** 14680 * xmlSchemaGetParticleTotalRangeMin: 14681 * @particle: the particle 14682 * 14683 * Schema Component Constraint: Effective Total Range 14684 * (all and sequence) + (choice) 14685 * 14686 * Returns the minimun Effective Total Range. 14687 */ 14688 static int 14689 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14690 { 14691 if ((particle->children == NULL) || 14692 (particle->minOccurs == 0)) 14693 return (0); 14694 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14695 int min = -1, cur; 14696 xmlSchemaParticlePtr part = 14697 (xmlSchemaParticlePtr) particle->children->children; 14698 14699 if (part == NULL) 14700 return (0); 14701 while (part != NULL) { 14702 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14703 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14704 cur = part->minOccurs; 14705 else 14706 cur = xmlSchemaGetParticleTotalRangeMin(part); 14707 if (cur == 0) 14708 return (0); 14709 if ((min > cur) || (min == -1)) 14710 min = cur; 14711 part = (xmlSchemaParticlePtr) part->next; 14712 } 14713 return (particle->minOccurs * min); 14714 } else { 14715 /* <all> and <sequence> */ 14716 int sum = 0; 14717 xmlSchemaParticlePtr part = 14718 (xmlSchemaParticlePtr) particle->children->children; 14719 14720 if (part == NULL) 14721 return (0); 14722 do { 14723 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14724 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14725 sum += part->minOccurs; 14726 else 14727 sum += xmlSchemaGetParticleTotalRangeMin(part); 14728 part = (xmlSchemaParticlePtr) part->next; 14729 } while (part != NULL); 14730 return (particle->minOccurs * sum); 14731 } 14732 } 14733 14734 #if 0 14735 /** 14736 * xmlSchemaGetParticleTotalRangeMax: 14737 * @particle: the particle 14738 * 14739 * Schema Component Constraint: Effective Total Range 14740 * (all and sequence) + (choice) 14741 * 14742 * Returns the maximum Effective Total Range. 14743 */ 14744 static int 14745 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14746 { 14747 if ((particle->children == NULL) || 14748 (particle->children->children == NULL)) 14749 return (0); 14750 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14751 int max = -1, cur; 14752 xmlSchemaParticlePtr part = 14753 (xmlSchemaParticlePtr) particle->children->children; 14754 14755 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14756 if (part->children == NULL) 14757 continue; 14758 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14759 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14760 cur = part->maxOccurs; 14761 else 14762 cur = xmlSchemaGetParticleTotalRangeMax(part); 14763 if (cur == UNBOUNDED) 14764 return (UNBOUNDED); 14765 if ((max < cur) || (max == -1)) 14766 max = cur; 14767 } 14768 /* TODO: Handle overflows? */ 14769 return (particle->maxOccurs * max); 14770 } else { 14771 /* <all> and <sequence> */ 14772 int sum = 0, cur; 14773 xmlSchemaParticlePtr part = 14774 (xmlSchemaParticlePtr) particle->children->children; 14775 14776 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14777 if (part->children == NULL) 14778 continue; 14779 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14780 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14781 cur = part->maxOccurs; 14782 else 14783 cur = xmlSchemaGetParticleTotalRangeMax(part); 14784 if (cur == UNBOUNDED) 14785 return (UNBOUNDED); 14786 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14787 return (UNBOUNDED); 14788 sum += cur; 14789 } 14790 /* TODO: Handle overflows? */ 14791 return (particle->maxOccurs * sum); 14792 } 14793 } 14794 #endif 14795 14796 /** 14797 * xmlSchemaIsParticleEmptiable: 14798 * @particle: the particle 14799 * 14800 * Schema Component Constraint: Particle Emptiable 14801 * Checks whether the given particle is emptiable. 14802 * 14803 * Returns 1 if emptiable, 0 otherwise. 14804 */ 14805 static int 14806 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14807 { 14808 /* 14809 * SPEC (1) "Its {min occurs} is 0." 14810 */ 14811 if ((particle == NULL) || (particle->minOccurs == 0) || 14812 (particle->children == NULL)) 14813 return (1); 14814 /* 14815 * SPEC (2) "Its {term} is a group and the minimum part of the 14816 * effective total range of that group, [...] is 0." 14817 */ 14818 if (WXS_IS_MODEL_GROUP(particle->children)) { 14819 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14820 return (1); 14821 } 14822 return (0); 14823 } 14824 14825 /** 14826 * xmlSchemaCheckCOSSTDerivedOK: 14827 * @actxt: a context 14828 * @type: the derived simple type definition 14829 * @baseType: the base type definition 14830 * @subset: the subset of ('restriction', ect.) 14831 * 14832 * Schema Component Constraint: 14833 * Type Derivation OK (Simple) (cos-st-derived-OK) 14834 * 14835 * Checks wheter @type can be validly 14836 * derived from @baseType. 14837 * 14838 * Returns 0 on success, an positive error code otherwise. 14839 */ 14840 static int 14841 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14842 xmlSchemaTypePtr type, 14843 xmlSchemaTypePtr baseType, 14844 int subset) 14845 { 14846 /* 14847 * 1 They are the same type definition. 14848 * TODO: The identy check might have to be more complex than this. 14849 */ 14850 if (type == baseType) 14851 return (0); 14852 /* 14853 * 2.1 restriction is not in the subset, or in the {final} 14854 * of its own {base type definition}; 14855 * 14856 * NOTE that this will be used also via "xsi:type". 14857 * 14858 * TODO: Revise this, it looks strange. How can the "type" 14859 * not be fixed or *in* fixing? 14860 */ 14861 if (WXS_IS_TYPE_NOT_FIXED(type)) 14862 if (xmlSchemaTypeFixup(type, actxt) == -1) 14863 return(-1); 14864 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14865 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14866 return(-1); 14867 if ((subset & SUBSET_RESTRICTION) || 14868 (xmlSchemaTypeFinalContains(type->baseType, 14869 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14870 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14871 } 14872 /* 2.2 */ 14873 if (type->baseType == baseType) { 14874 /* 14875 * 2.2.1 D's `base type definition` is B. 14876 */ 14877 return (0); 14878 } 14879 /* 14880 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14881 * and is validly derived from B given the subset, as defined by this 14882 * constraint. 14883 */ 14884 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14885 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14886 baseType, subset) == 0)) { 14887 return (0); 14888 } 14889 /* 14890 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14891 * definition`. 14892 */ 14893 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14894 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14895 return (0); 14896 } 14897 /* 14898 * 2.2.4 B's {variety} is union and D is validly derived from a type 14899 * definition in B's {member type definitions} given the subset, as 14900 * defined by this constraint. 14901 * 14902 * NOTE: This seems not to involve built-in types, since there is no 14903 * built-in Union Simple Type. 14904 */ 14905 if (WXS_IS_UNION(baseType)) { 14906 xmlSchemaTypeLinkPtr cur; 14907 14908 cur = baseType->memberTypes; 14909 while (cur != NULL) { 14910 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14911 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14912 return(-1); 14913 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14914 type, cur->type, subset) == 0) 14915 { 14916 /* 14917 * It just has to be validly derived from at least one 14918 * member-type. 14919 */ 14920 return (0); 14921 } 14922 cur = cur->next; 14923 } 14924 } 14925 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14926 } 14927 14928 /** 14929 * xmlSchemaCheckTypeDefCircularInternal: 14930 * @pctxt: the schema parser context 14931 * @ctxtType: the type definition 14932 * @ancestor: an ancestor of @ctxtType 14933 * 14934 * Checks st-props-correct (2) + ct-props-correct (3). 14935 * Circular type definitions are not allowed. 14936 * 14937 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14938 * circular, 0 otherwise. 14939 */ 14940 static int 14941 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14942 xmlSchemaTypePtr ctxtType, 14943 xmlSchemaTypePtr ancestor) 14944 { 14945 int ret; 14946 14947 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14948 return (0); 14949 14950 if (ctxtType == ancestor) { 14951 xmlSchemaPCustomErr(pctxt, 14952 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14953 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14954 "The definition is circular", NULL); 14955 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14956 } 14957 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14958 /* 14959 * Avoid inifinite recursion on circular types not yet checked. 14960 */ 14961 return (0); 14962 } 14963 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14964 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14965 ancestor->baseType); 14966 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14967 return (ret); 14968 } 14969 14970 /** 14971 * xmlSchemaCheckTypeDefCircular: 14972 * @item: the complex/simple type definition 14973 * @ctxt: the parser context 14974 * @name: the name 14975 * 14976 * Checks for circular type definitions. 14977 */ 14978 static void 14979 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14980 xmlSchemaParserCtxtPtr ctxt) 14981 { 14982 if ((item == NULL) || 14983 (item->type == XML_SCHEMA_TYPE_BASIC) || 14984 (item->baseType == NULL)) 14985 return; 14986 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14987 item->baseType); 14988 } 14989 14990 /* 14991 * Simple Type Definition Representation OK (src-simple-type) 4 14992 * 14993 * "4 Circular union type definition is disallowed. That is, if the 14994 * <union> alternative is chosen, there must not be any entries in the 14995 * memberTypes [attribute] at any depth which resolve to the component 14996 * corresponding to the <simpleType>." 14997 * 14998 * Note that this should work on the *representation* of a component, 14999 * thus assumes any union types in the member types not being yet 15000 * substituted. At this stage we need the variety of the types 15001 * to be already computed. 15002 */ 15003 static int 15004 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 15005 xmlSchemaTypePtr ctxType, 15006 xmlSchemaTypeLinkPtr members) 15007 { 15008 xmlSchemaTypeLinkPtr member; 15009 xmlSchemaTypePtr memberType; 15010 15011 member = members; 15012 while (member != NULL) { 15013 memberType = member->type; 15014 while ((memberType != NULL) && 15015 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 15016 if (memberType == ctxType) { 15017 xmlSchemaPCustomErr(pctxt, 15018 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 15019 WXS_BASIC_CAST ctxType, NULL, 15020 "The union type definition is circular", NULL); 15021 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 15022 } 15023 if ((WXS_IS_UNION(memberType)) && 15024 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 15025 { 15026 int res; 15027 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 15028 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 15029 ctxType, 15030 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 15031 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 15032 if (res != 0) 15033 return(res); 15034 } 15035 memberType = memberType->baseType; 15036 } 15037 member = member->next; 15038 } 15039 return(0); 15040 } 15041 15042 static int 15043 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15044 xmlSchemaTypePtr type) 15045 { 15046 if (! WXS_IS_UNION(type)) 15047 return(0); 15048 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15049 type->memberTypes)); 15050 } 15051 15052 /** 15053 * xmlSchemaResolveTypeReferences: 15054 * @item: the complex/simple type definition 15055 * @ctxt: the parser context 15056 * @name: the name 15057 * 15058 * Resolvese type definition references 15059 */ 15060 static void 15061 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15062 xmlSchemaParserCtxtPtr ctxt) 15063 { 15064 if (typeDef == NULL) 15065 return; 15066 15067 /* 15068 * Resolve the base type. 15069 */ 15070 if (typeDef->baseType == NULL) { 15071 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15072 typeDef->base, typeDef->baseNs); 15073 if (typeDef->baseType == NULL) { 15074 xmlSchemaPResCompAttrErr(ctxt, 15075 XML_SCHEMAP_SRC_RESOLVE, 15076 WXS_BASIC_CAST typeDef, typeDef->node, 15077 "base", typeDef->base, typeDef->baseNs, 15078 XML_SCHEMA_TYPE_SIMPLE, NULL); 15079 return; 15080 } 15081 } 15082 if (WXS_IS_SIMPLE(typeDef)) { 15083 if (WXS_IS_UNION(typeDef)) { 15084 /* 15085 * Resolve the memberTypes. 15086 */ 15087 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15088 return; 15089 } else if (WXS_IS_LIST(typeDef)) { 15090 /* 15091 * Resolve the itemType. 15092 */ 15093 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15094 15095 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15096 typeDef->base, typeDef->baseNs); 15097 15098 if ((typeDef->subtypes == NULL) || 15099 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15100 { 15101 typeDef->subtypes = NULL; 15102 xmlSchemaPResCompAttrErr(ctxt, 15103 XML_SCHEMAP_SRC_RESOLVE, 15104 WXS_BASIC_CAST typeDef, typeDef->node, 15105 "itemType", typeDef->base, typeDef->baseNs, 15106 XML_SCHEMA_TYPE_SIMPLE, NULL); 15107 } 15108 } 15109 return; 15110 } 15111 } 15112 /* 15113 * The ball of letters below means, that if we have a particle 15114 * which has a QName-helper component as its {term}, we want 15115 * to resolve it... 15116 */ 15117 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15118 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15119 XML_SCHEMA_TYPE_PARTICLE) && 15120 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15121 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15122 XML_SCHEMA_EXTRA_QNAMEREF)) 15123 { 15124 xmlSchemaQNameRefPtr ref = 15125 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15126 xmlSchemaModelGroupDefPtr groupDef; 15127 15128 /* 15129 * URGENT TODO: Test this. 15130 */ 15131 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15132 /* 15133 * Resolve the MG definition reference. 15134 */ 15135 groupDef = 15136 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15137 ref->itemType, ref->name, ref->targetNamespace); 15138 if (groupDef == NULL) { 15139 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15140 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15141 "ref", ref->name, ref->targetNamespace, ref->itemType, 15142 NULL); 15143 /* Remove the particle. */ 15144 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15145 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15146 /* Remove the particle. */ 15147 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15148 else { 15149 /* 15150 * Assign the MG definition's {model group} to the 15151 * particle's {term}. 15152 */ 15153 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15154 15155 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15156 /* 15157 * SPEC cos-all-limited (1.2) 15158 * "1.2 the {term} property of a particle with 15159 * {max occurs}=1 which is part of a pair which constitutes 15160 * the {content type} of a complex type definition." 15161 */ 15162 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15163 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15164 /* TODO: error code */ 15165 XML_SCHEMAP_COS_ALL_LIMITED, 15166 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15167 "The particle's {max occurs} must be 1, since the " 15168 "reference resolves to an 'all' model group", 15169 NULL, NULL); 15170 } 15171 } 15172 } 15173 } 15174 } 15175 15176 15177 15178 /** 15179 * xmlSchemaCheckSTPropsCorrect: 15180 * @ctxt: the schema parser context 15181 * @type: the simple type definition 15182 * 15183 * Checks st-props-correct. 15184 * 15185 * Returns 0 if the properties are correct, 15186 * if not, a positive error code and -1 on internal 15187 * errors. 15188 */ 15189 static int 15190 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15191 xmlSchemaTypePtr type) 15192 { 15193 xmlSchemaTypePtr baseType = type->baseType; 15194 xmlChar *str = NULL; 15195 15196 /* STATE: error funcs converted. */ 15197 /* 15198 * Schema Component Constraint: Simple Type Definition Properties Correct 15199 * 15200 * NOTE: This is somehow redundant, since we actually built a simple type 15201 * to have all the needed information; this acts as an self test. 15202 */ 15203 /* Base type: If the datatype has been `derived` by `restriction` 15204 * then the Simple Type Definition component from which it is `derived`, 15205 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15206 */ 15207 if (baseType == NULL) { 15208 /* 15209 * TODO: Think about: "modulo the impact of Missing 15210 * Sub-components ($5.3)." 15211 */ 15212 xmlSchemaPCustomErr(ctxt, 15213 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15214 WXS_BASIC_CAST type, NULL, 15215 "No base type existent", NULL); 15216 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15217 15218 } 15219 if (! WXS_IS_SIMPLE(baseType)) { 15220 xmlSchemaPCustomErr(ctxt, 15221 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15222 WXS_BASIC_CAST type, NULL, 15223 "The base type '%s' is not a simple type", 15224 xmlSchemaGetComponentQName(&str, baseType)); 15225 FREE_AND_NULL(str) 15226 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15227 } 15228 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15229 (WXS_IS_RESTRICTION(type) == 0) && 15230 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15231 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15232 xmlSchemaPCustomErr(ctxt, 15233 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15234 WXS_BASIC_CAST type, NULL, 15235 "A type, derived by list or union, must have " 15236 "the simple ur-type definition as base type, not '%s'", 15237 xmlSchemaGetComponentQName(&str, baseType)); 15238 FREE_AND_NULL(str) 15239 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15240 } 15241 /* 15242 * Variety: One of {atomic, list, union}. 15243 */ 15244 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15245 (! WXS_IS_LIST(type))) { 15246 xmlSchemaPCustomErr(ctxt, 15247 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15248 WXS_BASIC_CAST type, NULL, 15249 "The variety is absent", NULL); 15250 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15251 } 15252 /* TODO: Finish this. Hmm, is this finished? */ 15253 15254 /* 15255 * 3 The {final} of the {base type definition} must not contain restriction. 15256 */ 15257 if (xmlSchemaTypeFinalContains(baseType, 15258 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15259 xmlSchemaPCustomErr(ctxt, 15260 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15261 WXS_BASIC_CAST type, NULL, 15262 "The 'final' of its base type '%s' must not contain " 15263 "'restriction'", 15264 xmlSchemaGetComponentQName(&str, baseType)); 15265 FREE_AND_NULL(str) 15266 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15267 } 15268 15269 /* 15270 * 2 All simple type definitions must be derived ultimately from the `simple 15271 * ur-type definition` (so circular definitions are disallowed). That is, it 15272 * must be possible to reach a built-in primitive datatype or the `simple 15273 * ur-type definition` by repeatedly following the {base type definition}. 15274 * 15275 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15276 */ 15277 return (0); 15278 } 15279 15280 /** 15281 * xmlSchemaCheckCOSSTRestricts: 15282 * @ctxt: the schema parser context 15283 * @type: the simple type definition 15284 * 15285 * Schema Component Constraint: 15286 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15287 15288 * Checks if the given @type (simpleType) is derived validly by restriction. 15289 * STATUS: 15290 * 15291 * Returns -1 on internal errors, 0 if the type is validly derived, 15292 * a positive error code otherwise. 15293 */ 15294 static int 15295 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15296 xmlSchemaTypePtr type) 15297 { 15298 xmlChar *str = NULL; 15299 15300 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15301 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15302 "given type is not a user-derived simpleType"); 15303 return (-1); 15304 } 15305 15306 if (WXS_IS_ATOMIC(type)) { 15307 xmlSchemaTypePtr primitive; 15308 /* 15309 * 1.1 The {base type definition} must be an atomic simple 15310 * type definition or a built-in primitive datatype. 15311 */ 15312 if (! WXS_IS_ATOMIC(type->baseType)) { 15313 xmlSchemaPCustomErr(pctxt, 15314 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15315 WXS_BASIC_CAST type, NULL, 15316 "The base type '%s' is not an atomic simple type", 15317 xmlSchemaGetComponentQName(&str, type->baseType)); 15318 FREE_AND_NULL(str) 15319 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15320 } 15321 /* 1.2 The {final} of the {base type definition} must not contain 15322 * restriction. 15323 */ 15324 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15325 if (xmlSchemaTypeFinalContains(type->baseType, 15326 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15327 xmlSchemaPCustomErr(pctxt, 15328 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15329 WXS_BASIC_CAST type, NULL, 15330 "The final of its base type '%s' must not contain 'restriction'", 15331 xmlSchemaGetComponentQName(&str, type->baseType)); 15332 FREE_AND_NULL(str) 15333 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15334 } 15335 15336 /* 15337 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15338 * type definition}, as specified in the appropriate subsection of 3.2 15339 * Primitive datatypes. 15340 */ 15341 if (type->facets != NULL) { 15342 xmlSchemaFacetPtr facet; 15343 int ok = 1; 15344 15345 primitive = xmlSchemaGetPrimitiveType(type); 15346 if (primitive == NULL) { 15347 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15348 "failed to get primitive type"); 15349 return (-1); 15350 } 15351 facet = type->facets; 15352 do { 15353 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15354 ok = 0; 15355 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15356 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15357 type, primitive, facet); 15358 } 15359 facet = facet->next; 15360 } while (facet != NULL); 15361 if (ok == 0) 15362 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15363 } 15364 /* 15365 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15366 * of the {base type definition} (call this BF),then the DF's {value} 15367 * must be a valid restriction of BF's {value} as defined in 15368 * [XML Schemas: Datatypes]." 15369 * 15370 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15371 * xmlSchemaDeriveAndValidateFacets() 15372 */ 15373 } else if (WXS_IS_LIST(type)) { 15374 xmlSchemaTypePtr itemType = NULL; 15375 15376 itemType = type->subtypes; 15377 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15378 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15379 "failed to evaluate the item type"); 15380 return (-1); 15381 } 15382 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15383 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15384 /* 15385 * 2.1 The {item type definition} must have a {variety} of atomic or 15386 * union (in which case all the {member type definitions} 15387 * must be atomic). 15388 */ 15389 if ((! WXS_IS_ATOMIC(itemType)) && 15390 (! WXS_IS_UNION(itemType))) { 15391 xmlSchemaPCustomErr(pctxt, 15392 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15393 WXS_BASIC_CAST type, NULL, 15394 "The item type '%s' does not have a variety of atomic or union", 15395 xmlSchemaGetComponentQName(&str, itemType)); 15396 FREE_AND_NULL(str) 15397 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15398 } else if (WXS_IS_UNION(itemType)) { 15399 xmlSchemaTypeLinkPtr member; 15400 15401 member = itemType->memberTypes; 15402 while (member != NULL) { 15403 if (! WXS_IS_ATOMIC(member->type)) { 15404 xmlSchemaPCustomErr(pctxt, 15405 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15406 WXS_BASIC_CAST type, NULL, 15407 "The item type is a union type, but the " 15408 "member type '%s' of this item type is not atomic", 15409 xmlSchemaGetComponentQName(&str, member->type)); 15410 FREE_AND_NULL(str) 15411 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15412 } 15413 member = member->next; 15414 } 15415 } 15416 15417 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15418 xmlSchemaFacetPtr facet; 15419 /* 15420 * This is the case if we have: <simpleType><list .. 15421 */ 15422 /* 15423 * 2.3.1 15424 * 2.3.1.1 The {final} of the {item type definition} must not 15425 * contain list. 15426 */ 15427 if (xmlSchemaTypeFinalContains(itemType, 15428 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15429 xmlSchemaPCustomErr(pctxt, 15430 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15431 WXS_BASIC_CAST type, NULL, 15432 "The final of its item type '%s' must not contain 'list'", 15433 xmlSchemaGetComponentQName(&str, itemType)); 15434 FREE_AND_NULL(str) 15435 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15436 } 15437 /* 15438 * 2.3.1.2 The {facets} must only contain the whiteSpace 15439 * facet component. 15440 * OPTIMIZE TODO: the S4S already disallows any facet 15441 * to be specified. 15442 */ 15443 if (type->facets != NULL) { 15444 facet = type->facets; 15445 do { 15446 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15447 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15448 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15449 type, facet); 15450 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15451 } 15452 facet = facet->next; 15453 } while (facet != NULL); 15454 } 15455 /* 15456 * MAYBE TODO: (Hmm, not really) Datatypes states: 15457 * A `list` datatype can be `derived` from an `atomic` datatype 15458 * whose `lexical space` allows space (such as string or anyURI)or 15459 * a `union` datatype any of whose {member type definitions}'s 15460 * `lexical space` allows space. 15461 */ 15462 } else { 15463 /* 15464 * This is the case if we have: <simpleType><restriction ... 15465 * I.e. the variety of "list" is inherited. 15466 */ 15467 /* 15468 * 2.3.2 15469 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15470 */ 15471 if (! WXS_IS_LIST(type->baseType)) { 15472 xmlSchemaPCustomErr(pctxt, 15473 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15474 WXS_BASIC_CAST type, NULL, 15475 "The base type '%s' must be a list type", 15476 xmlSchemaGetComponentQName(&str, type->baseType)); 15477 FREE_AND_NULL(str) 15478 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15479 } 15480 /* 15481 * 2.3.2.2 The {final} of the {base type definition} must not 15482 * contain restriction. 15483 */ 15484 if (xmlSchemaTypeFinalContains(type->baseType, 15485 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15486 xmlSchemaPCustomErr(pctxt, 15487 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15488 WXS_BASIC_CAST type, NULL, 15489 "The 'final' of the base type '%s' must not contain 'restriction'", 15490 xmlSchemaGetComponentQName(&str, type->baseType)); 15491 FREE_AND_NULL(str) 15492 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15493 } 15494 /* 15495 * 2.3.2.3 The {item type definition} must be validly derived 15496 * from the {base type definition}'s {item type definition} given 15497 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15498 */ 15499 { 15500 xmlSchemaTypePtr baseItemType; 15501 15502 baseItemType = type->baseType->subtypes; 15503 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15504 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15505 "failed to eval the item type of a base type"); 15506 return (-1); 15507 } 15508 if ((itemType != baseItemType) && 15509 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15510 baseItemType, 0) != 0)) { 15511 xmlChar *strBIT = NULL, *strBT = NULL; 15512 xmlSchemaPCustomErrExt(pctxt, 15513 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15514 WXS_BASIC_CAST type, NULL, 15515 "The item type '%s' is not validly derived from " 15516 "the item type '%s' of the base type '%s'", 15517 xmlSchemaGetComponentQName(&str, itemType), 15518 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15519 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15520 15521 FREE_AND_NULL(str) 15522 FREE_AND_NULL(strBIT) 15523 FREE_AND_NULL(strBT) 15524 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15525 } 15526 } 15527 15528 if (type->facets != NULL) { 15529 xmlSchemaFacetPtr facet; 15530 int ok = 1; 15531 /* 15532 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15533 * and enumeration facet components are allowed among the {facets}. 15534 */ 15535 facet = type->facets; 15536 do { 15537 switch (facet->type) { 15538 case XML_SCHEMA_FACET_LENGTH: 15539 case XML_SCHEMA_FACET_MINLENGTH: 15540 case XML_SCHEMA_FACET_MAXLENGTH: 15541 case XML_SCHEMA_FACET_WHITESPACE: 15542 /* 15543 * TODO: 2.5.1.2 List datatypes 15544 * The value of `whiteSpace` is fixed to the value collapse. 15545 */ 15546 case XML_SCHEMA_FACET_PATTERN: 15547 case XML_SCHEMA_FACET_ENUMERATION: 15548 break; 15549 default: { 15550 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15551 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15552 type, facet); 15553 /* 15554 * We could return, but it's nicer to report all 15555 * invalid facets. 15556 */ 15557 ok = 0; 15558 } 15559 } 15560 facet = facet->next; 15561 } while (facet != NULL); 15562 if (ok == 0) 15563 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15564 /* 15565 * SPEC (2.3.2.5) (same as 1.3.2) 15566 * 15567 * NOTE (2.3.2.5) This is currently done in 15568 * xmlSchemaDeriveAndValidateFacets() 15569 */ 15570 } 15571 } 15572 } else if (WXS_IS_UNION(type)) { 15573 /* 15574 * 3.1 The {member type definitions} must all have {variety} of 15575 * atomic or list. 15576 */ 15577 xmlSchemaTypeLinkPtr member; 15578 15579 member = type->memberTypes; 15580 while (member != NULL) { 15581 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15582 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15583 15584 if ((! WXS_IS_ATOMIC(member->type)) && 15585 (! WXS_IS_LIST(member->type))) { 15586 xmlSchemaPCustomErr(pctxt, 15587 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15588 WXS_BASIC_CAST type, NULL, 15589 "The member type '%s' is neither an atomic, nor a list type", 15590 xmlSchemaGetComponentQName(&str, member->type)); 15591 FREE_AND_NULL(str) 15592 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15593 } 15594 member = member->next; 15595 } 15596 /* 15597 * 3.3.1 If the {base type definition} is the `simple ur-type 15598 * definition` 15599 */ 15600 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15601 /* 15602 * 3.3.1.1 All of the {member type definitions} must have a 15603 * {final} which does not contain union. 15604 */ 15605 member = type->memberTypes; 15606 while (member != NULL) { 15607 if (xmlSchemaTypeFinalContains(member->type, 15608 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15609 xmlSchemaPCustomErr(pctxt, 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15611 WXS_BASIC_CAST type, NULL, 15612 "The 'final' of member type '%s' contains 'union'", 15613 xmlSchemaGetComponentQName(&str, member->type)); 15614 FREE_AND_NULL(str) 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15616 } 15617 member = member->next; 15618 } 15619 /* 15620 * 3.3.1.2 The {facets} must be empty. 15621 */ 15622 if (type->facetSet != NULL) { 15623 xmlSchemaPCustomErr(pctxt, 15624 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15625 WXS_BASIC_CAST type, NULL, 15626 "No facets allowed", NULL); 15627 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15628 } 15629 } else { 15630 /* 15631 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15632 * I.e. the variety of "list" is inherited. 15633 */ 15634 if (! WXS_IS_UNION(type->baseType)) { 15635 xmlSchemaPCustomErr(pctxt, 15636 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15637 WXS_BASIC_CAST type, NULL, 15638 "The base type '%s' is not a union type", 15639 xmlSchemaGetComponentQName(&str, type->baseType)); 15640 FREE_AND_NULL(str) 15641 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15642 } 15643 /* 15644 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15645 */ 15646 if (xmlSchemaTypeFinalContains(type->baseType, 15647 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15648 xmlSchemaPCustomErr(pctxt, 15649 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15650 WXS_BASIC_CAST type, NULL, 15651 "The 'final' of its base type '%s' must not contain 'restriction'", 15652 xmlSchemaGetComponentQName(&str, type->baseType)); 15653 FREE_AND_NULL(str) 15654 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15655 } 15656 /* 15657 * 3.3.2.3 The {member type definitions}, in order, must be validly 15658 * derived from the corresponding type definitions in the {base 15659 * type definition}'s {member type definitions} given the empty set, 15660 * as defined in Type Derivation OK (Simple) ($3.14.6). 15661 */ 15662 { 15663 xmlSchemaTypeLinkPtr baseMember; 15664 15665 /* 15666 * OPTIMIZE: if the type is restricting, it has no local defined 15667 * member types and inherits the member types of the base type; 15668 * thus a check for equality can be skipped. 15669 */ 15670 /* 15671 * Even worse: I cannot see a scenario where a restricting 15672 * union simple type can have other member types as the member 15673 * types of it's base type. This check seems not necessary with 15674 * respect to the derivation process in libxml2. 15675 * But necessary if constructing types with an API. 15676 */ 15677 if (type->memberTypes != NULL) { 15678 member = type->memberTypes; 15679 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15680 if ((member == NULL) && (baseMember != NULL)) { 15681 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15682 "different number of member types in base"); 15683 } 15684 while (member != NULL) { 15685 if (baseMember == NULL) { 15686 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15687 "different number of member types in base"); 15688 } else if ((member->type != baseMember->type) && 15689 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15690 member->type, baseMember->type, 0) != 0)) { 15691 xmlChar *strBMT = NULL, *strBT = NULL; 15692 15693 xmlSchemaPCustomErrExt(pctxt, 15694 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15695 WXS_BASIC_CAST type, NULL, 15696 "The member type %s is not validly " 15697 "derived from its corresponding member " 15698 "type %s of the base type %s", 15699 xmlSchemaGetComponentQName(&str, member->type), 15700 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15701 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15702 FREE_AND_NULL(str) 15703 FREE_AND_NULL(strBMT) 15704 FREE_AND_NULL(strBT) 15705 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15706 } 15707 member = member->next; 15708 if (baseMember != NULL) 15709 baseMember = baseMember->next; 15710 } 15711 } 15712 } 15713 /* 15714 * 3.3.2.4 Only pattern and enumeration facet components are 15715 * allowed among the {facets}. 15716 */ 15717 if (type->facets != NULL) { 15718 xmlSchemaFacetPtr facet; 15719 int ok = 1; 15720 15721 facet = type->facets; 15722 do { 15723 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15724 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15725 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15726 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15727 type, facet); 15728 ok = 0; 15729 } 15730 facet = facet->next; 15731 } while (facet != NULL); 15732 if (ok == 0) 15733 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15734 15735 } 15736 /* 15737 * SPEC (3.3.2.5) (same as 1.3.2) 15738 * 15739 * NOTE (3.3.2.5) This is currently done in 15740 * xmlSchemaDeriveAndValidateFacets() 15741 */ 15742 } 15743 } 15744 15745 return (0); 15746 } 15747 15748 /** 15749 * xmlSchemaCheckSRCSimpleType: 15750 * @ctxt: the schema parser context 15751 * @type: the simple type definition 15752 * 15753 * Checks crc-simple-type constraints. 15754 * 15755 * Returns 0 if the constraints are satisfied, 15756 * if not a positive error code and -1 on internal 15757 * errors. 15758 */ 15759 #if 0 15760 static int 15761 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15762 xmlSchemaTypePtr type) 15763 { 15764 /* 15765 * src-simple-type.1 The corresponding simple type definition, if any, 15766 * must satisfy the conditions set out in Constraints on Simple Type 15767 * Definition Schema Components ($3.14.6). 15768 */ 15769 if (WXS_IS_RESTRICTION(type)) { 15770 /* 15771 * src-simple-type.2 "If the <restriction> alternative is chosen, 15772 * either it must have a base [attribute] or a <simpleType> among its 15773 * [children], but not both." 15774 * NOTE: This is checked in the parse function of <restriction>. 15775 */ 15776 /* 15777 * 15778 */ 15779 } else if (WXS_IS_LIST(type)) { 15780 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15781 * an itemType [attribute] or a <simpleType> among its [children], 15782 * but not both." 15783 * 15784 * NOTE: This is checked in the parse function of <list>. 15785 */ 15786 } else if (WXS_IS_UNION(type)) { 15787 /* 15788 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15789 */ 15790 } 15791 return (0); 15792 } 15793 #endif 15794 15795 static int 15796 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15797 { 15798 if (ctxt->vctxt == NULL) { 15799 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15800 if (ctxt->vctxt == NULL) { 15801 xmlSchemaPErr(ctxt, NULL, 15802 XML_SCHEMAP_INTERNAL, 15803 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15804 "failed to create a temp. validation context.\n", 15805 NULL, NULL); 15806 return (-1); 15807 } 15808 /* TODO: Pass user data. */ 15809 xmlSchemaSetValidErrors(ctxt->vctxt, 15810 ctxt->error, ctxt->warning, ctxt->errCtxt); 15811 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15812 ctxt->serror, ctxt->errCtxt); 15813 } 15814 return (0); 15815 } 15816 15817 static int 15818 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15819 xmlNodePtr node, 15820 xmlSchemaTypePtr type, 15821 const xmlChar *value, 15822 xmlSchemaValPtr *retVal, 15823 int fireErrors, 15824 int normalize, 15825 int isNormalized); 15826 15827 /** 15828 * xmlSchemaParseCheckCOSValidDefault: 15829 * @pctxt: the schema parser context 15830 * @type: the simple type definition 15831 * @value: the default value 15832 * @node: an optional node (the holder of the value) 15833 * 15834 * Schema Component Constraint: Element Default Valid (Immediate) 15835 * (cos-valid-default) 15836 * This will be used by the parser only. For the validator there's 15837 * an other version. 15838 * 15839 * Returns 0 if the constraints are satisfied, 15840 * if not, a positive error code and -1 on internal 15841 * errors. 15842 */ 15843 static int 15844 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15845 xmlNodePtr node, 15846 xmlSchemaTypePtr type, 15847 const xmlChar *value, 15848 xmlSchemaValPtr *val) 15849 { 15850 int ret = 0; 15851 15852 /* 15853 * cos-valid-default: 15854 * Schema Component Constraint: Element Default Valid (Immediate) 15855 * For a string to be a valid default with respect to a type 15856 * definition the appropriate case among the following must be true: 15857 */ 15858 if WXS_IS_COMPLEX(type) { 15859 /* 15860 * Complex type. 15861 * 15862 * SPEC (2.1) "its {content type} must be a simple type definition 15863 * or mixed." 15864 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15865 * type}'s particle must be `emptiable` as defined by 15866 * Particle Emptiable ($3.9.6)." 15867 */ 15868 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15869 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15870 /* NOTE that this covers (2.2.2) as well. */ 15871 xmlSchemaPCustomErr(pctxt, 15872 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15873 WXS_BASIC_CAST type, type->node, 15874 "For a string to be a valid default, the type definition " 15875 "must be a simple type or a complex type with mixed content " 15876 "and a particle emptiable", NULL); 15877 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15878 } 15879 } 15880 /* 15881 * 1 If the type definition is a simple type definition, then the string 15882 * must be `valid` with respect to that definition as defined by String 15883 * Valid ($3.14.4). 15884 * 15885 * AND 15886 * 15887 * 2.2.1 If the {content type} is a simple type definition, then the 15888 * string must be `valid` with respect to that simple type definition 15889 * as defined by String Valid ($3.14.4). 15890 */ 15891 if (WXS_IS_SIMPLE(type)) 15892 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15893 type, value, val, 1, 1, 0); 15894 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15895 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15896 type->contentTypeDef, value, val, 1, 1, 0); 15897 else 15898 return (ret); 15899 15900 if (ret < 0) { 15901 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15902 "calling xmlSchemaVCheckCVCSimpleType()"); 15903 } 15904 15905 return (ret); 15906 } 15907 15908 /** 15909 * xmlSchemaCheckCTPropsCorrect: 15910 * @ctxt: the schema parser context 15911 * @type: the complex type definition 15912 * 15913 *.(4.6) Constraints on Complex Type Definition Schema Components 15914 * Schema Component Constraint: 15915 * Complex Type Definition Properties Correct (ct-props-correct) 15916 * STATUS: (seems) complete 15917 * 15918 * Returns 0 if the constraints are satisfied, a positive 15919 * error code if not and -1 if an internal error occurred. 15920 */ 15921 static int 15922 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15923 xmlSchemaTypePtr type) 15924 { 15925 /* 15926 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15927 * 15928 * SPEC (1) "The values of the properties of a complex type definition must 15929 * be as described in the property tableau in The Complex Type Definition 15930 * Schema Component ($3.4.1), modulo the impact of Missing 15931 * Sub-components ($5.3)." 15932 */ 15933 if ((type->baseType != NULL) && 15934 (WXS_IS_SIMPLE(type->baseType)) && 15935 (WXS_IS_EXTENSION(type) == 0)) { 15936 /* 15937 * SPEC (2) "If the {base type definition} is a simple type definition, 15938 * the {derivation method} must be extension." 15939 */ 15940 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15941 XML_SCHEMAP_SRC_CT_1, 15942 NULL, WXS_BASIC_CAST type, 15943 "If the base type is a simple type, the derivation method must be " 15944 "'extension'", NULL, NULL); 15945 return (XML_SCHEMAP_SRC_CT_1); 15946 } 15947 /* 15948 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15949 * definition`. That is, it must be possible to reach the `ur-type 15950 * definition` by repeatedly following the {base type definition}." 15951 * 15952 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15953 */ 15954 /* 15955 * NOTE that (4) and (5) need the following: 15956 * - attribute uses need to be already inherited (apply attr. prohibitions) 15957 * - attribute group references need to be expanded already 15958 * - simple types need to be typefixed already 15959 */ 15960 if (type->attrUses && 15961 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15962 { 15963 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15964 xmlSchemaAttributeUsePtr use, tmp; 15965 int i, j, hasId = 0; 15966 15967 for (i = uses->nbItems -1; i >= 0; i--) { 15968 use = uses->items[i]; 15969 15970 /* 15971 * SPEC ct-props-correct 15972 * (4) "Two distinct attribute declarations in the 15973 * {attribute uses} must not have identical {name}s and 15974 * {target namespace}s." 15975 */ 15976 if (i > 0) { 15977 for (j = i -1; j >= 0; j--) { 15978 tmp = uses->items[j]; 15979 if ((WXS_ATTRUSE_DECL_NAME(use) == 15980 WXS_ATTRUSE_DECL_NAME(tmp)) && 15981 (WXS_ATTRUSE_DECL_TNS(use) == 15982 WXS_ATTRUSE_DECL_TNS(tmp))) 15983 { 15984 xmlChar *str = NULL; 15985 15986 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15987 XML_SCHEMAP_AG_PROPS_CORRECT, 15988 NULL, WXS_BASIC_CAST type, 15989 "Duplicate %s", 15990 xmlSchemaGetComponentDesignation(&str, use), 15991 NULL); 15992 FREE_AND_NULL(str); 15993 /* 15994 * Remove the duplicate. 15995 */ 15996 if (xmlSchemaItemListRemove(uses, i) == -1) 15997 goto exit_failure; 15998 goto next_use; 15999 } 16000 } 16001 } 16002 /* 16003 * SPEC ct-props-correct 16004 * (5) "Two distinct attribute declarations in the 16005 * {attribute uses} must not have {type definition}s which 16006 * are or are derived from ID." 16007 */ 16008 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 16009 if (xmlSchemaIsDerivedFromBuiltInType( 16010 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 16011 { 16012 if (hasId) { 16013 xmlChar *str = NULL; 16014 16015 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16016 XML_SCHEMAP_AG_PROPS_CORRECT, 16017 NULL, WXS_BASIC_CAST type, 16018 "There must not exist more than one attribute " 16019 "declaration of type 'xs:ID' " 16020 "(or derived from 'xs:ID'). The %s violates this " 16021 "constraint", 16022 xmlSchemaGetComponentDesignation(&str, use), 16023 NULL); 16024 FREE_AND_NULL(str); 16025 if (xmlSchemaItemListRemove(uses, i) == -1) 16026 goto exit_failure; 16027 } 16028 16029 hasId = 1; 16030 } 16031 } 16032 next_use: {} 16033 } 16034 } 16035 return (0); 16036 exit_failure: 16037 return(-1); 16038 } 16039 16040 static int 16041 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16042 xmlSchemaTypePtr typeB) 16043 { 16044 /* 16045 * TODO: This should implement component-identity 16046 * in the future. 16047 */ 16048 if ((typeA == NULL) || (typeB == NULL)) 16049 return (0); 16050 return (typeA == typeB); 16051 } 16052 16053 /** 16054 * xmlSchemaCheckCOSCTDerivedOK: 16055 * @ctxt: the schema parser context 16056 * @type: the to-be derived complex type definition 16057 * @baseType: the base complex type definition 16058 * @set: the given set 16059 * 16060 * Schema Component Constraint: 16061 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16062 * 16063 * STATUS: completed 16064 * 16065 * Returns 0 if the constraints are satisfied, or 1 16066 * if not. 16067 */ 16068 static int 16069 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16070 xmlSchemaTypePtr type, 16071 xmlSchemaTypePtr baseType, 16072 int set) 16073 { 16074 int equal = xmlSchemaAreEqualTypes(type, baseType); 16075 /* TODO: Error codes. */ 16076 /* 16077 * SPEC "For a complex type definition (call it D, for derived) 16078 * to be validly derived from a type definition (call this 16079 * B, for base) given a subset of {extension, restriction} 16080 * all of the following must be true:" 16081 */ 16082 if (! equal) { 16083 /* 16084 * SPEC (1) "If B and D are not the same type definition, then the 16085 * {derivation method} of D must not be in the subset." 16086 */ 16087 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16088 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16089 return (1); 16090 } else { 16091 /* 16092 * SPEC (2.1) "B and D must be the same type definition." 16093 */ 16094 return (0); 16095 } 16096 /* 16097 * SPEC (2.2) "B must be D's {base type definition}." 16098 */ 16099 if (type->baseType == baseType) 16100 return (0); 16101 /* 16102 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16103 * definition`." 16104 */ 16105 if (WXS_IS_ANYTYPE(type->baseType)) 16106 return (1); 16107 16108 if (WXS_IS_COMPLEX(type->baseType)) { 16109 /* 16110 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16111 * must be validly derived from B given the subset as defined by this 16112 * constraint." 16113 */ 16114 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16115 baseType, set)); 16116 } else { 16117 /* 16118 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16119 * must be validly derived from B given the subset as defined in Type 16120 * Derivation OK (Simple) ($3.14.6). 16121 */ 16122 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16123 baseType, set)); 16124 } 16125 } 16126 16127 /** 16128 * xmlSchemaCheckCOSDerivedOK: 16129 * @type: the derived simple type definition 16130 * @baseType: the base type definition 16131 * 16132 * Calls: 16133 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16134 * 16135 * Checks wheter @type can be validly derived from @baseType. 16136 * 16137 * Returns 0 on success, an positive error code otherwise. 16138 */ 16139 static int 16140 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16141 xmlSchemaTypePtr type, 16142 xmlSchemaTypePtr baseType, 16143 int set) 16144 { 16145 if (WXS_IS_SIMPLE(type)) 16146 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16147 else 16148 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16149 } 16150 16151 /** 16152 * xmlSchemaCheckCOSCTExtends: 16153 * @ctxt: the schema parser context 16154 * @type: the complex type definition 16155 * 16156 * (3.4.6) Constraints on Complex Type Definition Schema Components 16157 * Schema Component Constraint: 16158 * Derivation Valid (Extension) (cos-ct-extends) 16159 * 16160 * STATUS: 16161 * missing: 16162 * (1.5) 16163 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16164 * 16165 * Returns 0 if the constraints are satisfied, a positive 16166 * error code if not and -1 if an internal error occurred. 16167 */ 16168 static int 16169 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16170 xmlSchemaTypePtr type) 16171 { 16172 xmlSchemaTypePtr base = type->baseType; 16173 /* 16174 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16175 * temporarily only. 16176 */ 16177 /* 16178 * SPEC (1) "If the {base type definition} is a complex type definition, 16179 * then all of the following must be true:" 16180 */ 16181 if (WXS_IS_COMPLEX(base)) { 16182 /* 16183 * SPEC (1.1) "The {final} of the {base type definition} must not 16184 * contain extension." 16185 */ 16186 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16187 xmlSchemaPCustomErr(ctxt, 16188 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16189 WXS_BASIC_CAST type, NULL, 16190 "The 'final' of the base type definition " 16191 "contains 'extension'", NULL); 16192 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16193 } 16194 16195 /* 16196 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16197 * since they are automatically satisfied through the 16198 * inheriting mechanism. 16199 * Note that even if redefining components, the inheriting mechanism 16200 * is used. 16201 */ 16202 #if 0 16203 /* 16204 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16205 * uses} 16206 * of the complex type definition itself, that is, for every attribute 16207 * use in the {attribute uses} of the {base type definition}, there 16208 * must be an attribute use in the {attribute uses} of the complex 16209 * type definition itself whose {attribute declaration} has the same 16210 * {name}, {target namespace} and {type definition} as its attribute 16211 * declaration" 16212 */ 16213 if (base->attrUses != NULL) { 16214 int i, j, found; 16215 xmlSchemaAttributeUsePtr use, buse; 16216 16217 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16218 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16219 found = 0; 16220 if (type->attrUses != NULL) { 16221 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16222 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16223 { 16224 if ((WXS_ATTRUSE_DECL_NAME(use) == 16225 WXS_ATTRUSE_DECL_NAME(buse)) && 16226 (WXS_ATTRUSE_DECL_TNS(use) == 16227 WXS_ATTRUSE_DECL_TNS(buse)) && 16228 (WXS_ATTRUSE_TYPEDEF(use) == 16229 WXS_ATTRUSE_TYPEDEF(buse)) 16230 { 16231 found = 1; 16232 break; 16233 } 16234 } 16235 } 16236 if (! found) { 16237 xmlChar *str = NULL; 16238 16239 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16240 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16241 NULL, WXS_BASIC_CAST type, 16242 /* 16243 * TODO: The report does not indicate that also the 16244 * type needs to be the same. 16245 */ 16246 "This type is missing a matching correspondent " 16247 "for its {base type}'s %s in its {attribute uses}", 16248 xmlSchemaGetComponentDesignation(&str, 16249 buse->children), 16250 NULL); 16251 FREE_AND_NULL(str) 16252 } 16253 } 16254 } 16255 /* 16256 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16257 * definition must also have one, and the base type definition's 16258 * {attribute wildcard}'s {namespace constraint} must be a subset 16259 * of the complex type definition's {attribute wildcard}'s {namespace 16260 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16261 */ 16262 16263 /* 16264 * MAYBE TODO: Enable if ever needed. But this will be needed only 16265 * if created the type via a schema construction API. 16266 */ 16267 if (base->attributeWildcard != NULL) { 16268 if (type->attributeWilcard == NULL) { 16269 xmlChar *str = NULL; 16270 16271 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16272 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16273 NULL, type, 16274 "The base %s has an attribute wildcard, " 16275 "but this type is missing an attribute wildcard", 16276 xmlSchemaGetComponentDesignation(&str, base)); 16277 FREE_AND_NULL(str) 16278 16279 } else if (xmlSchemaCheckCOSNSSubset( 16280 base->attributeWildcard, type->attributeWildcard)) 16281 { 16282 xmlChar *str = NULL; 16283 16284 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16285 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16286 NULL, type, 16287 "The attribute wildcard is not a valid " 16288 "superset of the one in the base %s", 16289 xmlSchemaGetComponentDesignation(&str, base)); 16290 FREE_AND_NULL(str) 16291 } 16292 } 16293 #endif 16294 /* 16295 * SPEC (1.4) "One of the following must be true:" 16296 */ 16297 if ((type->contentTypeDef != NULL) && 16298 (type->contentTypeDef == base->contentTypeDef)) { 16299 /* 16300 * SPEC (1.4.1) "The {content type} of the {base type definition} 16301 * and the {content type} of the complex type definition itself 16302 * must be the same simple type definition" 16303 * PASS 16304 */ 16305 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16306 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16307 /* 16308 * SPEC (1.4.2) "The {content type} of both the {base type 16309 * definition} and the complex type definition itself must 16310 * be empty." 16311 * PASS 16312 */ 16313 } else { 16314 /* 16315 * SPEC (1.4.3) "All of the following must be true:" 16316 */ 16317 if (type->subtypes == NULL) { 16318 /* 16319 * SPEC 1.4.3.1 The {content type} of the complex type 16320 * definition itself must specify a particle. 16321 */ 16322 xmlSchemaPCustomErr(ctxt, 16323 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16324 WXS_BASIC_CAST type, NULL, 16325 "The content type must specify a particle", NULL); 16326 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16327 } 16328 /* 16329 * SPEC (1.4.3.2) "One of the following must be true:" 16330 */ 16331 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16332 /* 16333 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16334 * definition} must be empty. 16335 * PASS 16336 */ 16337 } else { 16338 /* 16339 * SPEC (1.4.3.2.2) "All of the following must be true:" 16340 */ 16341 if ((type->contentType != base->contentType) || 16342 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16343 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16344 /* 16345 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16346 * or both must be element-only." 16347 */ 16348 xmlSchemaPCustomErr(ctxt, 16349 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16350 WXS_BASIC_CAST type, NULL, 16351 "The content type of both, the type and its base " 16352 "type, must either 'mixed' or 'element-only'", NULL); 16353 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16354 } 16355 /* 16356 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16357 * complex type definition must be a `valid extension` 16358 * of the {base type definition}'s particle, as defined 16359 * in Particle Valid (Extension) ($3.9.6)." 16360 * 16361 * NOTE that we won't check "Particle Valid (Extension)", 16362 * since it is ensured by the derivation process in 16363 * xmlSchemaTypeFixup(). We need to implement this when heading 16364 * for a construction API 16365 * TODO: !! This is needed to be checked if redefining a type !! 16366 */ 16367 } 16368 /* 16369 * URGENT TODO (1.5) 16370 */ 16371 } 16372 } else { 16373 /* 16374 * SPEC (2) "If the {base type definition} is a simple type definition, 16375 * then all of the following must be true:" 16376 */ 16377 if (type->contentTypeDef != base) { 16378 /* 16379 * SPEC (2.1) "The {content type} must be the same simple type 16380 * definition." 16381 */ 16382 xmlSchemaPCustomErr(ctxt, 16383 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16384 WXS_BASIC_CAST type, NULL, 16385 "The content type must be the simple base type", NULL); 16386 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16387 } 16388 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16389 /* 16390 * SPEC (2.2) "The {final} of the {base type definition} must not 16391 * contain extension" 16392 * NOTE that this is the same as (1.1). 16393 */ 16394 xmlSchemaPCustomErr(ctxt, 16395 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16396 WXS_BASIC_CAST type, NULL, 16397 "The 'final' of the base type definition " 16398 "contains 'extension'", NULL); 16399 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16400 } 16401 } 16402 return (0); 16403 } 16404 16405 /** 16406 * xmlSchemaCheckDerivationOKRestriction: 16407 * @ctxt: the schema parser context 16408 * @type: the complex type definition 16409 * 16410 * (3.4.6) Constraints on Complex Type Definition Schema Components 16411 * Schema Component Constraint: 16412 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16413 * 16414 * STATUS: 16415 * missing: 16416 * (5.4.2) ??? 16417 * 16418 * ATTENTION: 16419 * In XML Schema 1.1 this will be: 16420 * Validation Rule: Checking complex type subsumption 16421 * 16422 * Returns 0 if the constraints are satisfied, a positive 16423 * error code if not and -1 if an internal error occurred. 16424 */ 16425 static int 16426 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16427 xmlSchemaTypePtr type) 16428 { 16429 xmlSchemaTypePtr base; 16430 16431 /* 16432 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16433 * temporarily only. 16434 */ 16435 base = type->baseType; 16436 if (! WXS_IS_COMPLEX(base)) { 16437 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16438 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16439 type->node, WXS_BASIC_CAST type, 16440 "The base type must be a complex type", NULL, NULL); 16441 return(ctxt->err); 16442 } 16443 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16444 /* 16445 * SPEC (1) "The {base type definition} must be a complex type 16446 * definition whose {final} does not contain restriction." 16447 */ 16448 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16449 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16450 type->node, WXS_BASIC_CAST type, 16451 "The 'final' of the base type definition " 16452 "contains 'restriction'", NULL, NULL); 16453 return (ctxt->err); 16454 } 16455 /* 16456 * SPEC (2), (3) and (4) 16457 * Those are handled in a separate function, since the 16458 * same constraints are needed for redefinition of 16459 * attribute groups as well. 16460 */ 16461 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16462 XML_SCHEMA_ACTION_DERIVE, 16463 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16464 type->attrUses, base->attrUses, 16465 type->attributeWildcard, 16466 base->attributeWildcard) == -1) 16467 { 16468 return(-1); 16469 } 16470 /* 16471 * SPEC (5) "One of the following must be true:" 16472 */ 16473 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16474 /* 16475 * SPEC (5.1) "The {base type definition} must be the 16476 * `ur-type definition`." 16477 * PASS 16478 */ 16479 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16480 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16481 /* 16482 * SPEC (5.2.1) "The {content type} of the complex type definition 16483 * must be a simple type definition" 16484 * 16485 * SPEC (5.2.2) "One of the following must be true:" 16486 */ 16487 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16488 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16489 { 16490 int err; 16491 /* 16492 * SPEC (5.2.2.1) "The {content type} of the {base type 16493 * definition} must be a simple type definition from which 16494 * the {content type} is validly derived given the empty 16495 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16496 * 16497 * ATTENTION TODO: This seems not needed if the type implicitely 16498 * derived from the base type. 16499 * 16500 */ 16501 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16502 type->contentTypeDef, base->contentTypeDef, 0); 16503 if (err != 0) { 16504 xmlChar *strA = NULL, *strB = NULL; 16505 16506 if (err == -1) 16507 return(-1); 16508 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16509 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16510 NULL, WXS_BASIC_CAST type, 16511 "The {content type} %s is not validly derived from the " 16512 "base type's {content type} %s", 16513 xmlSchemaGetComponentDesignation(&strA, 16514 type->contentTypeDef), 16515 xmlSchemaGetComponentDesignation(&strB, 16516 base->contentTypeDef)); 16517 FREE_AND_NULL(strA); 16518 FREE_AND_NULL(strB); 16519 return(ctxt->err); 16520 } 16521 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16522 (xmlSchemaIsParticleEmptiable( 16523 (xmlSchemaParticlePtr) base->subtypes))) { 16524 /* 16525 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16526 * and have a particle which is `emptiable` as defined in 16527 * Particle Emptiable ($3.9.6)." 16528 * PASS 16529 */ 16530 } else { 16531 xmlSchemaPCustomErr(ctxt, 16532 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16533 WXS_BASIC_CAST type, NULL, 16534 "The content type of the base type must be either " 16535 "a simple type or 'mixed' and an emptiable particle", NULL); 16536 return (ctxt->err); 16537 } 16538 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16539 /* 16540 * SPEC (5.3.1) "The {content type} of the complex type itself must 16541 * be empty" 16542 */ 16543 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16544 /* 16545 * SPEC (5.3.2.1) "The {content type} of the {base type 16546 * definition} must also be empty." 16547 * PASS 16548 */ 16549 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16550 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16551 xmlSchemaIsParticleEmptiable( 16552 (xmlSchemaParticlePtr) base->subtypes)) { 16553 /* 16554 * SPEC (5.3.2.2) "The {content type} of the {base type 16555 * definition} must be elementOnly or mixed and have a particle 16556 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16557 * PASS 16558 */ 16559 } else { 16560 xmlSchemaPCustomErr(ctxt, 16561 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16562 WXS_BASIC_CAST type, NULL, 16563 "The content type of the base type must be either " 16564 "empty or 'mixed' (or 'elements-only') and an emptiable " 16565 "particle", NULL); 16566 return (ctxt->err); 16567 } 16568 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16569 WXS_HAS_MIXED_CONTENT(type)) { 16570 /* 16571 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16572 * itself must be element-only" 16573 */ 16574 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16575 /* 16576 * SPEC (5.4.1.2) "The {content type} of the complex type 16577 * definition itself and of the {base type definition} must be 16578 * mixed" 16579 */ 16580 xmlSchemaPCustomErr(ctxt, 16581 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16582 WXS_BASIC_CAST type, NULL, 16583 "If the content type is 'mixed', then the content type of the " 16584 "base type must also be 'mixed'", NULL); 16585 return (ctxt->err); 16586 } 16587 /* 16588 * SPEC (5.4.2) "The particle of the complex type definition itself 16589 * must be a `valid restriction` of the particle of the {content 16590 * type} of the {base type definition} as defined in Particle Valid 16591 * (Restriction) ($3.9.6). 16592 * 16593 * URGENT TODO: (5.4.2) 16594 */ 16595 } else { 16596 xmlSchemaPCustomErr(ctxt, 16597 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16598 WXS_BASIC_CAST type, NULL, 16599 "The type is not a valid restriction of its base type", NULL); 16600 return (ctxt->err); 16601 } 16602 return (0); 16603 } 16604 16605 /** 16606 * xmlSchemaCheckCTComponent: 16607 * @ctxt: the schema parser context 16608 * @type: the complex type definition 16609 * 16610 * (3.4.6) Constraints on Complex Type Definition Schema Components 16611 * 16612 * Returns 0 if the constraints are satisfied, a positive 16613 * error code if not and -1 if an internal error occurred. 16614 */ 16615 static int 16616 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16617 xmlSchemaTypePtr type) 16618 { 16619 int ret; 16620 /* 16621 * Complex Type Definition Properties Correct 16622 */ 16623 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16624 if (ret != 0) 16625 return (ret); 16626 if (WXS_IS_EXTENSION(type)) 16627 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16628 else 16629 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16630 return (ret); 16631 } 16632 16633 /** 16634 * xmlSchemaCheckSRCCT: 16635 * @ctxt: the schema parser context 16636 * @type: the complex type definition 16637 * 16638 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16639 * Schema Representation Constraint: 16640 * Complex Type Definition Representation OK (src-ct) 16641 * 16642 * Returns 0 if the constraints are satisfied, a positive 16643 * error code if not and -1 if an internal error occurred. 16644 */ 16645 static int 16646 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16647 xmlSchemaTypePtr type) 16648 { 16649 xmlSchemaTypePtr base; 16650 int ret = 0; 16651 16652 /* 16653 * TODO: Adjust the error codes here, as I used 16654 * XML_SCHEMAP_SRC_CT_1 only yet. 16655 */ 16656 base = type->baseType; 16657 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16658 /* 16659 * 1 If the <complexContent> alternative is chosen, the type definition 16660 * `resolved` to by the `actual value` of the base [attribute] 16661 * must be a complex type definition; 16662 */ 16663 if (! WXS_IS_COMPLEX(base)) { 16664 xmlChar *str = NULL; 16665 xmlSchemaPCustomErr(ctxt, 16666 XML_SCHEMAP_SRC_CT_1, 16667 WXS_BASIC_CAST type, type->node, 16668 "If using <complexContent>, the base type is expected to be " 16669 "a complex type. The base type '%s' is a simple type", 16670 xmlSchemaFormatQName(&str, base->targetNamespace, 16671 base->name)); 16672 FREE_AND_NULL(str) 16673 return (XML_SCHEMAP_SRC_CT_1); 16674 } 16675 } else { 16676 /* 16677 * SPEC 16678 * 2 If the <simpleContent> alternative is chosen, all of the 16679 * following must be true: 16680 * 2.1 The type definition `resolved` to by the `actual value` of the 16681 * base [attribute] must be one of the following: 16682 */ 16683 if (WXS_IS_SIMPLE(base)) { 16684 if (WXS_IS_EXTENSION(type) == 0) { 16685 xmlChar *str = NULL; 16686 /* 16687 * 2.1.3 only if the <extension> alternative is also 16688 * chosen, a simple type definition. 16689 */ 16690 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16691 xmlSchemaPCustomErr(ctxt, 16692 XML_SCHEMAP_SRC_CT_1, 16693 WXS_BASIC_CAST type, NULL, 16694 "If using <simpleContent> and <restriction>, the base " 16695 "type must be a complex type. The base type '%s' is " 16696 "a simple type", 16697 xmlSchemaFormatQName(&str, base->targetNamespace, 16698 base->name)); 16699 FREE_AND_NULL(str) 16700 return (XML_SCHEMAP_SRC_CT_1); 16701 } 16702 } else { 16703 /* Base type is a complex type. */ 16704 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16705 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16706 /* 16707 * 2.1.1 a complex type definition whose {content type} is a 16708 * simple type definition; 16709 * PASS 16710 */ 16711 if (base->contentTypeDef == NULL) { 16712 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16713 WXS_BASIC_CAST type, NULL, 16714 "Internal error: xmlSchemaCheckSRCCT, " 16715 "'%s', base type has no content type", 16716 type->name); 16717 return (-1); 16718 } 16719 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16720 (WXS_IS_RESTRICTION(type))) { 16721 16722 /* 16723 * 2.1.2 only if the <restriction> alternative is also 16724 * chosen, a complex type definition whose {content type} 16725 * is mixed and a particle emptiable. 16726 */ 16727 if (! xmlSchemaIsParticleEmptiable( 16728 (xmlSchemaParticlePtr) base->subtypes)) { 16729 ret = XML_SCHEMAP_SRC_CT_1; 16730 } else 16731 /* 16732 * Attention: at this point the <simpleType> child is in 16733 * ->contentTypeDef (put there during parsing). 16734 */ 16735 if (type->contentTypeDef == NULL) { 16736 xmlChar *str = NULL; 16737 /* 16738 * 2.2 If clause 2.1.2 above is satisfied, then there 16739 * must be a <simpleType> among the [children] of 16740 * <restriction>. 16741 */ 16742 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16743 xmlSchemaPCustomErr(ctxt, 16744 XML_SCHEMAP_SRC_CT_1, 16745 WXS_BASIC_CAST type, NULL, 16746 "A <simpleType> is expected among the children " 16747 "of <restriction>, if <simpleContent> is used and " 16748 "the base type '%s' is a complex type", 16749 xmlSchemaFormatQName(&str, base->targetNamespace, 16750 base->name)); 16751 FREE_AND_NULL(str) 16752 return (XML_SCHEMAP_SRC_CT_1); 16753 } 16754 } else { 16755 ret = XML_SCHEMAP_SRC_CT_1; 16756 } 16757 } 16758 if (ret > 0) { 16759 xmlChar *str = NULL; 16760 if (WXS_IS_RESTRICTION(type)) { 16761 xmlSchemaPCustomErr(ctxt, 16762 XML_SCHEMAP_SRC_CT_1, 16763 WXS_BASIC_CAST type, NULL, 16764 "If <simpleContent> and <restriction> is used, the " 16765 "base type must be a simple type or a complex type with " 16766 "mixed content and particle emptiable. The base type " 16767 "'%s' is none of those", 16768 xmlSchemaFormatQName(&str, base->targetNamespace, 16769 base->name)); 16770 } else { 16771 xmlSchemaPCustomErr(ctxt, 16772 XML_SCHEMAP_SRC_CT_1, 16773 WXS_BASIC_CAST type, NULL, 16774 "If <simpleContent> and <extension> is used, the " 16775 "base type must be a simple type. The base type '%s' " 16776 "is a complex type", 16777 xmlSchemaFormatQName(&str, base->targetNamespace, 16778 base->name)); 16779 } 16780 FREE_AND_NULL(str) 16781 } 16782 } 16783 /* 16784 * SPEC (3) "The corresponding complex type definition component must 16785 * satisfy the conditions set out in Constraints on Complex Type 16786 * Definition Schema Components ($3.4.6);" 16787 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16788 */ 16789 /* 16790 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16791 * above for {attribute wildcard} is satisfied, the intensional 16792 * intersection must be expressible, as defined in Attribute Wildcard 16793 * Intersection ($3.10.6). 16794 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16795 */ 16796 return (ret); 16797 } 16798 16799 #ifdef ENABLE_PARTICLE_RESTRICTION 16800 /** 16801 * xmlSchemaCheckParticleRangeOK: 16802 * @ctxt: the schema parser context 16803 * @type: the complex type definition 16804 * 16805 * (3.9.6) Constraints on Particle Schema Components 16806 * Schema Component Constraint: 16807 * Occurrence Range OK (range-ok) 16808 * 16809 * STATUS: complete 16810 * 16811 * Returns 0 if the constraints are satisfied, a positive 16812 * error code if not and -1 if an internal error occurred. 16813 */ 16814 static int 16815 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16816 int bmin, int bmax) 16817 { 16818 if (rmin < bmin) 16819 return (1); 16820 if ((bmax != UNBOUNDED) && 16821 (rmax > bmax)) 16822 return (1); 16823 return (0); 16824 } 16825 16826 /** 16827 * xmlSchemaCheckRCaseNameAndTypeOK: 16828 * @ctxt: the schema parser context 16829 * @r: the restricting element declaration particle 16830 * @b: the base element declaration particle 16831 * 16832 * (3.9.6) Constraints on Particle Schema Components 16833 * Schema Component Constraint: 16834 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16835 * (rcase-NameAndTypeOK) 16836 * 16837 * STATUS: 16838 * MISSING (3.2.3) 16839 * CLARIFY: (3.2.2) 16840 * 16841 * Returns 0 if the constraints are satisfied, a positive 16842 * error code if not and -1 if an internal error occurred. 16843 */ 16844 static int 16845 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16846 xmlSchemaParticlePtr r, 16847 xmlSchemaParticlePtr b) 16848 { 16849 xmlSchemaElementPtr elemR, elemB; 16850 16851 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16852 elemR = (xmlSchemaElementPtr) r->children; 16853 elemB = (xmlSchemaElementPtr) b->children; 16854 /* 16855 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16856 * the same." 16857 */ 16858 if ((elemR != elemB) && 16859 ((! xmlStrEqual(elemR->name, elemB->name)) || 16860 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16861 return (1); 16862 /* 16863 * SPEC (2) "R's occurrence range is a valid restriction of B's 16864 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16865 */ 16866 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16867 b->minOccurs, b->maxOccurs) != 0) 16868 return (1); 16869 /* 16870 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16871 * {scope} are global." 16872 */ 16873 if (elemR == elemB) 16874 return (0); 16875 /* 16876 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16877 */ 16878 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16879 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16880 return (1); 16881 /* 16882 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16883 * or is not fixed, or R's declaration's {value constraint} is fixed 16884 * with the same value." 16885 */ 16886 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16887 ((elemR->value == NULL) || 16888 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16889 /* TODO: Equality of the initial value or normalized or canonical? */ 16890 (! xmlStrEqual(elemR->value, elemB->value)))) 16891 return (1); 16892 /* 16893 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16894 * definitions} is a subset of B's declaration's {identity-constraint 16895 * definitions}, if any." 16896 */ 16897 if (elemB->idcs != NULL) { 16898 /* TODO */ 16899 } 16900 /* 16901 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16902 * superset of B's declaration's {disallowed substitutions}." 16903 */ 16904 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16905 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16906 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16907 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16908 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16909 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16910 return (1); 16911 /* 16912 * SPEC (3.2.5) "R's {type definition} is validly derived given 16913 * {extension, list, union} from B's {type definition}" 16914 * 16915 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16916 * set, if the corresponding constraints handle "restriction" and 16917 * "extension" only? 16918 * 16919 */ 16920 { 16921 int set = 0; 16922 16923 set |= SUBSET_EXTENSION; 16924 set |= SUBSET_LIST; 16925 set |= SUBSET_UNION; 16926 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16927 elemB->subtypes, set) != 0) 16928 return (1); 16929 } 16930 return (0); 16931 } 16932 16933 /** 16934 * xmlSchemaCheckRCaseNSCompat: 16935 * @ctxt: the schema parser context 16936 * @r: the restricting element declaration particle 16937 * @b: the base wildcard particle 16938 * 16939 * (3.9.6) Constraints on Particle Schema Components 16940 * Schema Component Constraint: 16941 * Particle Derivation OK (Elt:Any -- NSCompat) 16942 * (rcase-NSCompat) 16943 * 16944 * STATUS: complete 16945 * 16946 * Returns 0 if the constraints are satisfied, a positive 16947 * error code if not and -1 if an internal error occurred. 16948 */ 16949 static int 16950 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16951 xmlSchemaParticlePtr r, 16952 xmlSchemaParticlePtr b) 16953 { 16954 /* TODO:Error codes (rcase-NSCompat). */ 16955 /* 16956 * SPEC "For an element declaration particle to be a `valid restriction` 16957 * of a wildcard particle all of the following must be true:" 16958 * 16959 * SPEC (1) "The element declaration's {target namespace} is `valid` 16960 * with respect to the wildcard's {namespace constraint} as defined by 16961 * Wildcard allows Namespace Name ($3.10.4)." 16962 */ 16963 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16964 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16965 return (1); 16966 /* 16967 * SPEC (2) "R's occurrence range is a valid restriction of B's 16968 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16969 */ 16970 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16971 b->minOccurs, b->maxOccurs) != 0) 16972 return (1); 16973 16974 return (0); 16975 } 16976 16977 /** 16978 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16979 * @ctxt: the schema parser context 16980 * @r: the restricting element declaration particle 16981 * @b: the base model group particle 16982 * 16983 * (3.9.6) Constraints on Particle Schema Components 16984 * Schema Component Constraint: 16985 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16986 * (rcase-RecurseAsIfGroup) 16987 * 16988 * STATUS: TODO 16989 * 16990 * Returns 0 if the constraints are satisfied, a positive 16991 * error code if not and -1 if an internal error occurred. 16992 */ 16993 static int 16994 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16995 xmlSchemaParticlePtr r, 16996 xmlSchemaParticlePtr b) 16997 { 16998 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16999 TODO 17000 return (0); 17001 } 17002 17003 /** 17004 * xmlSchemaCheckRCaseNSSubset: 17005 * @ctxt: the schema parser context 17006 * @r: the restricting wildcard particle 17007 * @b: the base wildcard particle 17008 * 17009 * (3.9.6) Constraints on Particle Schema Components 17010 * Schema Component Constraint: 17011 * Particle Derivation OK (Any:Any -- NSSubset) 17012 * (rcase-NSSubset) 17013 * 17014 * STATUS: complete 17015 * 17016 * Returns 0 if the constraints are satisfied, a positive 17017 * error code if not and -1 if an internal error occurred. 17018 */ 17019 static int 17020 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 17021 xmlSchemaParticlePtr r, 17022 xmlSchemaParticlePtr b, 17023 int isAnyTypeBase) 17024 { 17025 /* TODO: Error codes (rcase-NSSubset). */ 17026 /* 17027 * SPEC (1) "R's occurrence range is a valid restriction of B's 17028 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17029 */ 17030 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17031 b->minOccurs, b->maxOccurs)) 17032 return (1); 17033 /* 17034 * SPEC (2) "R's {namespace constraint} must be an intensional subset 17035 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 17036 */ 17037 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 17038 (xmlSchemaWildcardPtr) b->children)) 17039 return (1); 17040 /* 17041 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17042 * definition`, R's {process contents} must be identical to or stronger 17043 * than B's {process contents}, where strict is stronger than lax is 17044 * stronger than skip." 17045 */ 17046 if (! isAnyTypeBase) { 17047 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17048 ((xmlSchemaWildcardPtr) b->children)->processContents) 17049 return (1); 17050 } 17051 17052 return (0); 17053 } 17054 17055 /** 17056 * xmlSchemaCheckCOSParticleRestrict: 17057 * @ctxt: the schema parser context 17058 * @type: the complex type definition 17059 * 17060 * (3.9.6) Constraints on Particle Schema Components 17061 * Schema Component Constraint: 17062 * Particle Valid (Restriction) (cos-particle-restrict) 17063 * 17064 * STATUS: TODO 17065 * 17066 * Returns 0 if the constraints are satisfied, a positive 17067 * error code if not and -1 if an internal error occurred. 17068 */ 17069 static int 17070 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17071 xmlSchemaParticlePtr r, 17072 xmlSchemaParticlePtr b) 17073 { 17074 int ret = 0; 17075 17076 /*part = WXS_TYPE_PARTICLE(type); 17077 basePart = WXS_TYPE_PARTICLE(base); 17078 */ 17079 17080 TODO 17081 17082 /* 17083 * SPEC (1) "They are the same particle." 17084 */ 17085 if (r == b) 17086 return (0); 17087 17088 17089 return (0); 17090 } 17091 17092 #if 0 17093 /** 17094 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17095 * @ctxt: the schema parser context 17096 * @r: the model group particle 17097 * @b: the base wildcard particle 17098 * 17099 * (3.9.6) Constraints on Particle Schema Components 17100 * Schema Component Constraint: 17101 * Particle Derivation OK (All/Choice/Sequence:Any -- 17102 * NSRecurseCheckCardinality) 17103 * (rcase-NSRecurseCheckCardinality) 17104 * 17105 * STATUS: TODO: subst-groups 17106 * 17107 * Returns 0 if the constraints are satisfied, a positive 17108 * error code if not and -1 if an internal error occurred. 17109 */ 17110 static int 17111 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17112 xmlSchemaParticlePtr r, 17113 xmlSchemaParticlePtr b) 17114 { 17115 xmlSchemaParticlePtr part; 17116 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17117 if ((r->children == NULL) || (r->children->children == NULL)) 17118 return (-1); 17119 /* 17120 * SPEC "For a group particle to be a `valid restriction` of a 17121 * wildcard particle..." 17122 * 17123 * SPEC (1) "Every member of the {particles} of the group is a `valid 17124 * restriction` of the wildcard as defined by 17125 * Particle Valid (Restriction) ($3.9.6)." 17126 */ 17127 part = (xmlSchemaParticlePtr) r->children->children; 17128 do { 17129 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17130 return (1); 17131 part = (xmlSchemaParticlePtr) part->next; 17132 } while (part != NULL); 17133 /* 17134 * SPEC (2) "The effective total range of the group [...] is a 17135 * valid restriction of B's occurrence range as defined by 17136 * Occurrence Range OK ($3.9.6)." 17137 */ 17138 if (xmlSchemaCheckParticleRangeOK( 17139 xmlSchemaGetParticleTotalRangeMin(r), 17140 xmlSchemaGetParticleTotalRangeMax(r), 17141 b->minOccurs, b->maxOccurs) != 0) 17142 return (1); 17143 return (0); 17144 } 17145 #endif 17146 17147 /** 17148 * xmlSchemaCheckRCaseRecurse: 17149 * @ctxt: the schema parser context 17150 * @r: the <all> or <sequence> model group particle 17151 * @b: the base <all> or <sequence> model group particle 17152 * 17153 * (3.9.6) Constraints on Particle Schema Components 17154 * Schema Component Constraint: 17155 * Particle Derivation OK (All:All,Sequence:Sequence -- 17156 Recurse) 17157 * (rcase-Recurse) 17158 * 17159 * STATUS: ? 17160 * TODO: subst-groups 17161 * 17162 * Returns 0 if the constraints are satisfied, a positive 17163 * error code if not and -1 if an internal error occurred. 17164 */ 17165 static int 17166 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17167 xmlSchemaParticlePtr r, 17168 xmlSchemaParticlePtr b) 17169 { 17170 /* xmlSchemaParticlePtr part; */ 17171 /* TODO: Error codes (rcase-Recurse). */ 17172 if ((r->children == NULL) || (b->children == NULL) || 17173 (r->children->type != b->children->type)) 17174 return (-1); 17175 /* 17176 * SPEC "For an all or sequence group particle to be a `valid 17177 * restriction` of another group particle with the same {compositor}..." 17178 * 17179 * SPEC (1) "R's occurrence range is a valid restriction of B's 17180 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17181 */ 17182 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17183 b->minOccurs, b->maxOccurs)) 17184 return (1); 17185 17186 17187 return (0); 17188 } 17189 17190 #endif 17191 17192 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17193 xmlSchemaPCustomErrExt(pctxt, \ 17194 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17195 WXS_BASIC_CAST fac1, fac1->node, \ 17196 "It is an error for both '%s' and '%s' to be specified on the "\ 17197 "same type definition", \ 17198 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17199 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17200 17201 #define FACET_RESTR_ERR(fac1, msg) \ 17202 xmlSchemaPCustomErr(pctxt, \ 17203 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17204 WXS_BASIC_CAST fac1, fac1->node, \ 17205 msg, NULL); 17206 17207 #define FACET_RESTR_FIXED_ERR(fac) \ 17208 xmlSchemaPCustomErr(pctxt, \ 17209 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17210 WXS_BASIC_CAST fac, fac->node, \ 17211 "The base type's facet is 'fixed', thus the value must not " \ 17212 "differ", NULL); 17213 17214 static void 17215 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17216 xmlSchemaFacetPtr facet1, 17217 xmlSchemaFacetPtr facet2, 17218 int lessGreater, 17219 int orEqual, 17220 int ofBase) 17221 { 17222 xmlChar *msg = NULL; 17223 17224 msg = xmlStrdup(BAD_CAST "'"); 17225 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17226 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17227 if (lessGreater == 0) 17228 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17229 if (lessGreater == 1) 17230 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17231 else 17232 msg = xmlStrcat(msg, BAD_CAST " less than"); 17233 17234 if (orEqual) 17235 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17236 msg = xmlStrcat(msg, BAD_CAST " '"); 17237 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17238 if (ofBase) 17239 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17240 else 17241 msg = xmlStrcat(msg, BAD_CAST "'"); 17242 17243 xmlSchemaPCustomErr(pctxt, 17244 XML_SCHEMAP_INVALID_FACET_VALUE, 17245 WXS_BASIC_CAST facet1, NULL, 17246 (const char *) msg, NULL); 17247 17248 if (msg != NULL) 17249 xmlFree(msg); 17250 } 17251 17252 /* 17253 * xmlSchemaDeriveAndValidateFacets: 17254 * 17255 * Schema Component Constraint: Simple Type Restriction (Facets) 17256 * (st-restrict-facets) 17257 */ 17258 static int 17259 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17260 xmlSchemaTypePtr type) 17261 { 17262 xmlSchemaTypePtr base = type->baseType; 17263 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17264 xmlSchemaFacetPtr facet, bfacet, 17265 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17266 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17267 fmininc = NULL, fmaxinc = NULL, 17268 fminexc = NULL, fmaxexc = NULL, 17269 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17270 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17271 bfmininc = NULL, bfmaxinc = NULL, 17272 bfminexc = NULL, bfmaxexc = NULL; 17273 int res; /* err = 0, fixedErr; */ 17274 17275 /* 17276 * SPEC st-restrict-facets 1: 17277 * "The {variety} of R is the same as that of B." 17278 */ 17279 /* 17280 * SPEC st-restrict-facets 2: 17281 * "If {variety} is atomic, the {primitive type definition} 17282 * of R is the same as that of B." 17283 * 17284 * NOTE: we leave 1 & 2 out for now, since this will be 17285 * satisfied by the derivation process. 17286 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17287 */ 17288 /* 17289 * SPEC st-restrict-facets 3: 17290 * "The {facets} of R are the union of S and the {facets} 17291 * of B, eliminating duplicates. To eliminate duplicates, 17292 * when a facet of the same kind occurs in both S and the 17293 * {facets} of B, the one in the {facets} of B is not 17294 * included, with the exception of enumeration and pattern 17295 * facets, for which multiple occurrences with distinct values 17296 * are allowed." 17297 */ 17298 17299 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17300 return (0); 17301 17302 last = type->facetSet; 17303 if (last != NULL) 17304 while (last->next != NULL) 17305 last = last->next; 17306 17307 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17308 facet = cur->facet; 17309 switch (facet->type) { 17310 case XML_SCHEMA_FACET_LENGTH: 17311 flength = facet; break; 17312 case XML_SCHEMA_FACET_MINLENGTH: 17313 fminlen = facet; break; 17314 case XML_SCHEMA_FACET_MININCLUSIVE: 17315 fmininc = facet; break; 17316 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17317 fminexc = facet; break; 17318 case XML_SCHEMA_FACET_MAXLENGTH: 17319 fmaxlen = facet; break; 17320 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17321 fmaxinc = facet; break; 17322 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17323 fmaxexc = facet; break; 17324 case XML_SCHEMA_FACET_TOTALDIGITS: 17325 ftotdig = facet; break; 17326 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17327 ffracdig = facet; break; 17328 default: 17329 break; 17330 } 17331 } 17332 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17333 facet = cur->facet; 17334 switch (facet->type) { 17335 case XML_SCHEMA_FACET_LENGTH: 17336 bflength = facet; break; 17337 case XML_SCHEMA_FACET_MINLENGTH: 17338 bfminlen = facet; break; 17339 case XML_SCHEMA_FACET_MININCLUSIVE: 17340 bfmininc = facet; break; 17341 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17342 bfminexc = facet; break; 17343 case XML_SCHEMA_FACET_MAXLENGTH: 17344 bfmaxlen = facet; break; 17345 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17346 bfmaxinc = facet; break; 17347 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17348 bfmaxexc = facet; break; 17349 case XML_SCHEMA_FACET_TOTALDIGITS: 17350 bftotdig = facet; break; 17351 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17352 bffracdig = facet; break; 17353 default: 17354 break; 17355 } 17356 } 17357 /* 17358 * length and minLength or maxLength (2.2) + (3.2) 17359 */ 17360 if (flength && (fminlen || fmaxlen)) { 17361 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17362 "either of 'minLength' or 'maxLength' to be specified on " 17363 "the same type definition") 17364 } 17365 /* 17366 * Mutual exclusions in the same derivation step. 17367 */ 17368 if ((fmaxinc) && (fmaxexc)) { 17369 /* 17370 * SCC "maxInclusive and maxExclusive" 17371 */ 17372 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17373 } 17374 if ((fmininc) && (fminexc)) { 17375 /* 17376 * SCC "minInclusive and minExclusive" 17377 */ 17378 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17379 } 17380 17381 if (flength && bflength) { 17382 /* 17383 * SCC "length valid restriction" 17384 * The values have to be equal. 17385 */ 17386 res = xmlSchemaCompareValues(flength->val, bflength->val); 17387 if (res == -2) 17388 goto internal_error; 17389 if (res != 0) 17390 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17391 if ((res != 0) && (bflength->fixed)) { 17392 FACET_RESTR_FIXED_ERR(flength) 17393 } 17394 17395 } 17396 if (fminlen && bfminlen) { 17397 /* 17398 * SCC "minLength valid restriction" 17399 * minLength >= BASE minLength 17400 */ 17401 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17402 if (res == -2) 17403 goto internal_error; 17404 if (res == -1) 17405 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17406 if ((res != 0) && (bfminlen->fixed)) { 17407 FACET_RESTR_FIXED_ERR(fminlen) 17408 } 17409 } 17410 if (fmaxlen && bfmaxlen) { 17411 /* 17412 * SCC "maxLength valid restriction" 17413 * maxLength <= BASE minLength 17414 */ 17415 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17416 if (res == -2) 17417 goto internal_error; 17418 if (res == 1) 17419 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17420 if ((res != 0) && (bfmaxlen->fixed)) { 17421 FACET_RESTR_FIXED_ERR(fmaxlen) 17422 } 17423 } 17424 /* 17425 * SCC "length and minLength or maxLength" 17426 */ 17427 if (! flength) 17428 flength = bflength; 17429 if (flength) { 17430 if (! fminlen) 17431 fminlen = bfminlen; 17432 if (fminlen) { 17433 /* (1.1) length >= minLength */ 17434 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17435 if (res == -2) 17436 goto internal_error; 17437 if (res == -1) 17438 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17439 } 17440 if (! fmaxlen) 17441 fmaxlen = bfmaxlen; 17442 if (fmaxlen) { 17443 /* (2.1) length <= maxLength */ 17444 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17445 if (res == -2) 17446 goto internal_error; 17447 if (res == 1) 17448 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17449 } 17450 } 17451 if (fmaxinc) { 17452 /* 17453 * "maxInclusive" 17454 */ 17455 if (fmininc) { 17456 /* SCC "maxInclusive >= minInclusive" */ 17457 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17458 if (res == -2) 17459 goto internal_error; 17460 if (res == -1) { 17461 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17462 } 17463 } 17464 /* 17465 * SCC "maxInclusive valid restriction" 17466 */ 17467 if (bfmaxinc) { 17468 /* maxInclusive <= BASE maxInclusive */ 17469 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17470 if (res == -2) 17471 goto internal_error; 17472 if (res == 1) 17473 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17474 if ((res != 0) && (bfmaxinc->fixed)) { 17475 FACET_RESTR_FIXED_ERR(fmaxinc) 17476 } 17477 } 17478 if (bfmaxexc) { 17479 /* maxInclusive < BASE maxExclusive */ 17480 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17481 if (res == -2) 17482 goto internal_error; 17483 if (res != -1) { 17484 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17485 } 17486 } 17487 if (bfmininc) { 17488 /* maxInclusive >= BASE minInclusive */ 17489 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17490 if (res == -2) 17491 goto internal_error; 17492 if (res == -1) { 17493 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17494 } 17495 } 17496 if (bfminexc) { 17497 /* maxInclusive > BASE minExclusive */ 17498 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17499 if (res == -2) 17500 goto internal_error; 17501 if (res != 1) { 17502 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17503 } 17504 } 17505 } 17506 if (fmaxexc) { 17507 /* 17508 * "maxExclusive >= minExclusive" 17509 */ 17510 if (fminexc) { 17511 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17512 if (res == -2) 17513 goto internal_error; 17514 if (res == -1) { 17515 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17516 } 17517 } 17518 /* 17519 * "maxExclusive valid restriction" 17520 */ 17521 if (bfmaxexc) { 17522 /* maxExclusive <= BASE maxExclusive */ 17523 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17524 if (res == -2) 17525 goto internal_error; 17526 if (res == 1) { 17527 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17528 } 17529 if ((res != 0) && (bfmaxexc->fixed)) { 17530 FACET_RESTR_FIXED_ERR(fmaxexc) 17531 } 17532 } 17533 if (bfmaxinc) { 17534 /* maxExclusive <= BASE maxInclusive */ 17535 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17536 if (res == -2) 17537 goto internal_error; 17538 if (res == 1) { 17539 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17540 } 17541 } 17542 if (bfmininc) { 17543 /* maxExclusive > BASE minInclusive */ 17544 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17545 if (res == -2) 17546 goto internal_error; 17547 if (res != 1) { 17548 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17549 } 17550 } 17551 if (bfminexc) { 17552 /* maxExclusive > BASE minExclusive */ 17553 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17554 if (res == -2) 17555 goto internal_error; 17556 if (res != 1) { 17557 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17558 } 17559 } 17560 } 17561 if (fminexc) { 17562 /* 17563 * "minExclusive < maxInclusive" 17564 */ 17565 if (fmaxinc) { 17566 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17567 if (res == -2) 17568 goto internal_error; 17569 if (res != -1) { 17570 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17571 } 17572 } 17573 /* 17574 * "minExclusive valid restriction" 17575 */ 17576 if (bfminexc) { 17577 /* minExclusive >= BASE minExclusive */ 17578 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17579 if (res == -2) 17580 goto internal_error; 17581 if (res == -1) { 17582 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17583 } 17584 if ((res != 0) && (bfminexc->fixed)) { 17585 FACET_RESTR_FIXED_ERR(fminexc) 17586 } 17587 } 17588 if (bfmaxinc) { 17589 /* minExclusive <= BASE maxInclusive */ 17590 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17591 if (res == -2) 17592 goto internal_error; 17593 if (res == 1) { 17594 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17595 } 17596 } 17597 if (bfmininc) { 17598 /* minExclusive >= BASE minInclusive */ 17599 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17600 if (res == -2) 17601 goto internal_error; 17602 if (res == -1) { 17603 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17604 } 17605 } 17606 if (bfmaxexc) { 17607 /* minExclusive < BASE maxExclusive */ 17608 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17609 if (res == -2) 17610 goto internal_error; 17611 if (res != -1) { 17612 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17613 } 17614 } 17615 } 17616 if (fmininc) { 17617 /* 17618 * "minInclusive < maxExclusive" 17619 */ 17620 if (fmaxexc) { 17621 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17622 if (res == -2) 17623 goto internal_error; 17624 if (res != -1) { 17625 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17626 } 17627 } 17628 /* 17629 * "minExclusive valid restriction" 17630 */ 17631 if (bfmininc) { 17632 /* minInclusive >= BASE minInclusive */ 17633 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17634 if (res == -2) 17635 goto internal_error; 17636 if (res == -1) { 17637 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17638 } 17639 if ((res != 0) && (bfmininc->fixed)) { 17640 FACET_RESTR_FIXED_ERR(fmininc) 17641 } 17642 } 17643 if (bfmaxinc) { 17644 /* minInclusive <= BASE maxInclusive */ 17645 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17646 if (res == -2) 17647 goto internal_error; 17648 if (res == 1) { 17649 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17650 } 17651 } 17652 if (bfminexc) { 17653 /* minInclusive > BASE minExclusive */ 17654 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17655 if (res == -2) 17656 goto internal_error; 17657 if (res != 1) 17658 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17659 } 17660 if (bfmaxexc) { 17661 /* minInclusive < BASE maxExclusive */ 17662 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17663 if (res == -2) 17664 goto internal_error; 17665 if (res != -1) 17666 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17667 } 17668 } 17669 if (ftotdig && bftotdig) { 17670 /* 17671 * SCC " totalDigits valid restriction" 17672 * totalDigits <= BASE totalDigits 17673 */ 17674 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17675 if (res == -2) 17676 goto internal_error; 17677 if (res == 1) 17678 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17679 -1, 1, 1); 17680 if ((res != 0) && (bftotdig->fixed)) { 17681 FACET_RESTR_FIXED_ERR(ftotdig) 17682 } 17683 } 17684 if (ffracdig && bffracdig) { 17685 /* 17686 * SCC "fractionDigits valid restriction" 17687 * fractionDigits <= BASE fractionDigits 17688 */ 17689 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17690 if (res == -2) 17691 goto internal_error; 17692 if (res == 1) 17693 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17694 -1, 1, 1); 17695 if ((res != 0) && (bffracdig->fixed)) { 17696 FACET_RESTR_FIXED_ERR(ffracdig) 17697 } 17698 } 17699 /* 17700 * SCC "fractionDigits less than or equal to totalDigits" 17701 */ 17702 if (! ftotdig) 17703 ftotdig = bftotdig; 17704 if (! ffracdig) 17705 ffracdig = bffracdig; 17706 if (ftotdig && ffracdig) { 17707 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17708 if (res == -2) 17709 goto internal_error; 17710 if (res == 1) 17711 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17712 -1, 1, 0); 17713 } 17714 /* 17715 * *Enumerations* won' be added here, since only the first set 17716 * of enumerations in the ancestor-or-self axis is used 17717 * for validation, plus we need to use the base type of those 17718 * enumerations for whitespace. 17719 * 17720 * *Patterns*: won't be add here, since they are ORed at 17721 * type level and ANDed at ancestor level. This will 17722 * happed during validation by walking the base axis 17723 * of the type. 17724 */ 17725 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17726 bfacet = cur->facet; 17727 /* 17728 * Special handling of enumerations and patterns. 17729 * TODO: hmm, they should not appear in the set, so remove this. 17730 */ 17731 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17732 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17733 continue; 17734 /* 17735 * Search for a duplicate facet in the current type. 17736 */ 17737 link = type->facetSet; 17738 /* err = 0; */ 17739 /* fixedErr = 0; */ 17740 while (link != NULL) { 17741 facet = link->facet; 17742 if (facet->type == bfacet->type) { 17743 switch (facet->type) { 17744 case XML_SCHEMA_FACET_WHITESPACE: 17745 /* 17746 * The whitespace must be stronger. 17747 */ 17748 if (facet->whitespace < bfacet->whitespace) { 17749 FACET_RESTR_ERR(facet, 17750 "The 'whitespace' value has to be equal to " 17751 "or stronger than the 'whitespace' value of " 17752 "the base type") 17753 } 17754 if ((bfacet->fixed) && 17755 (facet->whitespace != bfacet->whitespace)) { 17756 FACET_RESTR_FIXED_ERR(facet) 17757 } 17758 break; 17759 default: 17760 break; 17761 } 17762 /* Duplicate found. */ 17763 break; 17764 } 17765 link = link->next; 17766 } 17767 /* 17768 * If no duplicate was found: add the base types's facet 17769 * to the set. 17770 */ 17771 if (link == NULL) { 17772 link = (xmlSchemaFacetLinkPtr) 17773 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17774 if (link == NULL) { 17775 xmlSchemaPErrMemory(pctxt, 17776 "deriving facets, creating a facet link", NULL); 17777 return (-1); 17778 } 17779 link->facet = cur->facet; 17780 link->next = NULL; 17781 if (last == NULL) 17782 type->facetSet = link; 17783 else 17784 last->next = link; 17785 last = link; 17786 } 17787 17788 } 17789 17790 return (0); 17791 internal_error: 17792 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17793 "an error occurred"); 17794 return (-1); 17795 } 17796 17797 static int 17798 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17799 xmlSchemaTypePtr type) 17800 { 17801 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17802 /* 17803 * The actual value is then formed by replacing any union type 17804 * definition in the `explicit members` with the members of their 17805 * {member type definitions}, in order. 17806 * 17807 * TODO: There's a bug entry at 17808 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17809 * which indicates that we'll keep the union types the future. 17810 */ 17811 link = type->memberTypes; 17812 while (link != NULL) { 17813 17814 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17815 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17816 17817 if (WXS_IS_UNION(link->type)) { 17818 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17819 if (subLink != NULL) { 17820 link->type = subLink->type; 17821 if (subLink->next != NULL) { 17822 lastLink = link->next; 17823 subLink = subLink->next; 17824 prevLink = link; 17825 while (subLink != NULL) { 17826 newLink = (xmlSchemaTypeLinkPtr) 17827 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17828 if (newLink == NULL) { 17829 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17830 NULL); 17831 return (-1); 17832 } 17833 newLink->type = subLink->type; 17834 prevLink->next = newLink; 17835 prevLink = newLink; 17836 newLink->next = lastLink; 17837 17838 subLink = subLink->next; 17839 } 17840 } 17841 } 17842 } 17843 link = link->next; 17844 } 17845 return (0); 17846 } 17847 17848 static void 17849 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17850 { 17851 int has = 0, needVal = 0, normVal = 0; 17852 17853 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17854 if (has) { 17855 needVal = (type->baseType->flags & 17856 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17857 normVal = (type->baseType->flags & 17858 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17859 } 17860 if (type->facets != NULL) { 17861 xmlSchemaFacetPtr fac; 17862 17863 for (fac = type->facets; fac != NULL; fac = fac->next) { 17864 switch (fac->type) { 17865 case XML_SCHEMA_FACET_WHITESPACE: 17866 break; 17867 case XML_SCHEMA_FACET_PATTERN: 17868 normVal = 1; 17869 has = 1; 17870 break; 17871 case XML_SCHEMA_FACET_ENUMERATION: 17872 needVal = 1; 17873 normVal = 1; 17874 has = 1; 17875 break; 17876 default: 17877 has = 1; 17878 break; 17879 } 17880 } 17881 } 17882 if (normVal) 17883 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17884 if (needVal) 17885 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17886 if (has) 17887 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17888 17889 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17890 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17891 /* 17892 * OPTIMIZE VAL TODO: Some facets need a computed value. 17893 */ 17894 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17895 (prim->builtInType != XML_SCHEMAS_STRING)) { 17896 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17897 } 17898 } 17899 } 17900 17901 static int 17902 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17903 { 17904 17905 17906 /* 17907 * Evaluate the whitespace-facet value. 17908 */ 17909 if (WXS_IS_LIST(type)) { 17910 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17911 return (0); 17912 } else if (WXS_IS_UNION(type)) 17913 return (0); 17914 17915 if (type->facetSet != NULL) { 17916 xmlSchemaFacetLinkPtr lin; 17917 17918 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17919 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17920 switch (lin->facet->whitespace) { 17921 case XML_SCHEMAS_FACET_PRESERVE: 17922 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17923 break; 17924 case XML_SCHEMAS_FACET_REPLACE: 17925 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17926 break; 17927 case XML_SCHEMAS_FACET_COLLAPSE: 17928 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17929 break; 17930 default: 17931 return (-1); 17932 } 17933 return (0); 17934 } 17935 } 17936 } 17937 /* 17938 * For all `atomic` datatypes other than string (and types `derived` 17939 * by `restriction` from it) the value of whiteSpace is fixed to 17940 * collapse 17941 */ 17942 { 17943 xmlSchemaTypePtr anc; 17944 17945 for (anc = type->baseType; anc != NULL && 17946 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17947 anc = anc->baseType) { 17948 17949 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17950 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17951 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17952 17953 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17954 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17955 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17956 17957 } else 17958 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17959 break; 17960 } 17961 } 17962 } 17963 return (0); 17964 } 17965 17966 static int 17967 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17968 xmlSchemaTypePtr type) 17969 { 17970 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17971 return(0); 17972 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17973 return(0); 17974 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17975 17976 if (WXS_IS_LIST(type)) { 17977 /* 17978 * Corresponds to <simpleType><list>... 17979 */ 17980 if (type->subtypes == NULL) { 17981 /* 17982 * This one is really needed, so get out. 17983 */ 17984 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17985 "list type has no item-type assigned"); 17986 return(-1); 17987 } 17988 } else if (WXS_IS_UNION(type)) { 17989 /* 17990 * Corresponds to <simpleType><union>... 17991 */ 17992 if (type->memberTypes == NULL) { 17993 /* 17994 * This one is really needed, so get out. 17995 */ 17996 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17997 "union type has no member-types assigned"); 17998 return(-1); 17999 } 18000 } else { 18001 /* 18002 * Corresponds to <simpleType><restriction>... 18003 */ 18004 if (type->baseType == NULL) { 18005 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 18006 "type has no base-type assigned"); 18007 return(-1); 18008 } 18009 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 18010 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 18011 return(-1); 18012 /* 18013 * Variety 18014 * If the <restriction> alternative is chosen, then the 18015 * {variety} of the {base type definition}. 18016 */ 18017 if (WXS_IS_ATOMIC(type->baseType)) 18018 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 18019 else if (WXS_IS_LIST(type->baseType)) { 18020 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 18021 /* 18022 * Inherit the itemType. 18023 */ 18024 type->subtypes = type->baseType->subtypes; 18025 } else if (WXS_IS_UNION(type->baseType)) { 18026 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 18027 /* 18028 * NOTE that we won't assign the memberTypes of the base, 18029 * since this will make trouble when freeing them; we will 18030 * use a lookup function to access them instead. 18031 */ 18032 } 18033 } 18034 return(0); 18035 } 18036 18037 #ifdef DEBUG_TYPE 18038 static void 18039 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18040 xmlSchemaTypePtr type) 18041 { 18042 if (type->node != NULL) { 18043 xmlGenericError(xmlGenericErrorContext, 18044 "Type of %s : %s:%d :", name, 18045 type->node->doc->URL, 18046 xmlGetLineNo(type->node)); 18047 } else { 18048 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18049 } 18050 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18051 switch (type->contentType) { 18052 case XML_SCHEMA_CONTENT_SIMPLE: 18053 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18054 break; 18055 case XML_SCHEMA_CONTENT_ELEMENTS: 18056 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18057 break; 18058 case XML_SCHEMA_CONTENT_UNKNOWN: 18059 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18060 break; 18061 case XML_SCHEMA_CONTENT_EMPTY: 18062 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18063 break; 18064 case XML_SCHEMA_CONTENT_MIXED: 18065 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18066 type->subtypes)) 18067 xmlGenericError(xmlGenericErrorContext, 18068 "mixed as emptiable particle\n"); 18069 else 18070 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18071 break; 18072 /* Removed, since not used. */ 18073 /* 18074 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18075 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18076 break; 18077 */ 18078 case XML_SCHEMA_CONTENT_BASIC: 18079 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18080 break; 18081 default: 18082 xmlGenericError(xmlGenericErrorContext, 18083 "not registered !!!\n"); 18084 break; 18085 } 18086 } 18087 } 18088 #endif 18089 18090 /* 18091 * 3.14.6 Constraints on Simple Type Definition Schema Components 18092 */ 18093 static int 18094 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18095 xmlSchemaTypePtr type) 18096 { 18097 int res, olderrs = pctxt->nberrors; 18098 18099 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18100 return(-1); 18101 18102 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18103 return(0); 18104 18105 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18106 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18107 18108 if (type->baseType == NULL) { 18109 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18110 "missing baseType"); 18111 goto exit_failure; 18112 } 18113 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18114 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18115 /* 18116 * If a member type of a union is a union itself, we need to substitute 18117 * that member type for its member types. 18118 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18119 * types in WXS 1.1. 18120 */ 18121 if ((type->memberTypes != NULL) && 18122 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18123 return(-1); 18124 /* 18125 * SPEC src-simple-type 1 18126 * "The corresponding simple type definition, if any, must satisfy 18127 * the conditions set out in Constraints on Simple Type Definition 18128 * Schema Components ($3.14.6)." 18129 */ 18130 /* 18131 * Schema Component Constraint: Simple Type Definition Properties Correct 18132 * (st-props-correct) 18133 */ 18134 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18135 HFAILURE HERROR 18136 /* 18137 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18138 * (cos-st-restricts) 18139 */ 18140 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18141 HFAILURE HERROR 18142 /* 18143 * TODO: Removed the error report, since it got annoying to get an 18144 * extra error report, if anything failed until now. 18145 * Enable this if needed. 18146 * 18147 * xmlSchemaPErr(ctxt, type->node, 18148 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18149 * "Simple type '%s' does not satisfy the constraints " 18150 * "on simple type definitions.\n", 18151 * type->name, NULL); 18152 */ 18153 /* 18154 * Schema Component Constraint: Simple Type Restriction (Facets) 18155 * (st-restrict-facets) 18156 */ 18157 res = xmlSchemaCheckFacetValues(type, pctxt); 18158 HFAILURE HERROR 18159 if ((type->facetSet != NULL) || 18160 (type->baseType->facetSet != NULL)) { 18161 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18162 HFAILURE HERROR 18163 } 18164 /* 18165 * Whitespace value. 18166 */ 18167 res = xmlSchemaTypeFixupWhitespace(type); 18168 HFAILURE HERROR 18169 xmlSchemaTypeFixupOptimFacets(type); 18170 18171 exit_error: 18172 #ifdef DEBUG_TYPE 18173 xmlSchemaDebugFixedType(pctxt, type); 18174 #endif 18175 if (olderrs != pctxt->nberrors) 18176 return(pctxt->err); 18177 return(0); 18178 18179 exit_failure: 18180 #ifdef DEBUG_TYPE 18181 xmlSchemaDebugFixedType(pctxt, type); 18182 #endif 18183 return(-1); 18184 } 18185 18186 static int 18187 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18188 xmlSchemaTypePtr type) 18189 { 18190 int res = 0, olderrs = pctxt->nberrors; 18191 xmlSchemaTypePtr baseType = type->baseType; 18192 18193 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18194 return(0); 18195 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18196 if (baseType == NULL) { 18197 PERROR_INT("xmlSchemaFixupComplexType", 18198 "missing baseType"); 18199 goto exit_failure; 18200 } 18201 /* 18202 * Fixup the base type. 18203 */ 18204 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18205 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18206 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18207 /* 18208 * Skip fixup if the base type is invalid. 18209 * TODO: Generate a warning! 18210 */ 18211 return(0); 18212 } 18213 /* 18214 * This basically checks if the base type can be derived. 18215 */ 18216 res = xmlSchemaCheckSRCCT(pctxt, type); 18217 HFAILURE HERROR 18218 /* 18219 * Fixup the content type. 18220 */ 18221 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18222 /* 18223 * Corresponds to <complexType><simpleContent>... 18224 */ 18225 if ((WXS_IS_COMPLEX(baseType)) && 18226 (baseType->contentTypeDef != NULL) && 18227 (WXS_IS_RESTRICTION(type))) { 18228 xmlSchemaTypePtr contentBase, content; 18229 #ifdef ENABLE_NAMED_LOCALS 18230 char buf[30]; 18231 const xmlChar *tmpname; 18232 #endif 18233 /* 18234 * SPEC (1) If <restriction> + base type is <complexType>, 18235 * "whose own {content type} is a simple type..." 18236 */ 18237 if (type->contentTypeDef != NULL) { 18238 /* 18239 * SPEC (1.1) "the simple type definition corresponding to the 18240 * <simpleType> among the [children] of <restriction> if there 18241 * is one;" 18242 * Note that this "<simpleType> among the [children]" was put 18243 * into ->contentTypeDef during parsing. 18244 */ 18245 contentBase = type->contentTypeDef; 18246 type->contentTypeDef = NULL; 18247 } else { 18248 /* 18249 * (1.2) "...otherwise (<restriction> has no <simpleType> 18250 * among its [children]), the simple type definition which 18251 * is the {content type} of the ... base type." 18252 */ 18253 contentBase = baseType->contentTypeDef; 18254 } 18255 /* 18256 * SPEC 18257 * "... a simple type definition which restricts the simple 18258 * type definition identified in clause 1.1 or clause 1.2 18259 * with a set of facet components" 18260 * 18261 * Create the anonymous simple type, which will be the content 18262 * type of the complex type. 18263 */ 18264 #ifdef ENABLE_NAMED_LOCALS 18265 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18266 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18267 content = xmlSchemaAddType(pctxt, pctxt->schema, 18268 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18269 type->node, 0); 18270 #else 18271 content = xmlSchemaAddType(pctxt, pctxt->schema, 18272 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18273 type->node, 0); 18274 #endif 18275 if (content == NULL) 18276 goto exit_failure; 18277 /* 18278 * We will use the same node as for the <complexType> 18279 * to have it somehow anchored in the schema doc. 18280 */ 18281 content->type = XML_SCHEMA_TYPE_SIMPLE; 18282 content->baseType = contentBase; 18283 /* 18284 * Move the facets, previously anchored on the 18285 * complexType during parsing. 18286 */ 18287 content->facets = type->facets; 18288 type->facets = NULL; 18289 content->facetSet = type->facetSet; 18290 type->facetSet = NULL; 18291 18292 type->contentTypeDef = content; 18293 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18294 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18295 /* 18296 * Fixup the newly created type. We don't need to check 18297 * for circularity here. 18298 */ 18299 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18300 HFAILURE HERROR 18301 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18302 HFAILURE HERROR 18303 18304 } else if ((WXS_IS_COMPLEX(baseType)) && 18305 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18306 (WXS_IS_RESTRICTION(type))) { 18307 /* 18308 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18309 * an emptiable particle, then a simple type definition which 18310 * restricts the <restriction>'s <simpleType> child. 18311 */ 18312 if ((type->contentTypeDef == NULL) || 18313 (type->contentTypeDef->baseType == NULL)) { 18314 /* 18315 * TODO: Check if this ever happens. 18316 */ 18317 xmlSchemaPCustomErr(pctxt, 18318 XML_SCHEMAP_INTERNAL, 18319 WXS_BASIC_CAST type, NULL, 18320 "Internal error: xmlSchemaTypeFixup, " 18321 "complex type '%s': the <simpleContent><restriction> " 18322 "is missing a <simpleType> child, but was not catched " 18323 "by xmlSchemaCheckSRCCT()", type->name); 18324 goto exit_failure; 18325 } 18326 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18327 /* 18328 * SPEC (3) If <extension> + base is <complexType> with 18329 * <simpleType> content, "...then the {content type} of that 18330 * complex type definition" 18331 */ 18332 if (baseType->contentTypeDef == NULL) { 18333 /* 18334 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18335 * should have catched this already. 18336 */ 18337 xmlSchemaPCustomErr(pctxt, 18338 XML_SCHEMAP_INTERNAL, 18339 WXS_BASIC_CAST type, NULL, 18340 "Internal error: xmlSchemaTypeFixup, " 18341 "complex type '%s': the <extension>ed base type is " 18342 "a complex type with no simple content type", 18343 type->name); 18344 goto exit_failure; 18345 } 18346 type->contentTypeDef = baseType->contentTypeDef; 18347 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18348 /* 18349 * SPEC (4) <extension> + base is <simpleType> 18350 * "... then that simple type definition" 18351 */ 18352 type->contentTypeDef = baseType; 18353 } else { 18354 /* 18355 * TODO: Check if this ever happens. 18356 */ 18357 xmlSchemaPCustomErr(pctxt, 18358 XML_SCHEMAP_INTERNAL, 18359 WXS_BASIC_CAST type, NULL, 18360 "Internal error: xmlSchemaTypeFixup, " 18361 "complex type '%s' with <simpleContent>: unhandled " 18362 "derivation case", type->name); 18363 goto exit_failure; 18364 } 18365 } else { 18366 int dummySequence = 0; 18367 xmlSchemaParticlePtr particle = 18368 (xmlSchemaParticlePtr) type->subtypes; 18369 /* 18370 * Corresponds to <complexType><complexContent>... 18371 * 18372 * NOTE that the effective mixed was already set during parsing of 18373 * <complexType> and <complexContent>; its flag value is 18374 * XML_SCHEMAS_TYPE_MIXED. 18375 * 18376 * Compute the "effective content": 18377 * (2.1.1) + (2.1.2) + (2.1.3) 18378 */ 18379 if ((particle == NULL) || 18380 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18381 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18382 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18383 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18384 (particle->minOccurs == 0))) && 18385 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18386 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18387 /* 18388 * SPEC (2.1.4) "If the `effective mixed` is true, then 18389 * a particle whose properties are as follows:..." 18390 * 18391 * Empty sequence model group with 18392 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18393 * NOTE that we sill assign it the <complexType> node to 18394 * somehow anchor it in the doc. 18395 */ 18396 if ((particle == NULL) || 18397 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18398 /* 18399 * Create the particle. 18400 */ 18401 particle = xmlSchemaAddParticle(pctxt, 18402 type->node, 1, 1); 18403 if (particle == NULL) 18404 goto exit_failure; 18405 /* 18406 * Create the model group. 18407 */ /* URGENT TODO: avoid adding to pending items. */ 18408 particle->children = (xmlSchemaTreeItemPtr) 18409 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18410 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18411 if (particle->children == NULL) 18412 goto exit_failure; 18413 18414 type->subtypes = (xmlSchemaTypePtr) particle; 18415 } 18416 dummySequence = 1; 18417 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18418 } else { 18419 /* 18420 * SPEC (2.1.5) "otherwise empty" 18421 */ 18422 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18423 } 18424 } else { 18425 /* 18426 * SPEC (2.2) "otherwise the particle corresponding to the 18427 * <all>, <choice>, <group> or <sequence> among the 18428 * [children]." 18429 */ 18430 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18431 } 18432 /* 18433 * Compute the "content type". 18434 */ 18435 if (WXS_IS_RESTRICTION(type)) { 18436 /* 18437 * SPEC (3.1) "If <restriction>..." 18438 * (3.1.1) + (3.1.2) */ 18439 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18440 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18441 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18442 } 18443 } else { 18444 /* 18445 * SPEC (3.2) "If <extension>..." 18446 */ 18447 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18448 /* 18449 * SPEC (3.2.1) 18450 * "If the `effective content` is empty, then the 18451 * {content type} of the [...] base ..." 18452 */ 18453 type->contentType = baseType->contentType; 18454 type->subtypes = baseType->subtypes; 18455 /* 18456 * Fixes bug #347316: 18457 * This is the case when the base type has a simple 18458 * type definition as content. 18459 */ 18460 type->contentTypeDef = baseType->contentTypeDef; 18461 /* 18462 * NOTE that the effective mixed is ignored here. 18463 */ 18464 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18465 /* 18466 * SPEC (3.2.2) 18467 */ 18468 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18469 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18470 } else { 18471 /* 18472 * SPEC (3.2.3) 18473 */ 18474 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18475 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18476 /* 18477 * "A model group whose {compositor} is sequence and whose 18478 * {particles} are..." 18479 */ 18480 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18481 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18482 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18483 XML_SCHEMA_TYPE_ALL)) 18484 { 18485 /* 18486 * SPEC cos-all-limited (1) 18487 */ 18488 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18489 /* TODO: error code */ 18490 XML_SCHEMAP_COS_ALL_LIMITED, 18491 WXS_ITEM_NODE(type), NULL, 18492 "The type has an 'all' model group in its " 18493 "{content type} and thus cannot be derived from " 18494 "a non-empty type, since this would produce a " 18495 "'sequence' model group containing the 'all' " 18496 "model group; 'all' model groups are not " 18497 "allowed to appear inside other model groups", 18498 NULL, NULL); 18499 18500 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18501 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18502 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18503 XML_SCHEMA_TYPE_ALL)) 18504 { 18505 /* 18506 * SPEC cos-all-limited (1) 18507 */ 18508 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18509 /* TODO: error code */ 18510 XML_SCHEMAP_COS_ALL_LIMITED, 18511 WXS_ITEM_NODE(type), NULL, 18512 "A type cannot be derived by extension from a type " 18513 "which has an 'all' model group in its " 18514 "{content type}, since this would produce a " 18515 "'sequence' model group containing the 'all' " 18516 "model group; 'all' model groups are not " 18517 "allowed to appear inside other model groups", 18518 NULL, NULL); 18519 18520 } else if (! dummySequence) { 18521 xmlSchemaTreeItemPtr effectiveContent = 18522 (xmlSchemaTreeItemPtr) type->subtypes; 18523 /* 18524 * Create the particle. 18525 */ 18526 particle = xmlSchemaAddParticle(pctxt, 18527 type->node, 1, 1); 18528 if (particle == NULL) 18529 goto exit_failure; 18530 /* 18531 * Create the "sequence" model group. 18532 */ 18533 particle->children = (xmlSchemaTreeItemPtr) 18534 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18535 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18536 if (particle->children == NULL) 18537 goto exit_failure; 18538 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18539 /* 18540 * SPEC "the particle of the {content type} of 18541 * the ... base ..." 18542 * Create a duplicate of the base type's particle 18543 * and assign its "term" to it. 18544 */ 18545 particle->children->children = 18546 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18547 type->node, 18548 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18549 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18550 if (particle->children->children == NULL) 18551 goto exit_failure; 18552 particle = (xmlSchemaParticlePtr) 18553 particle->children->children; 18554 particle->children = 18555 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18556 /* 18557 * SPEC "followed by the `effective content`." 18558 */ 18559 particle->next = effectiveContent; 18560 /* 18561 * This all will result in: 18562 * new-particle 18563 * --> new-sequence( 18564 * new-particle 18565 * --> base-model, 18566 * this-particle 18567 * --> this-model 18568 * ) 18569 */ 18570 } else { 18571 /* 18572 * This is the case when there is already an empty 18573 * <sequence> with minOccurs==maxOccurs==1. 18574 * Just add the base types's content type. 18575 * NOTE that, although we miss to add an intermediate 18576 * <sequence>, this should produce no difference to 18577 * neither the regex compilation of the content model, 18578 * nor to the complex type contraints. 18579 */ 18580 particle->children->children = 18581 (xmlSchemaTreeItemPtr) baseType->subtypes; 18582 } 18583 } 18584 } 18585 } 18586 /* 18587 * Now fixup attribute uses: 18588 * - expand attr. group references 18589 * - intersect attribute wildcards 18590 * - inherit attribute uses of the base type 18591 * - inherit or union attr. wildcards if extending 18592 * - apply attr. use prohibitions if restricting 18593 */ 18594 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18595 HFAILURE HERROR 18596 /* 18597 * Apply the complex type component constraints; this will not 18598 * check attributes, since this is done in 18599 * xmlSchemaFixupTypeAttributeUses(). 18600 */ 18601 res = xmlSchemaCheckCTComponent(pctxt, type); 18602 HFAILURE HERROR 18603 18604 #ifdef DEBUG_TYPE 18605 xmlSchemaDebugFixedType(pctxt, type); 18606 #endif 18607 if (olderrs != pctxt->nberrors) 18608 return(pctxt->err); 18609 else 18610 return(0); 18611 18612 exit_error: 18613 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18614 #ifdef DEBUG_TYPE 18615 xmlSchemaDebugFixedType(pctxt, type); 18616 #endif 18617 return(pctxt->err); 18618 18619 exit_failure: 18620 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18621 #ifdef DEBUG_TYPE 18622 xmlSchemaDebugFixedType(pctxt, type); 18623 #endif 18624 return(-1); 18625 } 18626 18627 18628 /** 18629 * xmlSchemaTypeFixup: 18630 * @typeDecl: the schema type definition 18631 * @ctxt: the schema parser context 18632 * 18633 * Fixes the content model of the type. 18634 * URGENT TODO: We need an int result! 18635 */ 18636 static int 18637 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18638 xmlSchemaAbstractCtxtPtr actxt) 18639 { 18640 if (type == NULL) 18641 return(0); 18642 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18643 AERROR_INT("xmlSchemaTypeFixup", 18644 "this function needs a parser context"); 18645 return(-1); 18646 } 18647 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18648 return(0); 18649 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18650 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18651 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18652 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18653 return(0); 18654 } 18655 18656 /** 18657 * xmlSchemaCheckFacet: 18658 * @facet: the facet 18659 * @typeDecl: the schema type definition 18660 * @pctxt: the schema parser context or NULL 18661 * @name: the optional name of the type 18662 * 18663 * Checks and computes the values of facets. 18664 * 18665 * Returns 0 if valid, a positive error code if not valid and 18666 * -1 in case of an internal or API error. 18667 */ 18668 int 18669 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18670 xmlSchemaTypePtr typeDecl, 18671 xmlSchemaParserCtxtPtr pctxt, 18672 const xmlChar * name ATTRIBUTE_UNUSED) 18673 { 18674 int ret = 0, ctxtGiven; 18675 18676 if ((facet == NULL) || (typeDecl == NULL)) 18677 return(-1); 18678 /* 18679 * TODO: will the parser context be given if used from 18680 * the relaxNG module? 18681 */ 18682 if (pctxt == NULL) 18683 ctxtGiven = 0; 18684 else 18685 ctxtGiven = 1; 18686 18687 switch (facet->type) { 18688 case XML_SCHEMA_FACET_MININCLUSIVE: 18689 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18690 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18691 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18692 case XML_SCHEMA_FACET_ENUMERATION: { 18693 /* 18694 * Okay we need to validate the value 18695 * at that point. 18696 */ 18697 xmlSchemaTypePtr base; 18698 18699 /* 4.3.5.5 Constraints on enumeration Schema Components 18700 * Schema Component Constraint: enumeration valid restriction 18701 * It is an `error` if any member of {value} is not in the 18702 * `value space` of {base type definition}. 18703 * 18704 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18705 * The value `must` be in the 18706 * `value space` of the `base type`. 18707 */ 18708 /* 18709 * This function is intended to deliver a compiled value 18710 * on the facet. In this implementation of XML Schemata the 18711 * type holding a facet, won't be a built-in type. 18712 * Thus to ensure that other API 18713 * calls (relaxng) do work, if the given type is a built-in 18714 * type, we will assume that the given built-in type *is 18715 * already* the base type. 18716 */ 18717 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18718 base = typeDecl->baseType; 18719 if (base == NULL) { 18720 PERROR_INT("xmlSchemaCheckFacet", 18721 "a type user derived type has no base type"); 18722 return (-1); 18723 } 18724 } else 18725 base = typeDecl; 18726 18727 if (! ctxtGiven) { 18728 /* 18729 * A context is needed if called from RelaxNG. 18730 */ 18731 pctxt = xmlSchemaNewParserCtxt("*"); 18732 if (pctxt == NULL) 18733 return (-1); 18734 } 18735 /* 18736 * NOTE: This call does not check the content nodes, 18737 * since they are not available: 18738 * facet->node is just the node holding the facet 18739 * definition, *not* the attribute holding the *value* 18740 * of the facet. 18741 */ 18742 ret = xmlSchemaVCheckCVCSimpleType( 18743 ACTXT_CAST pctxt, facet->node, base, 18744 facet->value, &(facet->val), 1, 1, 0); 18745 if (ret != 0) { 18746 if (ret < 0) { 18747 /* No error message for RelaxNG. */ 18748 if (ctxtGiven) { 18749 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18750 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18751 "Internal error: xmlSchemaCheckFacet, " 18752 "failed to validate the value '%s' of the " 18753 "facet '%s' against the base type", 18754 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18755 } 18756 goto internal_error; 18757 } 18758 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18759 /* No error message for RelaxNG. */ 18760 if (ctxtGiven) { 18761 xmlChar *str = NULL; 18762 18763 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18764 ret, facet->node, WXS_BASIC_CAST facet, 18765 "The value '%s' of the facet does not validate " 18766 "against the base type '%s'", 18767 facet->value, 18768 xmlSchemaFormatQName(&str, 18769 base->targetNamespace, base->name)); 18770 FREE_AND_NULL(str); 18771 } 18772 goto exit; 18773 } else if (facet->val == NULL) { 18774 if (ctxtGiven) { 18775 PERROR_INT("xmlSchemaCheckFacet", 18776 "value was not computed"); 18777 } 18778 TODO 18779 } 18780 break; 18781 } 18782 case XML_SCHEMA_FACET_PATTERN: 18783 facet->regexp = xmlRegexpCompile(facet->value); 18784 if (facet->regexp == NULL) { 18785 ret = XML_SCHEMAP_REGEXP_INVALID; 18786 /* No error message for RelaxNG. */ 18787 if (ctxtGiven) { 18788 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18789 ret, facet->node, WXS_BASIC_CAST typeDecl, 18790 "The value '%s' of the facet 'pattern' is not a " 18791 "valid regular expression", 18792 facet->value, NULL); 18793 } 18794 } 18795 break; 18796 case XML_SCHEMA_FACET_TOTALDIGITS: 18797 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18798 case XML_SCHEMA_FACET_LENGTH: 18799 case XML_SCHEMA_FACET_MAXLENGTH: 18800 case XML_SCHEMA_FACET_MINLENGTH: 18801 18802 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18803 ret = xmlSchemaValidatePredefinedType( 18804 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18805 facet->value, &(facet->val)); 18806 } else { 18807 ret = xmlSchemaValidatePredefinedType( 18808 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18809 facet->value, &(facet->val)); 18810 } 18811 if (ret != 0) { 18812 if (ret < 0) { 18813 /* No error message for RelaxNG. */ 18814 if (ctxtGiven) { 18815 PERROR_INT("xmlSchemaCheckFacet", 18816 "validating facet value"); 18817 } 18818 goto internal_error; 18819 } 18820 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18821 /* No error message for RelaxNG. */ 18822 if (ctxtGiven) { 18823 /* error code */ 18824 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18825 ret, facet->node, WXS_BASIC_CAST typeDecl, 18826 "The value '%s' of the facet '%s' is not a valid '%s'", 18827 facet->value, 18828 xmlSchemaFacetTypeToString(facet->type), 18829 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18830 BAD_CAST "nonNegativeInteger" : 18831 BAD_CAST "positiveInteger", 18832 NULL); 18833 } 18834 } 18835 break; 18836 18837 case XML_SCHEMA_FACET_WHITESPACE:{ 18838 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18839 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18840 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18841 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18842 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18843 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18844 } else { 18845 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18846 /* No error message for RelaxNG. */ 18847 if (ctxtGiven) { 18848 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18849 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18850 ret, facet->node, WXS_BASIC_CAST typeDecl, 18851 "The value '%s' of the facet 'whitespace' is not " 18852 "valid", facet->value, NULL); 18853 } 18854 } 18855 } 18856 default: 18857 break; 18858 } 18859 exit: 18860 if ((! ctxtGiven) && (pctxt != NULL)) 18861 xmlSchemaFreeParserCtxt(pctxt); 18862 return (ret); 18863 internal_error: 18864 if ((! ctxtGiven) && (pctxt != NULL)) 18865 xmlSchemaFreeParserCtxt(pctxt); 18866 return (-1); 18867 } 18868 18869 /** 18870 * xmlSchemaCheckFacetValues: 18871 * @typeDecl: the schema type definition 18872 * @ctxt: the schema parser context 18873 * 18874 * Checks the default values types, especially for facets 18875 */ 18876 static int 18877 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18878 xmlSchemaParserCtxtPtr pctxt) 18879 { 18880 int res, olderrs = pctxt->nberrors; 18881 const xmlChar *name = typeDecl->name; 18882 /* 18883 * NOTE: It is intended to use the facets list, instead 18884 * of facetSet. 18885 */ 18886 if (typeDecl->facets != NULL) { 18887 xmlSchemaFacetPtr facet = typeDecl->facets; 18888 18889 /* 18890 * Temporarily assign the "schema" to the validation context 18891 * of the parser context. This is needed for NOTATION validation. 18892 */ 18893 if (pctxt->vctxt == NULL) { 18894 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18895 return(-1); 18896 } 18897 pctxt->vctxt->schema = pctxt->schema; 18898 while (facet != NULL) { 18899 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18900 HFAILURE 18901 facet = facet->next; 18902 } 18903 pctxt->vctxt->schema = NULL; 18904 } 18905 if (olderrs != pctxt->nberrors) 18906 return(pctxt->err); 18907 return(0); 18908 exit_failure: 18909 return(-1); 18910 } 18911 18912 /** 18913 * xmlSchemaGetCircModelGrDefRef: 18914 * @ctxtMGroup: the searched model group 18915 * @selfMGroup: the second searched model group 18916 * @particle: the first particle 18917 * 18918 * This one is intended to be used by 18919 * xmlSchemaCheckGroupDefCircular only. 18920 * 18921 * Returns the particle with the circular model group definition reference, 18922 * otherwise NULL. 18923 */ 18924 static xmlSchemaTreeItemPtr 18925 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18926 xmlSchemaTreeItemPtr particle) 18927 { 18928 xmlSchemaTreeItemPtr circ = NULL; 18929 xmlSchemaTreeItemPtr term; 18930 xmlSchemaModelGroupDefPtr gdef; 18931 18932 for (; particle != NULL; particle = particle->next) { 18933 term = particle->children; 18934 if (term == NULL) 18935 continue; 18936 switch (term->type) { 18937 case XML_SCHEMA_TYPE_GROUP: 18938 gdef = (xmlSchemaModelGroupDefPtr) term; 18939 if (gdef == groupDef) 18940 return (particle); 18941 /* 18942 * Mark this model group definition to avoid infinite 18943 * recursion on circular references not yet examined. 18944 */ 18945 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18946 continue; 18947 if (gdef->children != NULL) { 18948 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18949 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18950 gdef->children->children); 18951 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18952 if (circ != NULL) 18953 return (circ); 18954 } 18955 break; 18956 case XML_SCHEMA_TYPE_SEQUENCE: 18957 case XML_SCHEMA_TYPE_CHOICE: 18958 case XML_SCHEMA_TYPE_ALL: 18959 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18960 if (circ != NULL) 18961 return (circ); 18962 break; 18963 default: 18964 break; 18965 } 18966 } 18967 return (NULL); 18968 } 18969 18970 /** 18971 * xmlSchemaCheckGroupDefCircular: 18972 * @item: the model group definition 18973 * @ctxt: the parser context 18974 * @name: the name 18975 * 18976 * Checks for circular references to model group definitions. 18977 */ 18978 static void 18979 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18980 xmlSchemaParserCtxtPtr ctxt) 18981 { 18982 /* 18983 * Schema Component Constraint: Model Group Correct 18984 * 2 Circular groups are disallowed. That is, within the {particles} 18985 * of a group there must not be at any depth a particle whose {term} 18986 * is the group itself. 18987 */ 18988 if ((item == NULL) || 18989 (item->type != XML_SCHEMA_TYPE_GROUP) || 18990 (item->children == NULL)) 18991 return; 18992 { 18993 xmlSchemaTreeItemPtr circ; 18994 18995 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18996 if (circ != NULL) { 18997 xmlChar *str = NULL; 18998 /* 18999 * TODO: The error report is not adequate: this constraint 19000 * is defined for model groups but not definitions, but since 19001 * there cannot be any circular model groups without a model group 19002 * definition (if not using a construction API), we check those 19003 * defintions only. 19004 */ 19005 xmlSchemaPCustomErr(ctxt, 19006 XML_SCHEMAP_MG_PROPS_CORRECT_2, 19007 NULL, WXS_ITEM_NODE(circ), 19008 "Circular reference to the model group definition '%s' " 19009 "defined", xmlSchemaFormatQName(&str, 19010 item->targetNamespace, item->name)); 19011 FREE_AND_NULL(str) 19012 /* 19013 * NOTE: We will cut the reference to avoid further 19014 * confusion of the processor. This is a fatal error. 19015 */ 19016 circ->children = NULL; 19017 } 19018 } 19019 } 19020 19021 /** 19022 * xmlSchemaModelGroupToModelGroupDefFixup: 19023 * @ctxt: the parser context 19024 * @mg: the model group 19025 * 19026 * Assigns the model group of model group definitions to the "term" 19027 * of the referencing particle. 19028 * In xmlSchemaResolveModelGroupParticleReferences the model group 19029 * definitions were assigned to the "term", since needed for the 19030 * circularity check. 19031 * 19032 * Schema Component Constraint: 19033 * All Group Limited (cos-all-limited) (1.2) 19034 */ 19035 static void 19036 xmlSchemaModelGroupToModelGroupDefFixup( 19037 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 19038 xmlSchemaModelGroupPtr mg) 19039 { 19040 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19041 19042 while (particle != NULL) { 19043 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19044 ((WXS_PARTICLE_TERM(particle))->type != 19045 XML_SCHEMA_TYPE_GROUP)) 19046 { 19047 particle = WXS_PTC_CAST particle->next; 19048 continue; 19049 } 19050 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19051 /* 19052 * TODO: Remove the particle. 19053 */ 19054 WXS_PARTICLE_TERM(particle) = NULL; 19055 particle = WXS_PTC_CAST particle->next; 19056 continue; 19057 } 19058 /* 19059 * Assign the model group to the {term} of the particle. 19060 */ 19061 WXS_PARTICLE_TERM(particle) = 19062 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19063 19064 particle = WXS_PTC_CAST particle->next; 19065 } 19066 } 19067 19068 /** 19069 * xmlSchemaCheckAttrGroupCircularRecur: 19070 * @ctxtGr: the searched attribute group 19071 * @attr: the current attribute list to be processed 19072 * 19073 * This one is intended to be used by 19074 * xmlSchemaCheckAttrGroupCircular only. 19075 * 19076 * Returns the circular attribute grou reference, otherwise NULL. 19077 */ 19078 static xmlSchemaQNameRefPtr 19079 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19080 xmlSchemaItemListPtr list) 19081 { 19082 xmlSchemaAttributeGroupPtr gr; 19083 xmlSchemaQNameRefPtr ref, circ; 19084 int i; 19085 /* 19086 * We will search for an attribute group reference which 19087 * references the context attribute group. 19088 */ 19089 for (i = 0; i < list->nbItems; i++) { 19090 ref = list->items[i]; 19091 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19092 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19093 (ref->item != NULL)) 19094 { 19095 gr = WXS_ATTR_GROUP_CAST ref->item; 19096 if (gr == ctxtGr) 19097 return(ref); 19098 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19099 continue; 19100 /* 19101 * Mark as visited to avoid infinite recursion on 19102 * circular references not yet examined. 19103 */ 19104 if ((gr->attrUses) && 19105 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19106 { 19107 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19108 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19109 (xmlSchemaItemListPtr) gr->attrUses); 19110 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19111 if (circ != NULL) 19112 return (circ); 19113 } 19114 19115 } 19116 } 19117 return (NULL); 19118 } 19119 19120 /** 19121 * xmlSchemaCheckAttrGroupCircular: 19122 * attrGr: the attribute group definition 19123 * @ctxt: the parser context 19124 * @name: the name 19125 * 19126 * Checks for circular references of attribute groups. 19127 */ 19128 static int 19129 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19130 xmlSchemaParserCtxtPtr ctxt) 19131 { 19132 /* 19133 * Schema Representation Constraint: 19134 * Attribute Group Definition Representation OK 19135 * 3 Circular group reference is disallowed outside <redefine>. 19136 * That is, unless this element information item's parent is 19137 * <redefine>, then among the [children], if any, there must 19138 * not be an <attributeGroup> with ref [attribute] which resolves 19139 * to the component corresponding to this <attributeGroup>. Indirect 19140 * circularity is also ruled out. That is, when QName resolution 19141 * (Schema Document) ($3.15.3) is applied to a `QName` arising from 19142 * any <attributeGroup>s with a ref [attribute] among the [children], 19143 * it must not be the case that a `QName` is encountered at any depth 19144 * which resolves to the component corresponding to this <attributeGroup>. 19145 */ 19146 if (attrGr->attrUses == NULL) 19147 return(0); 19148 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19149 return(0); 19150 else { 19151 xmlSchemaQNameRefPtr circ; 19152 19153 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19154 (xmlSchemaItemListPtr) attrGr->attrUses); 19155 if (circ != NULL) { 19156 xmlChar *str = NULL; 19157 /* 19158 * TODO: Report the referenced attr group as QName. 19159 */ 19160 xmlSchemaPCustomErr(ctxt, 19161 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19162 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19163 "Circular reference to the attribute group '%s' " 19164 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19165 FREE_AND_NULL(str); 19166 /* 19167 * NOTE: We will cut the reference to avoid further 19168 * confusion of the processor. 19169 * BADSPEC TODO: The spec should define how to process in this case. 19170 */ 19171 circ->item = NULL; 19172 return(ctxt->err); 19173 } 19174 } 19175 return(0); 19176 } 19177 19178 static int 19179 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19180 xmlSchemaAttributeGroupPtr attrGr); 19181 19182 /** 19183 * xmlSchemaExpandAttributeGroupRefs: 19184 * @pctxt: the parser context 19185 * @node: the node of the component holding the attribute uses 19186 * @completeWild: the intersected wildcard to be returned 19187 * @list: the attribute uses 19188 * 19189 * Substitutes contained attribute group references 19190 * for their attribute uses. Wilcards are intersected. 19191 * Attribute use prohibitions are removed from the list 19192 * and returned via the @prohibs list. 19193 * Pointlessness of attr. prohibs, if a matching attr. decl 19194 * is existent a well, are checked. 19195 */ 19196 static int 19197 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19198 xmlSchemaBasicItemPtr item, 19199 xmlSchemaWildcardPtr *completeWild, 19200 xmlSchemaItemListPtr list, 19201 xmlSchemaItemListPtr prohibs) 19202 { 19203 xmlSchemaAttributeGroupPtr gr; 19204 xmlSchemaAttributeUsePtr use; 19205 xmlSchemaItemListPtr sublist; 19206 int i, j; 19207 int created = (*completeWild == NULL) ? 0 : 1; 19208 19209 if (prohibs) 19210 prohibs->nbItems = 0; 19211 19212 for (i = 0; i < list->nbItems; i++) { 19213 use = list->items[i]; 19214 19215 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19216 if (prohibs == NULL) { 19217 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19218 "unexpected attr prohibition found"); 19219 return(-1); 19220 } 19221 /* 19222 * Remove from attribute uses. 19223 */ 19224 if (xmlSchemaItemListRemove(list, i) == -1) 19225 return(-1); 19226 i--; 19227 /* 19228 * Note that duplicate prohibitions were already 19229 * handled at parsing time. 19230 */ 19231 /* 19232 * Add to list of prohibitions. 19233 */ 19234 xmlSchemaItemListAddSize(prohibs, 2, use); 19235 continue; 19236 } 19237 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19238 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19239 { 19240 if ((WXS_QNAME_CAST use)->item == NULL) 19241 return(-1); 19242 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19243 /* 19244 * Expand the referenced attr. group. 19245 * TODO: remove this, this is done in a previous step, so 19246 * already done here. 19247 */ 19248 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19249 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19250 return(-1); 19251 } 19252 /* 19253 * Build the 'complete' wildcard; i.e. intersect multiple 19254 * wildcards. 19255 */ 19256 if (gr->attributeWildcard != NULL) { 19257 if (*completeWild == NULL) { 19258 *completeWild = gr->attributeWildcard; 19259 } else { 19260 if (! created) { 19261 xmlSchemaWildcardPtr tmpWild; 19262 19263 /* 19264 * Copy the first encountered wildcard as context, 19265 * except for the annotation. 19266 * 19267 * Although the complete wildcard might not correspond 19268 * to any node in the schema, we will anchor it on 19269 * the node of the owner component. 19270 */ 19271 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19272 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19273 WXS_ITEM_NODE(item)); 19274 if (tmpWild == NULL) 19275 return(-1); 19276 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19277 tmpWild, *completeWild) == -1) 19278 return (-1); 19279 tmpWild->processContents = (*completeWild)->processContents; 19280 *completeWild = tmpWild; 19281 created = 1; 19282 } 19283 19284 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19285 gr->attributeWildcard) == -1) 19286 return(-1); 19287 } 19288 } 19289 /* 19290 * Just remove the reference if the referenced group does not 19291 * contain any attribute uses. 19292 */ 19293 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19294 if ((sublist == NULL) || sublist->nbItems == 0) { 19295 if (xmlSchemaItemListRemove(list, i) == -1) 19296 return(-1); 19297 i--; 19298 continue; 19299 } 19300 /* 19301 * Add the attribute uses. 19302 */ 19303 list->items[i] = sublist->items[0]; 19304 if (sublist->nbItems != 1) { 19305 for (j = 1; j < sublist->nbItems; j++) { 19306 i++; 19307 if (xmlSchemaItemListInsert(list, 19308 sublist->items[j], i) == -1) 19309 return(-1); 19310 } 19311 } 19312 } 19313 19314 } 19315 /* 19316 * Handle pointless prohibitions of declared attributes. 19317 */ 19318 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19319 xmlSchemaAttributeUseProhibPtr prohib; 19320 19321 for (i = prohibs->nbItems -1; i >= 0; i--) { 19322 prohib = prohibs->items[i]; 19323 for (j = 0; j < list->nbItems; j++) { 19324 use = list->items[j]; 19325 19326 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19327 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19328 { 19329 xmlChar *str = NULL; 19330 19331 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19332 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19333 prohib->node, NULL, 19334 "Skipping pointless attribute use prohibition " 19335 "'%s', since a corresponding attribute use " 19336 "exists already in the type definition", 19337 xmlSchemaFormatQName(&str, 19338 prohib->targetNamespace, prohib->name), 19339 NULL, NULL); 19340 FREE_AND_NULL(str); 19341 /* 19342 * Remove the prohibition. 19343 */ 19344 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19345 return(-1); 19346 break; 19347 } 19348 } 19349 } 19350 } 19351 return(0); 19352 } 19353 19354 /** 19355 * xmlSchemaAttributeGroupExpandRefs: 19356 * @pctxt: the parser context 19357 * @attrGr: the attribute group definition 19358 * 19359 * Computation of: 19360 * {attribute uses} property 19361 * {attribute wildcard} property 19362 * 19363 * Substitutes contained attribute group references 19364 * for their attribute uses. Wilcards are intersected. 19365 */ 19366 static int 19367 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19368 xmlSchemaAttributeGroupPtr attrGr) 19369 { 19370 if ((attrGr->attrUses == NULL) || 19371 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19372 return(0); 19373 19374 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19375 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19376 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19377 return(-1); 19378 return(0); 19379 } 19380 19381 /** 19382 * xmlSchemaAttributeGroupExpandRefs: 19383 * @pctxt: the parser context 19384 * @attrGr: the attribute group definition 19385 * 19386 * Substitutes contained attribute group references 19387 * for their attribute uses. Wilcards are intersected. 19388 * 19389 * Schema Component Constraint: 19390 * Attribute Group Definition Properties Correct (ag-props-correct) 19391 */ 19392 static int 19393 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19394 xmlSchemaAttributeGroupPtr attrGr) 19395 { 19396 /* 19397 * SPEC ag-props-correct 19398 * (1) "The values of the properties of an attribute group definition 19399 * must be as described in the property tableau in The Attribute 19400 * Group Definition Schema Component ($3.6.1), modulo the impact of 19401 * Missing Sub-components ($5.3);" 19402 */ 19403 19404 if ((attrGr->attrUses != NULL) && 19405 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19406 { 19407 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19408 xmlSchemaAttributeUsePtr use, tmp; 19409 int i, j, hasId = 0; 19410 19411 for (i = uses->nbItems -1; i >= 0; i--) { 19412 use = uses->items[i]; 19413 /* 19414 * SPEC ag-props-correct 19415 * (2) "Two distinct members of the {attribute uses} must not have 19416 * {attribute declaration}s both of whose {name}s match and whose 19417 * {target namespace}s are identical." 19418 */ 19419 if (i > 0) { 19420 for (j = i -1; j >= 0; j--) { 19421 tmp = uses->items[j]; 19422 if ((WXS_ATTRUSE_DECL_NAME(use) == 19423 WXS_ATTRUSE_DECL_NAME(tmp)) && 19424 (WXS_ATTRUSE_DECL_TNS(use) == 19425 WXS_ATTRUSE_DECL_TNS(tmp))) 19426 { 19427 xmlChar *str = NULL; 19428 19429 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19430 XML_SCHEMAP_AG_PROPS_CORRECT, 19431 attrGr->node, WXS_BASIC_CAST attrGr, 19432 "Duplicate %s", 19433 xmlSchemaGetComponentDesignation(&str, use), 19434 NULL); 19435 FREE_AND_NULL(str); 19436 /* 19437 * Remove the duplicate. 19438 */ 19439 if (xmlSchemaItemListRemove(uses, i) == -1) 19440 return(-1); 19441 goto next_use; 19442 } 19443 } 19444 } 19445 /* 19446 * SPEC ag-props-correct 19447 * (3) "Two distinct members of the {attribute uses} must not have 19448 * {attribute declaration}s both of whose {type definition}s are or 19449 * are derived from ID." 19450 * TODO: Does 'derived' include member-types of unions? 19451 */ 19452 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19453 if (xmlSchemaIsDerivedFromBuiltInType( 19454 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19455 { 19456 if (hasId) { 19457 xmlChar *str = NULL; 19458 19459 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19460 XML_SCHEMAP_AG_PROPS_CORRECT, 19461 attrGr->node, WXS_BASIC_CAST attrGr, 19462 "There must not exist more than one attribute " 19463 "declaration of type 'xs:ID' " 19464 "(or derived from 'xs:ID'). The %s violates this " 19465 "constraint", 19466 xmlSchemaGetComponentDesignation(&str, use), 19467 NULL); 19468 FREE_AND_NULL(str); 19469 if (xmlSchemaItemListRemove(uses, i) == -1) 19470 return(-1); 19471 } 19472 hasId = 1; 19473 } 19474 } 19475 next_use: {} 19476 } 19477 } 19478 return(0); 19479 } 19480 19481 /** 19482 * xmlSchemaResolveAttrGroupReferences: 19483 * @attrgrpDecl: the schema attribute definition 19484 * @ctxt: the schema parser context 19485 * @name: the attribute name 19486 * 19487 * Resolves references to attribute group definitions. 19488 */ 19489 static int 19490 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19491 xmlSchemaParserCtxtPtr ctxt) 19492 { 19493 xmlSchemaAttributeGroupPtr group; 19494 19495 if (ref->item != NULL) 19496 return(0); 19497 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19498 ref->name, 19499 ref->targetNamespace); 19500 if (group == NULL) { 19501 xmlSchemaPResCompAttrErr(ctxt, 19502 XML_SCHEMAP_SRC_RESOLVE, 19503 NULL, ref->node, 19504 "ref", ref->name, ref->targetNamespace, 19505 ref->itemType, NULL); 19506 return(ctxt->err); 19507 } 19508 ref->item = WXS_BASIC_CAST group; 19509 return(0); 19510 } 19511 19512 /** 19513 * xmlSchemaCheckAttrPropsCorrect: 19514 * @item: an schema attribute declaration/use 19515 * @ctxt: a schema parser context 19516 * @name: the name of the attribute 19517 * 19518 * 19519 * Schema Component Constraint: 19520 * Attribute Declaration Properties Correct (a-props-correct) 19521 * 19522 * Validates the value constraints of an attribute declaration/use. 19523 * NOTE that this needs the simle type definitions to be already 19524 * builded and checked. 19525 */ 19526 static int 19527 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19528 xmlSchemaAttributePtr attr) 19529 { 19530 19531 /* 19532 * SPEC a-props-correct (1) 19533 * "The values of the properties of an attribute declaration must 19534 * be as described in the property tableau in The Attribute 19535 * Declaration Schema Component ($3.2.1), modulo the impact of 19536 * Missing Sub-components ($5.3)." 19537 */ 19538 19539 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19540 return(0); 19541 19542 if (attr->defValue != NULL) { 19543 int ret; 19544 19545 /* 19546 * SPEC a-props-correct (3) 19547 * "If the {type definition} is or is derived from ID then there 19548 * must not be a {value constraint}." 19549 */ 19550 if (xmlSchemaIsDerivedFromBuiltInType( 19551 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19552 { 19553 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19554 XML_SCHEMAP_A_PROPS_CORRECT_3, 19555 NULL, WXS_BASIC_CAST attr, 19556 "Value constraints are not allowed if the type definition " 19557 "is or is derived from xs:ID", 19558 NULL, NULL); 19559 return(pctxt->err); 19560 } 19561 /* 19562 * SPEC a-props-correct (2) 19563 * "if there is a {value constraint}, the canonical lexical 19564 * representation of its value must be `valid` with respect 19565 * to the {type definition} as defined in String Valid ($3.14.4)." 19566 * TODO: Don't care about the *canonical* stuff here, this requirement 19567 * will be removed in WXS 1.1 anyway. 19568 */ 19569 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19570 attr->node, WXS_ATTR_TYPEDEF(attr), 19571 attr->defValue, &(attr->defVal), 19572 1, 1, 0); 19573 if (ret != 0) { 19574 if (ret < 0) { 19575 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19576 "calling xmlSchemaVCheckCVCSimpleType()"); 19577 return(-1); 19578 } 19579 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19580 XML_SCHEMAP_A_PROPS_CORRECT_2, 19581 NULL, WXS_BASIC_CAST attr, 19582 "The value of the value constraint is not valid", 19583 NULL, NULL); 19584 return(pctxt->err); 19585 } 19586 } 19587 19588 return(0); 19589 } 19590 19591 static xmlSchemaElementPtr 19592 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19593 xmlSchemaElementPtr ancestor) 19594 { 19595 xmlSchemaElementPtr ret; 19596 19597 if (WXS_SUBST_HEAD(ancestor) == NULL) 19598 return (NULL); 19599 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19600 return (ancestor); 19601 19602 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19603 return (NULL); 19604 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19605 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19606 WXS_SUBST_HEAD(ancestor)); 19607 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19608 19609 return (ret); 19610 } 19611 19612 /** 19613 * xmlSchemaCheckElemPropsCorrect: 19614 * @ctxt: a schema parser context 19615 * @decl: the element declaration 19616 * @name: the name of the attribute 19617 * 19618 * Schema Component Constraint: 19619 * Element Declaration Properties Correct (e-props-correct) 19620 * 19621 * STATUS: 19622 * missing: (6) 19623 */ 19624 static int 19625 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19626 xmlSchemaElementPtr elemDecl) 19627 { 19628 int ret = 0; 19629 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19630 /* 19631 * SPEC (1) "The values of the properties of an element declaration 19632 * must be as described in the property tableau in The Element 19633 * Declaration Schema Component ($3.3.1), modulo the impact of Missing 19634 * Sub-components ($5.3)." 19635 */ 19636 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19637 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19638 19639 xmlSchemaCheckElementDeclComponent(head, pctxt); 19640 /* 19641 * SPEC (3) "If there is a non-`absent` {substitution group 19642 * affiliation}, then {scope} must be global." 19643 */ 19644 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19645 xmlSchemaPCustomErr(pctxt, 19646 XML_SCHEMAP_E_PROPS_CORRECT_3, 19647 WXS_BASIC_CAST elemDecl, NULL, 19648 "Only global element declarations can have a " 19649 "substitution group affiliation", NULL); 19650 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19651 } 19652 /* 19653 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19654 * That is, it must not be possible to return to an element declaration 19655 * by repeatedly following the {substitution group affiliation} 19656 * property." 19657 */ 19658 if (head == elemDecl) 19659 circ = head; 19660 else if (WXS_SUBST_HEAD(head) != NULL) 19661 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19662 else 19663 circ = NULL; 19664 if (circ != NULL) { 19665 xmlChar *strA = NULL, *strB = NULL; 19666 19667 xmlSchemaPCustomErrExt(pctxt, 19668 XML_SCHEMAP_E_PROPS_CORRECT_6, 19669 WXS_BASIC_CAST circ, NULL, 19670 "The element declaration '%s' defines a circular " 19671 "substitution group to element declaration '%s'", 19672 xmlSchemaGetComponentQName(&strA, circ), 19673 xmlSchemaGetComponentQName(&strB, head), 19674 NULL); 19675 FREE_AND_NULL(strA) 19676 FREE_AND_NULL(strB) 19677 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19678 } 19679 /* 19680 * SPEC (4) "If there is a {substitution group affiliation}, 19681 * the {type definition} 19682 * of the element declaration must be validly derived from the {type 19683 * definition} of the {substitution group affiliation}, given the value 19684 * of the {substitution group exclusions} of the {substitution group 19685 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6) 19686 * (if the {type definition} is complex) or as defined in 19687 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is 19688 * simple)." 19689 * 19690 * NOTE: {substitution group exclusions} means the values of the 19691 * attribute "final". 19692 */ 19693 19694 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19695 int set = 0; 19696 19697 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19698 set |= SUBSET_EXTENSION; 19699 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19700 set |= SUBSET_RESTRICTION; 19701 19702 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19703 WXS_ELEM_TYPEDEF(head), set) != 0) { 19704 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19705 19706 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19707 xmlSchemaPCustomErrExt(pctxt, 19708 XML_SCHEMAP_E_PROPS_CORRECT_4, 19709 WXS_BASIC_CAST elemDecl, NULL, 19710 "The type definition '%s' was " 19711 "either rejected by the substitution group " 19712 "affiliation '%s', or not validly derived from its type " 19713 "definition '%s'", 19714 xmlSchemaGetComponentQName(&strA, typeDef), 19715 xmlSchemaGetComponentQName(&strB, head), 19716 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19717 FREE_AND_NULL(strA) 19718 FREE_AND_NULL(strB) 19719 FREE_AND_NULL(strC) 19720 } 19721 } 19722 } 19723 /* 19724 * SPEC (5) "If the {type definition} or {type definition}'s 19725 * {content type} 19726 * is or is derived from ID then there must not be a {value constraint}. 19727 * Note: The use of ID as a type definition for elements goes beyond 19728 * XML 1.0, and should be avoided if backwards compatibility is desired" 19729 */ 19730 if ((elemDecl->value != NULL) && 19731 ((WXS_IS_SIMPLE(typeDef) && 19732 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19733 (WXS_IS_COMPLEX(typeDef) && 19734 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19735 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19736 XML_SCHEMAS_ID)))) { 19737 19738 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19739 xmlSchemaPCustomErr(pctxt, 19740 XML_SCHEMAP_E_PROPS_CORRECT_5, 19741 WXS_BASIC_CAST elemDecl, NULL, 19742 "The type definition (or type definition's content type) is or " 19743 "is derived from ID; value constraints are not allowed in " 19744 "conjunction with such a type definition", NULL); 19745 } else if (elemDecl->value != NULL) { 19746 int vcret; 19747 xmlNodePtr node = NULL; 19748 19749 /* 19750 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19751 * representation of its value must be `valid` with respect to the 19752 * {type definition} as defined in Element Default Valid (Immediate) 19753 * ($3.3.6)." 19754 */ 19755 if (typeDef == NULL) { 19756 xmlSchemaPErr(pctxt, elemDecl->node, 19757 XML_SCHEMAP_INTERNAL, 19758 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19759 "type is missing... skipping validation of " 19760 "the value constraint", NULL, NULL); 19761 return (-1); 19762 } 19763 if (elemDecl->node != NULL) { 19764 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19765 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19766 BAD_CAST "fixed"); 19767 else 19768 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19769 BAD_CAST "default"); 19770 } 19771 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19772 typeDef, elemDecl->value, &(elemDecl->defVal)); 19773 if (vcret != 0) { 19774 if (vcret < 0) { 19775 PERROR_INT("xmlSchemaElemCheckValConstr", 19776 "failed to validate the value constraint of an " 19777 "element declaration"); 19778 return (-1); 19779 } 19780 return (vcret); 19781 } 19782 } 19783 19784 return (ret); 19785 } 19786 19787 /** 19788 * xmlSchemaCheckElemSubstGroup: 19789 * @ctxt: a schema parser context 19790 * @decl: the element declaration 19791 * @name: the name of the attribute 19792 * 19793 * Schema Component Constraint: 19794 * Substitution Group (cos-equiv-class) 19795 * 19796 * In Libxml2 the subst. groups will be precomputed, in terms of that 19797 * a list will be built for each subst. group head, holding all direct 19798 * referents to this head. 19799 * NOTE that this function needs: 19800 * 1. circular subst. groups to be checked beforehand 19801 * 2. the declaration's type to be derived from the head's type 19802 * 19803 * STATUS: 19804 * 19805 */ 19806 static void 19807 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19808 xmlSchemaElementPtr elemDecl) 19809 { 19810 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19811 /* SPEC (1) "Its {abstract} is false." */ 19812 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19813 return; 19814 { 19815 xmlSchemaElementPtr head; 19816 xmlSchemaTypePtr headType, type; 19817 int set, methSet; 19818 /* 19819 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19820 * {disallowed substitutions} as the blocking constraint, as defined in 19821 * Substitution Group OK (Transitive) ($3.3.6)." 19822 */ 19823 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19824 head = WXS_SUBST_HEAD(head)) { 19825 set = 0; 19826 methSet = 0; 19827 /* 19828 * The blocking constraints. 19829 */ 19830 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19831 continue; 19832 headType = head->subtypes; 19833 type = elemDecl->subtypes; 19834 if (headType == type) 19835 goto add_member; 19836 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19837 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19838 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19839 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19840 /* 19841 * SPEC: Substitution Group OK (Transitive) (2.3) 19842 * "The set of all {derivation method}s involved in the 19843 * derivation of D's {type definition} from C's {type definition} 19844 * does not intersect with the union of the blocking constraint, 19845 * C's {prohibited substitutions} (if C is complex, otherwise the 19846 * empty set) and the {prohibited substitutions} (respectively the 19847 * empty set) of any intermediate {type definition}s in the 19848 * derivation of D's {type definition} from C's {type definition}." 19849 */ 19850 /* 19851 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19852 * subst.head axis, the methSet does not need to be computed for 19853 * the full depth over and over. 19854 */ 19855 /* 19856 * The set of all {derivation method}s involved in the derivation 19857 */ 19858 while ((type != NULL) && (type != headType)) { 19859 if ((WXS_IS_EXTENSION(type)) && 19860 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19861 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19862 19863 if (WXS_IS_RESTRICTION(type) && 19864 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19865 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19866 19867 type = type->baseType; 19868 } 19869 /* 19870 * The {prohibited substitutions} of all intermediate types + 19871 * the head's type. 19872 */ 19873 type = elemDecl->subtypes->baseType; 19874 while (type != NULL) { 19875 if (WXS_IS_COMPLEX(type)) { 19876 if ((type->flags & 19877 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19878 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19879 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19880 if ((type->flags & 19881 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19882 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19883 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19884 } else 19885 break; 19886 if (type == headType) 19887 break; 19888 type = type->baseType; 19889 } 19890 if ((set != 0) && 19891 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19892 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19893 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19894 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19895 continue; 19896 } 19897 add_member: 19898 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19899 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19900 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19901 } 19902 } 19903 } 19904 19905 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19906 /** 19907 * xmlSchemaCheckElementDeclComponent 19908 * @pctxt: the schema parser context 19909 * @ctxtComponent: the context component (an element declaration) 19910 * @ctxtParticle: the first particle of the context component 19911 * @searchParticle: the element declaration particle to be analysed 19912 * 19913 * Schema Component Constraint: Element Declarations Consistent 19914 */ 19915 static int 19916 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19917 xmlSchemaBasicItemPtr ctxtComponent, 19918 xmlSchemaParticlePtr ctxtParticle, 19919 xmlSchemaParticlePtr searchParticle, 19920 xmlSchemaParticlePtr curParticle, 19921 int search) 19922 { 19923 return(0); 19924 19925 int ret = 0; 19926 xmlSchemaParticlePtr cur = curParticle; 19927 if (curParticle == NULL) { 19928 return(0); 19929 } 19930 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19931 /* 19932 * Just return in this case. A missing "term" of the particle 19933 * might arise due to an invalid "term" component. 19934 */ 19935 return(0); 19936 } 19937 while (cur != NULL) { 19938 switch (WXS_PARTICLE_TERM(cur)->type) { 19939 case XML_SCHEMA_TYPE_ANY: 19940 break; 19941 case XML_SCHEMA_TYPE_ELEMENT: 19942 if (search == 0) { 19943 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19944 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19945 if (ret != 0) 19946 return(ret); 19947 } else { 19948 xmlSchemaElementPtr elem = 19949 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19950 /* 19951 * SPEC Element Declarations Consistent: 19952 * "If the {particles} contains, either directly, 19953 * indirectly (that is, within the {particles} of a 19954 * contained model group, recursively) or `implicitly` 19955 * two or more element declaration particles with 19956 * the same {name} and {target namespace}, then 19957 * all their type definitions must be the same 19958 * top-level definition [...]" 19959 */ 19960 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19961 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19962 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19963 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19964 { 19965 xmlChar *strA = NULL, *strB = NULL; 19966 19967 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19968 /* TODO: error code */ 19969 XML_SCHEMAP_COS_NONAMBIG, 19970 WXS_ITEM_NODE(cur), NULL, 19971 "In the content model of %s, there are multiple " 19972 "element declarations for '%s' with different " 19973 "type definitions", 19974 xmlSchemaGetComponentDesignation(&strA, 19975 ctxtComponent), 19976 xmlSchemaFormatQName(&strB, 19977 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19978 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19979 FREE_AND_NULL(strA); 19980 FREE_AND_NULL(strB); 19981 return(XML_SCHEMAP_COS_NONAMBIG); 19982 } 19983 } 19984 break; 19985 case XML_SCHEMA_TYPE_SEQUENCE: { 19986 break; 19987 } 19988 case XML_SCHEMA_TYPE_CHOICE:{ 19989 /* 19990 xmlSchemaTreeItemPtr sub; 19991 19992 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19993 while (sub != NULL) { 19994 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19995 ctxtParticle, ctxtElem); 19996 if (ret != 0) 19997 return(ret); 19998 sub = sub->next; 19999 } 20000 */ 20001 break; 20002 } 20003 case XML_SCHEMA_TYPE_ALL: 20004 break; 20005 case XML_SCHEMA_TYPE_GROUP: 20006 break; 20007 default: 20008 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 20009 "xmlSchemaCheckElementDeclConsistent", 20010 "found unexpected term of type '%s' in content model", 20011 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 20012 return(-1); 20013 } 20014 cur = (xmlSchemaParticlePtr) cur->next; 20015 } 20016 20017 exit: 20018 return(ret); 20019 } 20020 #endif 20021 20022 /** 20023 * xmlSchemaCheckElementDeclComponent 20024 * @item: an schema element declaration/particle 20025 * @ctxt: a schema parser context 20026 * @name: the name of the attribute 20027 * 20028 * Validates the value constraints of an element declaration. 20029 * Adds substitution group members. 20030 */ 20031 static void 20032 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 20033 xmlSchemaParserCtxtPtr ctxt) 20034 { 20035 if (elemDecl == NULL) 20036 return; 20037 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 20038 return; 20039 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 20040 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 20041 /* 20042 * Adds substitution group members. 20043 */ 20044 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 20045 } 20046 } 20047 20048 /** 20049 * xmlSchemaResolveModelGroupParticleReferences: 20050 * @particle: a particle component 20051 * @ctxt: a parser context 20052 * 20053 * Resolves references of a model group's {particles} to 20054 * model group definitions and to element declarations. 20055 */ 20056 static void 20057 xmlSchemaResolveModelGroupParticleReferences( 20058 xmlSchemaParserCtxtPtr ctxt, 20059 xmlSchemaModelGroupPtr mg) 20060 { 20061 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 20062 xmlSchemaQNameRefPtr ref; 20063 xmlSchemaBasicItemPtr refItem; 20064 20065 /* 20066 * URGENT TODO: Test this. 20067 */ 20068 while (particle != NULL) { 20069 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20070 ((WXS_PARTICLE_TERM(particle))->type != 20071 XML_SCHEMA_EXTRA_QNAMEREF)) 20072 { 20073 goto next_particle; 20074 } 20075 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20076 /* 20077 * Resolve the reference. 20078 * NULL the {term} by default. 20079 */ 20080 particle->children = NULL; 20081 20082 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20083 ref->itemType, ref->name, ref->targetNamespace); 20084 if (refItem == NULL) { 20085 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20086 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20087 ref->targetNamespace, ref->itemType, NULL); 20088 /* TODO: remove the particle. */ 20089 goto next_particle; 20090 } 20091 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20092 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20093 /* TODO: remove the particle. */ 20094 goto next_particle; 20095 /* 20096 * NOTE that we will assign the model group definition 20097 * itself to the "term" of the particle. This will ease 20098 * the check for circular model group definitions. After 20099 * that the "term" will be assigned the model group of the 20100 * model group definition. 20101 */ 20102 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20103 XML_SCHEMA_TYPE_ALL) { 20104 /* 20105 * SPEC cos-all-limited (1) 20106 * SPEC cos-all-limited (1.2) 20107 * "It appears only as the value of one or both of the 20108 * following properties:" 20109 * (1.1) "the {model group} property of a model group 20110 * definition." 20111 * (1.2) "the {term} property of a particle [... of] the " 20112 * {content type} of a complex type definition." 20113 */ 20114 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20115 /* TODO: error code */ 20116 XML_SCHEMAP_COS_ALL_LIMITED, 20117 WXS_ITEM_NODE(particle), NULL, 20118 "A model group definition is referenced, but " 20119 "it contains an 'all' model group, which " 20120 "cannot be contained by model groups", 20121 NULL, NULL); 20122 /* TODO: remove the particle. */ 20123 goto next_particle; 20124 } 20125 particle->children = (xmlSchemaTreeItemPtr) refItem; 20126 } else { 20127 /* 20128 * TODO: Are referenced element declarations the only 20129 * other components we expect here? 20130 */ 20131 particle->children = (xmlSchemaTreeItemPtr) refItem; 20132 } 20133 next_particle: 20134 particle = WXS_PTC_CAST particle->next; 20135 } 20136 } 20137 20138 static int 20139 xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20140 xmlSchemaValPtr y) 20141 { 20142 xmlSchemaTypePtr tx, ty, ptx, pty; 20143 int ret; 20144 20145 while (x != NULL) { 20146 /* Same types. */ 20147 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20148 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20149 ptx = xmlSchemaGetPrimitiveType(tx); 20150 pty = xmlSchemaGetPrimitiveType(ty); 20151 /* 20152 * (1) if a datatype T' is `derived` by `restriction` from an 20153 * atomic datatype T then the `value space` of T' is a subset of 20154 * the `value space` of T. */ 20155 /* 20156 * (2) if datatypes T' and T'' are `derived` by `restriction` 20157 * from a common atomic ancestor T then the `value space`s of T' 20158 * and T'' may overlap. 20159 */ 20160 if (ptx != pty) 20161 return(0); 20162 /* 20163 * We assume computed values to be normalized, so do a fast 20164 * string comparison for string based types. 20165 */ 20166 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20167 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20168 if (! xmlStrEqual( 20169 xmlSchemaValueGetAsString(x), 20170 xmlSchemaValueGetAsString(y))) 20171 return (0); 20172 } else { 20173 ret = xmlSchemaCompareValuesWhtsp( 20174 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20175 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20176 if (ret == -2) 20177 return(-1); 20178 if (ret != 0) 20179 return(0); 20180 } 20181 /* 20182 * Lists. 20183 */ 20184 x = xmlSchemaValueGetNext(x); 20185 if (x != NULL) { 20186 y = xmlSchemaValueGetNext(y); 20187 if (y == NULL) 20188 return (0); 20189 } else if (xmlSchemaValueGetNext(y) != NULL) 20190 return (0); 20191 else 20192 return (1); 20193 } 20194 return (0); 20195 } 20196 20197 /** 20198 * xmlSchemaResolveAttrUseReferences: 20199 * @item: an attribute use 20200 * @ctxt: a parser context 20201 * 20202 * Resolves the referenced attribute declaration. 20203 */ 20204 static int 20205 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20206 xmlSchemaParserCtxtPtr ctxt) 20207 { 20208 if ((ctxt == NULL) || (ause == NULL)) 20209 return(-1); 20210 if ((ause->attrDecl == NULL) || 20211 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20212 return(0); 20213 20214 { 20215 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20216 20217 /* 20218 * TODO: Evaluate, what errors could occur if the declaration is not 20219 * found. 20220 */ 20221 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20222 ref->name, ref->targetNamespace); 20223 if (ause->attrDecl == NULL) { 20224 xmlSchemaPResCompAttrErr(ctxt, 20225 XML_SCHEMAP_SRC_RESOLVE, 20226 WXS_BASIC_CAST ause, ause->node, 20227 "ref", ref->name, ref->targetNamespace, 20228 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20229 return(ctxt->err);; 20230 } 20231 } 20232 return(0); 20233 } 20234 20235 /** 20236 * xmlSchemaCheckAttrUsePropsCorrect: 20237 * @ctxt: a parser context 20238 * @use: an attribute use 20239 * 20240 * Schema Component Constraint: 20241 * Attribute Use Correct (au-props-correct) 20242 * 20243 */ 20244 static int 20245 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20246 xmlSchemaAttributeUsePtr use) 20247 { 20248 if ((ctxt == NULL) || (use == NULL)) 20249 return(-1); 20250 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20251 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20252 return(0); 20253 20254 /* 20255 * SPEC au-props-correct (1) 20256 * "The values of the properties of an attribute use must be as 20257 * described in the property tableau in The Attribute Use Schema 20258 * Component ($3.5.1), modulo the impact of Missing 20259 * Sub-components ($5.3)." 20260 */ 20261 20262 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20263 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20264 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20265 { 20266 xmlSchemaPCustomErr(ctxt, 20267 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20268 WXS_BASIC_CAST use, NULL, 20269 "The attribute declaration has a 'fixed' value constraint " 20270 ", thus the attribute use must also have a 'fixed' value " 20271 "constraint", 20272 NULL); 20273 return(ctxt->err); 20274 } 20275 /* 20276 * Compute and check the value constraint's value. 20277 */ 20278 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20279 int ret; 20280 /* 20281 * TODO: The spec seems to be missing a check of the 20282 * value constraint of the attribute use. We will do it here. 20283 */ 20284 /* 20285 * SPEC a-props-correct (3) 20286 */ 20287 if (xmlSchemaIsDerivedFromBuiltInType( 20288 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20289 { 20290 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20291 XML_SCHEMAP_AU_PROPS_CORRECT, 20292 NULL, WXS_BASIC_CAST use, 20293 "Value constraints are not allowed if the type definition " 20294 "is or is derived from xs:ID", 20295 NULL, NULL); 20296 return(ctxt->err); 20297 } 20298 20299 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20300 use->node, WXS_ATTRUSE_TYPEDEF(use), 20301 use->defValue, &(use->defVal), 20302 1, 1, 0); 20303 if (ret != 0) { 20304 if (ret < 0) { 20305 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20306 "calling xmlSchemaVCheckCVCSimpleType()"); 20307 return(-1); 20308 } 20309 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20310 XML_SCHEMAP_AU_PROPS_CORRECT, 20311 NULL, WXS_BASIC_CAST use, 20312 "The value of the value constraint is not valid", 20313 NULL, NULL); 20314 return(ctxt->err); 20315 } 20316 } 20317 /* 20318 * SPEC au-props-correct (2) 20319 * "If the {attribute declaration} has a fixed 20320 * {value constraint}, then if the attribute use itself has a 20321 * {value constraint}, it must also be fixed and its value must match 20322 * that of the {attribute declaration}'s {value constraint}." 20323 */ 20324 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20325 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20326 { 20327 if (! xmlSchemaAreValuesEqual(use->defVal, 20328 (WXS_ATTRUSE_DECL(use))->defVal)) 20329 { 20330 xmlSchemaPCustomErr(ctxt, 20331 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20332 WXS_BASIC_CAST use, NULL, 20333 "The 'fixed' value constraint of the attribute use " 20334 "must match the attribute declaration's value " 20335 "constraint '%s'", 20336 (WXS_ATTRUSE_DECL(use))->defValue); 20337 } 20338 return(ctxt->err); 20339 } 20340 return(0); 20341 } 20342 20343 20344 20345 20346 /** 20347 * xmlSchemaResolveAttrTypeReferences: 20348 * @item: an attribute declaration 20349 * @ctxt: a parser context 20350 * 20351 * Resolves the referenced type definition component. 20352 */ 20353 static int 20354 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20355 xmlSchemaParserCtxtPtr ctxt) 20356 { 20357 /* 20358 * The simple type definition corresponding to the <simpleType> element 20359 * information item in the [children], if present, otherwise the simple 20360 * type definition `resolved` to by the `actual value` of the type 20361 * [attribute], if present, otherwise the `simple ur-type definition`. 20362 */ 20363 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20364 return(0); 20365 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20366 if (item->subtypes != NULL) 20367 return(0); 20368 if (item->typeName != NULL) { 20369 xmlSchemaTypePtr type; 20370 20371 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20372 item->typeNs); 20373 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20374 xmlSchemaPResCompAttrErr(ctxt, 20375 XML_SCHEMAP_SRC_RESOLVE, 20376 WXS_BASIC_CAST item, item->node, 20377 "type", item->typeName, item->typeNs, 20378 XML_SCHEMA_TYPE_SIMPLE, NULL); 20379 return(ctxt->err); 20380 } else 20381 item->subtypes = type; 20382 20383 } else { 20384 /* 20385 * The type defaults to the xs:anySimpleType. 20386 */ 20387 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20388 } 20389 return(0); 20390 } 20391 20392 /** 20393 * xmlSchemaResolveIDCKeyReferences: 20394 * @idc: the identity-constraint definition 20395 * @ctxt: the schema parser context 20396 * @name: the attribute name 20397 * 20398 * Resolve keyRef references to key/unique IDCs. 20399 * Schema Component Constraint: 20400 * Identity-constraint Definition Properties Correct (c-props-correct) 20401 */ 20402 static int 20403 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20404 xmlSchemaParserCtxtPtr pctxt) 20405 { 20406 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20407 return(0); 20408 if (idc->ref->name != NULL) { 20409 idc->ref->item = (xmlSchemaBasicItemPtr) 20410 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20411 idc->ref->targetNamespace); 20412 if (idc->ref->item == NULL) { 20413 /* 20414 * TODO: It is actually not an error to fail to resolve 20415 * at this stage. BUT we need to be that strict! 20416 */ 20417 xmlSchemaPResCompAttrErr(pctxt, 20418 XML_SCHEMAP_SRC_RESOLVE, 20419 WXS_BASIC_CAST idc, idc->node, 20420 "refer", idc->ref->name, 20421 idc->ref->targetNamespace, 20422 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20423 return(pctxt->err); 20424 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20425 /* 20426 * SPEC c-props-correct (1) 20427 */ 20428 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20429 XML_SCHEMAP_C_PROPS_CORRECT, 20430 NULL, WXS_BASIC_CAST idc, 20431 "The keyref references a keyref", 20432 NULL, NULL); 20433 idc->ref->item = NULL; 20434 return(pctxt->err); 20435 } else { 20436 if (idc->nbFields != 20437 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20438 xmlChar *str = NULL; 20439 xmlSchemaIDCPtr refer; 20440 20441 refer = (xmlSchemaIDCPtr) idc->ref->item; 20442 /* 20443 * SPEC c-props-correct(2) 20444 * "If the {identity-constraint category} is keyref, 20445 * the cardinality of the {fields} must equal that of 20446 * the {fields} of the {referenced key}. 20447 */ 20448 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20449 XML_SCHEMAP_C_PROPS_CORRECT, 20450 NULL, WXS_BASIC_CAST idc, 20451 "The cardinality of the keyref differs from the " 20452 "cardinality of the referenced key/unique '%s'", 20453 xmlSchemaFormatQName(&str, refer->targetNamespace, 20454 refer->name), 20455 NULL); 20456 FREE_AND_NULL(str) 20457 return(pctxt->err); 20458 } 20459 } 20460 } 20461 return(0); 20462 } 20463 20464 static int 20465 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20466 xmlSchemaParserCtxtPtr pctxt) 20467 { 20468 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20469 prohib->targetNamespace) == NULL) { 20470 20471 xmlSchemaPResCompAttrErr(pctxt, 20472 XML_SCHEMAP_SRC_RESOLVE, 20473 NULL, prohib->node, 20474 "ref", prohib->name, prohib->targetNamespace, 20475 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20476 return(XML_SCHEMAP_SRC_RESOLVE); 20477 } 20478 return(0); 20479 } 20480 20481 #define WXS_REDEFINED_TYPE(c) \ 20482 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20483 20484 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20485 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20486 20487 #define WXS_REDEFINED_ATTR_GROUP(c) \ 20488 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20489 20490 static int 20491 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20492 { 20493 int err = 0; 20494 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20495 xmlSchemaBasicItemPtr prev, item; 20496 int wasRedefined; 20497 20498 if (redef == NULL) 20499 return(0); 20500 20501 do { 20502 item = redef->item; 20503 /* 20504 * First try to locate the redefined component in the 20505 * schema graph starting with the redefined schema. 20506 * NOTE: According to this schema bug entry: 20507 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20508 * it's not clear if the referenced component needs to originate 20509 * from the <redefine>d schema _document_ or the schema; the latter 20510 * would include all imported and included sub-schemas of the 20511 * <redefine>d schema. Currenlty we latter approach is used. 20512 * SUPPLEMENT: It seems that the WG moves towards the latter 20513 * approach, so we are doing it right. 20514 * 20515 */ 20516 prev = xmlSchemaFindRedefCompInGraph( 20517 redef->targetBucket, item->type, 20518 redef->refName, redef->refTargetNs); 20519 if (prev == NULL) { 20520 xmlChar *str = NULL; 20521 xmlNodePtr node; 20522 20523 /* 20524 * SPEC src-redefine: 20525 * (6.2.1) "The `actual value` of its own name attribute plus 20526 * target namespace must successfully `resolve` to a model 20527 * group definition in I." 20528 * (7.2.1) "The `actual value` of its own name attribute plus 20529 * target namespace must successfully `resolve` to an attribute 20530 * group definition in I." 20531 20532 * 20533 * Note that, if we are redefining with the use of references 20534 * to components, the spec assumes the src-resolve to be used; 20535 * but this won't assure that we search only *inside* the 20536 * redefined schema. 20537 */ 20538 if (redef->reference) 20539 node = WXS_ITEM_NODE(redef->reference); 20540 else 20541 node = WXS_ITEM_NODE(item); 20542 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20543 /* 20544 * TODO: error code. 20545 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20546 * reference kind. 20547 */ 20548 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20549 "The %s '%s' to be redefined could not be found in " 20550 "the redefined schema", 20551 WXS_ITEM_TYPE_NAME(item), 20552 xmlSchemaFormatQName(&str, redef->refTargetNs, 20553 redef->refName)); 20554 FREE_AND_NULL(str); 20555 err = pctxt->err; 20556 redef = redef->next; 20557 continue; 20558 } 20559 /* 20560 * TODO: Obtaining and setting the redefinition state is really 20561 * clumsy. 20562 */ 20563 wasRedefined = 0; 20564 switch (item->type) { 20565 case XML_SCHEMA_TYPE_COMPLEX: 20566 case XML_SCHEMA_TYPE_SIMPLE: 20567 if ((WXS_TYPE_CAST prev)->flags & 20568 XML_SCHEMAS_TYPE_REDEFINED) 20569 { 20570 wasRedefined = 1; 20571 break; 20572 } 20573 /* Mark it as redefined. */ 20574 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20575 /* 20576 * Assign the redefined type to the 20577 * base type of the redefining type. 20578 * TODO: How 20579 */ 20580 ((xmlSchemaTypePtr) item)->baseType = 20581 (xmlSchemaTypePtr) prev; 20582 break; 20583 case XML_SCHEMA_TYPE_GROUP: 20584 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20585 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20586 { 20587 wasRedefined = 1; 20588 break; 20589 } 20590 /* Mark it as redefined. */ 20591 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20592 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20593 if (redef->reference != NULL) { 20594 /* 20595 * Overwrite the QName-reference with the 20596 * referenced model group def. 20597 */ 20598 (WXS_PTC_CAST redef->reference)->children = 20599 WXS_TREE_CAST prev; 20600 } 20601 redef->target = prev; 20602 break; 20603 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20604 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20605 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20606 { 20607 wasRedefined = 1; 20608 break; 20609 } 20610 (WXS_ATTR_GROUP_CAST prev)->flags |= 20611 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20612 if (redef->reference != NULL) { 20613 /* 20614 * Assign the redefined attribute group to the 20615 * QName-reference component. 20616 * This is the easy case, since we will just 20617 * expand the redefined group. 20618 */ 20619 (WXS_QNAME_CAST redef->reference)->item = prev; 20620 redef->target = NULL; 20621 } else { 20622 /* 20623 * This is the complicated case: we need 20624 * to apply src-redefine (7.2.2) at a later 20625 * stage, i.e. when attribute group references 20626 * have beed expanded and simple types have 20627 * beed fixed. 20628 */ 20629 redef->target = prev; 20630 } 20631 break; 20632 default: 20633 PERROR_INT("xmlSchemaResolveRedefReferences", 20634 "Unexpected redefined component type"); 20635 return(-1); 20636 } 20637 if (wasRedefined) { 20638 xmlChar *str = NULL; 20639 xmlNodePtr node; 20640 20641 if (redef->reference) 20642 node = WXS_ITEM_NODE(redef->reference); 20643 else 20644 node = WXS_ITEM_NODE(redef->item); 20645 20646 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20647 /* TODO: error code. */ 20648 XML_SCHEMAP_SRC_REDEFINE, 20649 node, NULL, 20650 "The referenced %s was already redefined. Multiple " 20651 "redefinition of the same component is not supported", 20652 xmlSchemaGetComponentDesignation(&str, prev), 20653 NULL); 20654 FREE_AND_NULL(str) 20655 err = pctxt->err; 20656 redef = redef->next; 20657 continue; 20658 } 20659 redef = redef->next; 20660 } while (redef != NULL); 20661 20662 return(err); 20663 } 20664 20665 static int 20666 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20667 { 20668 int err = 0; 20669 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20670 xmlSchemaBasicItemPtr item; 20671 20672 if (redef == NULL) 20673 return(0); 20674 20675 do { 20676 if (redef->target == NULL) { 20677 redef = redef->next; 20678 continue; 20679 } 20680 item = redef->item; 20681 20682 switch (item->type) { 20683 case XML_SCHEMA_TYPE_SIMPLE: 20684 case XML_SCHEMA_TYPE_COMPLEX: 20685 /* 20686 * Since the spec wants the {name} of the redefined 20687 * type to be 'absent', we'll NULL it. 20688 */ 20689 (WXS_TYPE_CAST redef->target)->name = NULL; 20690 20691 /* 20692 * TODO: Seems like there's nothing more to do. The normal 20693 * inheritance mechanism is used. But not 100% sure. 20694 */ 20695 break; 20696 case XML_SCHEMA_TYPE_GROUP: 20697 /* 20698 * URGENT TODO: 20699 * SPEC src-redefine: 20700 * (6.2.2) "The {model group} of the model group definition 20701 * which corresponds to it per XML Representation of Model 20702 * Group Definition Schema Components ($3.7.2) must be a 20703 * `valid restriction` of the {model group} of that model 20704 * group definition in I, as defined in Particle Valid 20705 * (Restriction) ($3.9.6)." 20706 */ 20707 break; 20708 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20709 /* 20710 * SPEC src-redefine: 20711 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20712 * the attribute group definition which corresponds to it 20713 * per XML Representation of Attribute Group Definition Schema 20714 * Components ($3.6.2) must be `valid restrictions` of the 20715 * {attribute uses} and {attribute wildcard} of that attribute 20716 * group definition in I, as defined in clause 2, clause 3 and 20717 * clause 4 of Derivation Valid (Restriction, Complex) 20718 * ($3.4.6) (where references to the base type definition are 20719 * understood as references to the attribute group definition 20720 * in I)." 20721 */ 20722 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20723 XML_SCHEMA_ACTION_REDEFINE, 20724 item, redef->target, 20725 (WXS_ATTR_GROUP_CAST item)->attrUses, 20726 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20727 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20728 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20729 if (err == -1) 20730 return(-1); 20731 break; 20732 default: 20733 break; 20734 } 20735 redef = redef->next; 20736 } while (redef != NULL); 20737 return(0); 20738 } 20739 20740 20741 static int 20742 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20743 xmlSchemaBucketPtr bucket) 20744 { 20745 xmlSchemaBasicItemPtr item; 20746 int err; 20747 xmlHashTablePtr *table; 20748 const xmlChar *name; 20749 int i; 20750 20751 #define WXS_GET_GLOBAL_HASH(c, slot) { \ 20752 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20753 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20754 else \ 20755 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20756 20757 /* 20758 * Add global components to the schema's hash tables. 20759 * This is the place where duplicate components will be 20760 * detected. 20761 * TODO: I think normally we should support imports of the 20762 * same namespace from multiple locations. We don't do currently, 20763 * but if we do then according to: 20764 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20765 * we would need, if imported directly, to import redefined 20766 * components as well to be able to catch clashing components. 20767 * (I hope I'll still know what this means after some months :-() 20768 */ 20769 if (bucket == NULL) 20770 return(-1); 20771 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20772 return(0); 20773 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20774 20775 for (i = 0; i < bucket->globals->nbItems; i++) { 20776 item = bucket->globals->items[i]; 20777 table = NULL; 20778 switch (item->type) { 20779 case XML_SCHEMA_TYPE_COMPLEX: 20780 case XML_SCHEMA_TYPE_SIMPLE: 20781 if (WXS_REDEFINED_TYPE(item)) 20782 continue; 20783 name = (WXS_TYPE_CAST item)->name; 20784 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20785 break; 20786 case XML_SCHEMA_TYPE_ELEMENT: 20787 name = (WXS_ELEM_CAST item)->name; 20788 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20789 break; 20790 case XML_SCHEMA_TYPE_ATTRIBUTE: 20791 name = (WXS_ATTR_CAST item)->name; 20792 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20793 break; 20794 case XML_SCHEMA_TYPE_GROUP: 20795 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20796 continue; 20797 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20798 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20799 break; 20800 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20801 if (WXS_REDEFINED_ATTR_GROUP(item)) 20802 continue; 20803 name = (WXS_ATTR_GROUP_CAST item)->name; 20804 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20805 break; 20806 case XML_SCHEMA_TYPE_IDC_KEY: 20807 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20808 case XML_SCHEMA_TYPE_IDC_KEYREF: 20809 name = (WXS_IDC_CAST item)->name; 20810 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20811 break; 20812 case XML_SCHEMA_TYPE_NOTATION: 20813 name = ((xmlSchemaNotationPtr) item)->name; 20814 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20815 break; 20816 default: 20817 PERROR_INT("xmlSchemaAddComponents", 20818 "Unexpected global component type"); 20819 continue; 20820 } 20821 if (*table == NULL) { 20822 *table = xmlHashCreateDict(10, pctxt->dict); 20823 if (*table == NULL) { 20824 PERROR_INT("xmlSchemaAddComponents", 20825 "failed to create a component hash table"); 20826 return(-1); 20827 } 20828 } 20829 err = xmlHashAddEntry(*table, name, item); 20830 if (err != 0) { 20831 xmlChar *str = NULL; 20832 20833 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20834 XML_SCHEMAP_REDEFINED_TYPE, 20835 WXS_ITEM_NODE(item), 20836 WXS_BASIC_CAST item, 20837 "A global %s '%s' does already exist", 20838 WXS_ITEM_TYPE_NAME(item), 20839 xmlSchemaGetComponentQName(&str, item)); 20840 FREE_AND_NULL(str); 20841 } 20842 } 20843 /* 20844 * Process imported/included schemas. 20845 */ 20846 if (bucket->relations != NULL) { 20847 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20848 do { 20849 if ((rel->bucket != NULL) && 20850 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20851 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20852 return(-1); 20853 } 20854 rel = rel->next; 20855 } while (rel != NULL); 20856 } 20857 return(0); 20858 } 20859 20860 static int 20861 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20862 xmlSchemaBucketPtr rootBucket) 20863 { 20864 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20865 xmlSchemaTreeItemPtr item, *items; 20866 int nbItems, i, ret = 0; 20867 xmlSchemaBucketPtr oldbucket = con->bucket; 20868 xmlSchemaElementPtr elemDecl; 20869 20870 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20871 20872 if ((con->pending == NULL) || 20873 (con->pending->nbItems == 0)) 20874 return(0); 20875 20876 /* 20877 * Since xmlSchemaFixupComplexType() will create new particles 20878 * (local components), and those particle components need a bucket 20879 * on the constructor, we'll assure here that the constructor has 20880 * a bucket. 20881 * TODO: Think about storing locals _only_ on the main bucket. 20882 */ 20883 if (con->bucket == NULL) 20884 con->bucket = rootBucket; 20885 20886 /* TODO: 20887 * SPEC (src-redefine): 20888 * (6.2) "If it has no such self-reference, then all of the 20889 * following must be true:" 20890 20891 * (6.2.2) The {model group} of the model group definition which 20892 * corresponds to it per XML Representation of Model Group 20893 * Definition Schema Components ($3.7.2) must be a `valid 20894 * restriction` of the {model group} of that model group definition 20895 * in I, as defined in Particle Valid (Restriction) ($3.9.6)." 20896 */ 20897 xmlSchemaCheckSRCRedefineFirst(pctxt); 20898 20899 /* 20900 * Add global components to the schemata's hash tables. 20901 */ 20902 xmlSchemaAddComponents(pctxt, rootBucket); 20903 20904 pctxt->ctxtType = NULL; 20905 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20906 nbItems = con->pending->nbItems; 20907 /* 20908 * Now that we have parsed *all* the schema document(s) and converted 20909 * them to schema components, we can resolve references, apply component 20910 * constraints, create the FSA from the content model, etc. 20911 */ 20912 /* 20913 * Resolve references of.. 20914 * 20915 * 1. element declarations: 20916 * - the type definition 20917 * - the substitution group affiliation 20918 * 2. simple/complex types: 20919 * - the base type definition 20920 * - the memberTypes of union types 20921 * - the itemType of list types 20922 * 3. attributes declarations and attribute uses: 20923 * - the type definition 20924 * - if an attribute use, then the attribute declaration 20925 * 4. attribute group references: 20926 * - the attribute group definition 20927 * 5. particles: 20928 * - the term of the particle (e.g. a model group) 20929 * 6. IDC key-references: 20930 * - the referenced IDC 'key' or 'unique' definition 20931 * 7. Attribute prohibitions which had a "ref" attribute. 20932 */ 20933 for (i = 0; i < nbItems; i++) { 20934 item = items[i]; 20935 switch (item->type) { 20936 case XML_SCHEMA_TYPE_ELEMENT: 20937 xmlSchemaResolveElementReferences( 20938 (xmlSchemaElementPtr) item, pctxt); 20939 FIXHFAILURE; 20940 break; 20941 case XML_SCHEMA_TYPE_COMPLEX: 20942 case XML_SCHEMA_TYPE_SIMPLE: 20943 xmlSchemaResolveTypeReferences( 20944 (xmlSchemaTypePtr) item, pctxt); 20945 FIXHFAILURE; 20946 break; 20947 case XML_SCHEMA_TYPE_ATTRIBUTE: 20948 xmlSchemaResolveAttrTypeReferences( 20949 (xmlSchemaAttributePtr) item, pctxt); 20950 FIXHFAILURE; 20951 break; 20952 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20953 xmlSchemaResolveAttrUseReferences( 20954 (xmlSchemaAttributeUsePtr) item, pctxt); 20955 FIXHFAILURE; 20956 break; 20957 case XML_SCHEMA_EXTRA_QNAMEREF: 20958 if ((WXS_QNAME_CAST item)->itemType == 20959 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20960 { 20961 xmlSchemaResolveAttrGroupReferences( 20962 WXS_QNAME_CAST item, pctxt); 20963 } 20964 FIXHFAILURE; 20965 break; 20966 case XML_SCHEMA_TYPE_SEQUENCE: 20967 case XML_SCHEMA_TYPE_CHOICE: 20968 case XML_SCHEMA_TYPE_ALL: 20969 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20970 WXS_MODEL_GROUP_CAST item); 20971 FIXHFAILURE; 20972 break; 20973 case XML_SCHEMA_TYPE_IDC_KEY: 20974 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20975 case XML_SCHEMA_TYPE_IDC_KEYREF: 20976 xmlSchemaResolveIDCKeyReferences( 20977 (xmlSchemaIDCPtr) item, pctxt); 20978 FIXHFAILURE; 20979 break; 20980 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20981 /* 20982 * Handle attribue prohibition which had a 20983 * "ref" attribute. 20984 */ 20985 xmlSchemaResolveAttrUseProhibReferences( 20986 WXS_ATTR_PROHIB_CAST item, pctxt); 20987 FIXHFAILURE; 20988 break; 20989 default: 20990 break; 20991 } 20992 } 20993 if (pctxt->nberrors != 0) 20994 goto exit_error; 20995 20996 /* 20997 * Now that all references are resolved we 20998 * can check for circularity of... 20999 * 1. the base axis of type definitions 21000 * 2. nested model group definitions 21001 * 3. nested attribute group definitions 21002 * TODO: check for circual substitution groups. 21003 */ 21004 for (i = 0; i < nbItems; i++) { 21005 item = items[i]; 21006 /* 21007 * Let's better stop on the first error here. 21008 */ 21009 switch (item->type) { 21010 case XML_SCHEMA_TYPE_COMPLEX: 21011 case XML_SCHEMA_TYPE_SIMPLE: 21012 xmlSchemaCheckTypeDefCircular( 21013 (xmlSchemaTypePtr) item, pctxt); 21014 FIXHFAILURE; 21015 if (pctxt->nberrors != 0) 21016 goto exit_error; 21017 break; 21018 case XML_SCHEMA_TYPE_GROUP: 21019 xmlSchemaCheckGroupDefCircular( 21020 (xmlSchemaModelGroupDefPtr) item, pctxt); 21021 FIXHFAILURE; 21022 if (pctxt->nberrors != 0) 21023 goto exit_error; 21024 break; 21025 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21026 xmlSchemaCheckAttrGroupCircular( 21027 (xmlSchemaAttributeGroupPtr) item, pctxt); 21028 FIXHFAILURE; 21029 if (pctxt->nberrors != 0) 21030 goto exit_error; 21031 break; 21032 default: 21033 break; 21034 } 21035 } 21036 if (pctxt->nberrors != 0) 21037 goto exit_error; 21038 /* 21039 * Model group definition references: 21040 * Such a reference is reflected by a particle at the component 21041 * level. Until now the 'term' of such particles pointed 21042 * to the model group definition; this was done, in order to 21043 * ease circularity checks. Now we need to set the 'term' of 21044 * such particles to the model group of the model group definition. 21045 */ 21046 for (i = 0; i < nbItems; i++) { 21047 item = items[i]; 21048 switch (item->type) { 21049 case XML_SCHEMA_TYPE_SEQUENCE: 21050 case XML_SCHEMA_TYPE_CHOICE: 21051 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 21052 WXS_MODEL_GROUP_CAST item); 21053 break; 21054 default: 21055 break; 21056 } 21057 } 21058 if (pctxt->nberrors != 0) 21059 goto exit_error; 21060 /* 21061 * Expand attribute group references of attribute group definitions. 21062 */ 21063 for (i = 0; i < nbItems; i++) { 21064 item = items[i]; 21065 switch (item->type) { 21066 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21067 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 21068 WXS_ATTR_GROUP_HAS_REFS(item)) 21069 { 21070 xmlSchemaAttributeGroupExpandRefs(pctxt, 21071 WXS_ATTR_GROUP_CAST item); 21072 FIXHFAILURE; 21073 } 21074 break; 21075 default: 21076 break; 21077 } 21078 } 21079 if (pctxt->nberrors != 0) 21080 goto exit_error; 21081 /* 21082 * First compute the variety of simple types. This is needed as 21083 * a seperate step, since otherwise we won't be able to detect 21084 * circular union types in all cases. 21085 */ 21086 for (i = 0; i < nbItems; i++) { 21087 item = items[i]; 21088 switch (item->type) { 21089 case XML_SCHEMA_TYPE_SIMPLE: 21090 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21091 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21092 (xmlSchemaTypePtr) item); 21093 FIXHFAILURE; 21094 } 21095 break; 21096 default: 21097 break; 21098 } 21099 } 21100 if (pctxt->nberrors != 0) 21101 goto exit_error; 21102 /* 21103 * Detect circular union types. Note that this needs the variety to 21104 * be already computed. 21105 */ 21106 for (i = 0; i < nbItems; i++) { 21107 item = items[i]; 21108 switch (item->type) { 21109 case XML_SCHEMA_TYPE_SIMPLE: 21110 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21111 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21112 (xmlSchemaTypePtr) item); 21113 FIXHFAILURE; 21114 } 21115 break; 21116 default: 21117 break; 21118 } 21119 } 21120 if (pctxt->nberrors != 0) 21121 goto exit_error; 21122 21123 /* 21124 * Do the complete type fixup for simple types. 21125 */ 21126 for (i = 0; i < nbItems; i++) { 21127 item = items[i]; 21128 switch (item->type) { 21129 case XML_SCHEMA_TYPE_SIMPLE: 21130 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21131 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21132 FIXHFAILURE; 21133 } 21134 break; 21135 default: 21136 break; 21137 } 21138 } 21139 if (pctxt->nberrors != 0) 21140 goto exit_error; 21141 /* 21142 * At this point we need build and check all simple types. 21143 */ 21144 /* 21145 * Apply contraints for attribute declarations. 21146 */ 21147 for (i = 0; i < nbItems; i++) { 21148 item = items[i]; 21149 switch (item->type) { 21150 case XML_SCHEMA_TYPE_ATTRIBUTE: 21151 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21152 FIXHFAILURE; 21153 break; 21154 default: 21155 break; 21156 } 21157 } 21158 if (pctxt->nberrors != 0) 21159 goto exit_error; 21160 /* 21161 * Apply constraints for attribute uses. 21162 */ 21163 for (i = 0; i < nbItems; i++) { 21164 item = items[i]; 21165 switch (item->type) { 21166 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21167 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21168 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21169 WXS_ATTR_USE_CAST item); 21170 FIXHFAILURE; 21171 } 21172 break; 21173 default: 21174 break; 21175 } 21176 } 21177 if (pctxt->nberrors != 0) 21178 goto exit_error; 21179 21180 /* 21181 * Apply constraints for attribute group definitions. 21182 */ 21183 for (i = 0; i < nbItems; i++) { 21184 item = items[i]; 21185 switch (item->type) { 21186 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21187 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21188 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21189 { 21190 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21191 FIXHFAILURE; 21192 } 21193 break; 21194 default: 21195 break; 21196 } 21197 } 21198 if (pctxt->nberrors != 0) 21199 goto exit_error; 21200 21201 /* 21202 * Apply constraints for redefinitions. 21203 */ 21204 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21205 xmlSchemaCheckSRCRedefineSecond(pctxt); 21206 if (pctxt->nberrors != 0) 21207 goto exit_error; 21208 21209 /* 21210 * Complex types are builded and checked. 21211 */ 21212 for (i = 0; i < nbItems; i++) { 21213 item = con->pending->items[i]; 21214 switch (item->type) { 21215 case XML_SCHEMA_TYPE_COMPLEX: 21216 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21217 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21218 FIXHFAILURE; 21219 } 21220 break; 21221 default: 21222 break; 21223 } 21224 } 21225 if (pctxt->nberrors != 0) 21226 goto exit_error; 21227 21228 /* 21229 * The list could have changed, since xmlSchemaFixupComplexType() 21230 * will create particles and model groups in some cases. 21231 */ 21232 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21233 nbItems = con->pending->nbItems; 21234 21235 /* 21236 * Apply some constraints for element declarations. 21237 */ 21238 for (i = 0; i < nbItems; i++) { 21239 item = items[i]; 21240 switch (item->type) { 21241 case XML_SCHEMA_TYPE_ELEMENT: 21242 elemDecl = (xmlSchemaElementPtr) item; 21243 21244 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21245 { 21246 xmlSchemaCheckElementDeclComponent( 21247 (xmlSchemaElementPtr) elemDecl, pctxt); 21248 FIXHFAILURE; 21249 } 21250 21251 #ifdef WXS_ELEM_DECL_CONS_ENABLED 21252 /* 21253 * Schema Component Constraint: Element Declarations Consistent 21254 * Apply this constraint to local types of element declarations. 21255 */ 21256 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21257 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21258 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21259 { 21260 xmlSchemaCheckElementDeclConsistent(pctxt, 21261 WXS_BASIC_CAST elemDecl, 21262 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21263 NULL, NULL, 0); 21264 } 21265 #endif 21266 break; 21267 default: 21268 break; 21269 } 21270 } 21271 if (pctxt->nberrors != 0) 21272 goto exit_error; 21273 21274 /* 21275 * Finally we can build the automaton from the content model of 21276 * complex types. 21277 */ 21278 21279 for (i = 0; i < nbItems; i++) { 21280 item = items[i]; 21281 switch (item->type) { 21282 case XML_SCHEMA_TYPE_COMPLEX: 21283 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21284 /* FIXHFAILURE; */ 21285 break; 21286 default: 21287 break; 21288 } 21289 } 21290 if (pctxt->nberrors != 0) 21291 goto exit_error; 21292 /* 21293 * URGENT TODO: cos-element-consistent 21294 */ 21295 goto exit; 21296 21297 exit_error: 21298 ret = pctxt->err; 21299 goto exit; 21300 21301 exit_failure: 21302 ret = -1; 21303 21304 exit: 21305 /* 21306 * Reset the constructor. This is needed for XSI acquisition, since 21307 * those items will be processed over and over again for every XSI 21308 * if not cleared here. 21309 */ 21310 con->bucket = oldbucket; 21311 con->pending->nbItems = 0; 21312 if (con->substGroups != NULL) { 21313 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); 21314 con->substGroups = NULL; 21315 } 21316 if (con->redefs != NULL) { 21317 xmlSchemaRedefListFree(con->redefs); 21318 con->redefs = NULL; 21319 } 21320 return(ret); 21321 } 21322 /** 21323 * xmlSchemaParse: 21324 * @ctxt: a schema validation context 21325 * 21326 * parse a schema definition resource and build an internal 21327 * XML Shema struture which can be used to validate instances. 21328 * 21329 * Returns the internal XML Schema structure built from the resource or 21330 * NULL in case of error 21331 */ 21332 xmlSchemaPtr 21333 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21334 { 21335 xmlSchemaPtr mainSchema = NULL; 21336 xmlSchemaBucketPtr bucket = NULL; 21337 int res; 21338 21339 /* 21340 * This one is used if the schema to be parsed was specified via 21341 * the API; i.e. not automatically by the validated instance document. 21342 */ 21343 21344 xmlSchemaInitTypes(); 21345 21346 if (ctxt == NULL) 21347 return (NULL); 21348 21349 /* TODO: Init the context. Is this all we need?*/ 21350 ctxt->nberrors = 0; 21351 ctxt->err = 0; 21352 ctxt->counter = 0; 21353 21354 /* Create the *main* schema. */ 21355 mainSchema = xmlSchemaNewSchema(ctxt); 21356 if (mainSchema == NULL) 21357 goto exit_failure; 21358 /* 21359 * Create the schema constructor. 21360 */ 21361 if (ctxt->constructor == NULL) { 21362 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21363 if (ctxt->constructor == NULL) 21364 return(NULL); 21365 /* Take ownership of the constructor to be able to free it. */ 21366 ctxt->ownsConstructor = 1; 21367 } 21368 ctxt->constructor->mainSchema = mainSchema; 21369 /* 21370 * Locate and add the schema document. 21371 */ 21372 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21373 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21374 NULL, NULL, &bucket); 21375 if (res == -1) 21376 goto exit_failure; 21377 if (res != 0) 21378 goto exit; 21379 21380 if (bucket == NULL) { 21381 /* TODO: Error code, actually we failed to *locate* the schema. */ 21382 if (ctxt->URL) 21383 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21384 NULL, NULL, 21385 "Failed to locate the main schema resource at '%s'", 21386 ctxt->URL, NULL); 21387 else 21388 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21389 NULL, NULL, 21390 "Failed to locate the main schema resource", 21391 NULL, NULL); 21392 goto exit; 21393 } 21394 /* Then do the parsing for good. */ 21395 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21396 goto exit_failure; 21397 if (ctxt->nberrors != 0) 21398 goto exit; 21399 21400 mainSchema->doc = bucket->doc; 21401 mainSchema->preserve = ctxt->preserve; 21402 21403 ctxt->schema = mainSchema; 21404 21405 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21406 goto exit_failure; 21407 21408 /* 21409 * TODO: This is not nice, since we cannot distinguish from the 21410 * result if there was an internal error or not. 21411 */ 21412 exit: 21413 if (ctxt->nberrors != 0) { 21414 if (mainSchema) { 21415 xmlSchemaFree(mainSchema); 21416 mainSchema = NULL; 21417 } 21418 if (ctxt->constructor) { 21419 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21420 ctxt->constructor = NULL; 21421 ctxt->ownsConstructor = 0; 21422 } 21423 } 21424 ctxt->schema = NULL; 21425 return(mainSchema); 21426 exit_failure: 21427 /* 21428 * Quite verbose, but should catch internal errors, which were 21429 * not communitated. 21430 */ 21431 if (mainSchema) { 21432 xmlSchemaFree(mainSchema); 21433 mainSchema = NULL; 21434 } 21435 if (ctxt->constructor) { 21436 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21437 ctxt->constructor = NULL; 21438 ctxt->ownsConstructor = 0; 21439 } 21440 PERROR_INT2("xmlSchemaParse", 21441 "An internal error occurred"); 21442 ctxt->schema = NULL; 21443 return(NULL); 21444 } 21445 21446 /** 21447 * xmlSchemaSetParserErrors: 21448 * @ctxt: a schema validation context 21449 * @err: the error callback 21450 * @warn: the warning callback 21451 * @ctx: contextual data for the callbacks 21452 * 21453 * Set the callback functions used to handle errors for a validation context 21454 */ 21455 void 21456 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21457 xmlSchemaValidityErrorFunc err, 21458 xmlSchemaValidityWarningFunc warn, void *ctx) 21459 { 21460 if (ctxt == NULL) 21461 return; 21462 ctxt->error = err; 21463 ctxt->warning = warn; 21464 ctxt->errCtxt = ctx; 21465 if (ctxt->vctxt != NULL) 21466 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21467 } 21468 21469 /** 21470 * xmlSchemaSetParserStructuredErrors: 21471 * @ctxt: a schema parser context 21472 * @serror: the structured error function 21473 * @ctx: the functions context 21474 * 21475 * Set the structured error callback 21476 */ 21477 void 21478 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21479 xmlStructuredErrorFunc serror, 21480 void *ctx) 21481 { 21482 if (ctxt == NULL) 21483 return; 21484 ctxt->serror = serror; 21485 ctxt->errCtxt = ctx; 21486 if (ctxt->vctxt != NULL) 21487 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21488 } 21489 21490 /** 21491 * xmlSchemaGetParserErrors: 21492 * @ctxt: a XMl-Schema parser context 21493 * @err: the error callback result 21494 * @warn: the warning callback result 21495 * @ctx: contextual data for the callbacks result 21496 * 21497 * Get the callback information used to handle errors for a parser context 21498 * 21499 * Returns -1 in case of failure, 0 otherwise 21500 */ 21501 int 21502 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21503 xmlSchemaValidityErrorFunc * err, 21504 xmlSchemaValidityWarningFunc * warn, void **ctx) 21505 { 21506 if (ctxt == NULL) 21507 return(-1); 21508 if (err != NULL) 21509 *err = ctxt->error; 21510 if (warn != NULL) 21511 *warn = ctxt->warning; 21512 if (ctx != NULL) 21513 *ctx = ctxt->errCtxt; 21514 return(0); 21515 } 21516 21517 /** 21518 * xmlSchemaFacetTypeToString: 21519 * @type: the facet type 21520 * 21521 * Convert the xmlSchemaTypeType to a char string. 21522 * 21523 * Returns the char string representation of the facet type if the 21524 * type is a facet and an "Internal Error" string otherwise. 21525 */ 21526 static const xmlChar * 21527 xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21528 { 21529 switch (type) { 21530 case XML_SCHEMA_FACET_PATTERN: 21531 return (BAD_CAST "pattern"); 21532 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21533 return (BAD_CAST "maxExclusive"); 21534 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21535 return (BAD_CAST "maxInclusive"); 21536 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21537 return (BAD_CAST "minExclusive"); 21538 case XML_SCHEMA_FACET_MININCLUSIVE: 21539 return (BAD_CAST "minInclusive"); 21540 case XML_SCHEMA_FACET_WHITESPACE: 21541 return (BAD_CAST "whiteSpace"); 21542 case XML_SCHEMA_FACET_ENUMERATION: 21543 return (BAD_CAST "enumeration"); 21544 case XML_SCHEMA_FACET_LENGTH: 21545 return (BAD_CAST "length"); 21546 case XML_SCHEMA_FACET_MAXLENGTH: 21547 return (BAD_CAST "maxLength"); 21548 case XML_SCHEMA_FACET_MINLENGTH: 21549 return (BAD_CAST "minLength"); 21550 case XML_SCHEMA_FACET_TOTALDIGITS: 21551 return (BAD_CAST "totalDigits"); 21552 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21553 return (BAD_CAST "fractionDigits"); 21554 default: 21555 break; 21556 } 21557 return (BAD_CAST "Internal Error"); 21558 } 21559 21560 static xmlSchemaWhitespaceValueType 21561 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21562 { 21563 /* 21564 * The normalization type can be changed only for types which are derived 21565 * from xsd:string. 21566 */ 21567 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21568 /* 21569 * Note that we assume a whitespace of preserve for anySimpleType. 21570 */ 21571 if ((type->builtInType == XML_SCHEMAS_STRING) || 21572 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21573 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21574 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21575 return(XML_SCHEMA_WHITESPACE_REPLACE); 21576 else { 21577 /* 21578 * For all `atomic` datatypes other than string (and types `derived` 21579 * by `restriction` from it) the value of whiteSpace is fixed to 21580 * collapse 21581 * Note that this includes built-in list datatypes. 21582 */ 21583 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21584 } 21585 } else if (WXS_IS_LIST(type)) { 21586 /* 21587 * For list types the facet "whiteSpace" is fixed to "collapse". 21588 */ 21589 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21590 } else if (WXS_IS_UNION(type)) { 21591 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21592 } else if (WXS_IS_ATOMIC(type)) { 21593 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21594 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21595 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21596 return (XML_SCHEMA_WHITESPACE_REPLACE); 21597 else 21598 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21599 } 21600 return (-1); 21601 } 21602 21603 /************************************************************************ 21604 * * 21605 * Simple type validation * 21606 * * 21607 ************************************************************************/ 21608 21609 21610 /************************************************************************ 21611 * * 21612 * DOM Validation code * 21613 * * 21614 ************************************************************************/ 21615 21616 /** 21617 * xmlSchemaAssembleByLocation: 21618 * @pctxt: a schema parser context 21619 * @vctxt: a schema validation context 21620 * @schema: the existing schema 21621 * @node: the node that fired the assembling 21622 * @nsName: the namespace name of the new schema 21623 * @location: the location of the schema 21624 * 21625 * Expands an existing schema by an additional schema. 21626 * 21627 * Returns 0 if the new schema is correct, a positive error code 21628 * number otherwise and -1 in case of an internal or API error. 21629 */ 21630 static int 21631 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21632 xmlSchemaPtr schema, 21633 xmlNodePtr node, 21634 const xmlChar *nsName, 21635 const xmlChar *location) 21636 { 21637 int ret = 0; 21638 xmlSchemaParserCtxtPtr pctxt; 21639 xmlSchemaBucketPtr bucket = NULL; 21640 21641 if ((vctxt == NULL) || (schema == NULL)) 21642 return (-1); 21643 21644 if (vctxt->pctxt == NULL) { 21645 VERROR_INT("xmlSchemaAssembleByLocation", 21646 "no parser context available"); 21647 return(-1); 21648 } 21649 pctxt = vctxt->pctxt; 21650 if (pctxt->constructor == NULL) { 21651 PERROR_INT("xmlSchemaAssembleByLocation", 21652 "no constructor"); 21653 return(-1); 21654 } 21655 /* 21656 * Acquire the schema document. 21657 */ 21658 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21659 location, node); 21660 /* 21661 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21662 * the process will automatically change this to 21663 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21664 */ 21665 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21666 location, NULL, NULL, 0, node, NULL, nsName, 21667 &bucket); 21668 if (ret != 0) 21669 return(ret); 21670 if (bucket == NULL) { 21671 /* 21672 * Generate a warning that the document could not be located. 21673 */ 21674 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21675 node, NULL, 21676 "The document at location '%s' could not be acquired", 21677 location, NULL, NULL); 21678 return(ret); 21679 } 21680 /* 21681 * The first located schema will be handled as if all other 21682 * schemas imported by XSI were imported by this first schema. 21683 */ 21684 if ((bucket != NULL) && 21685 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21686 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21687 /* 21688 * TODO: Is this handled like an import? I.e. is it not an error 21689 * if the schema cannot be located? 21690 */ 21691 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21692 return(0); 21693 /* 21694 * We will reuse the parser context for every schema imported 21695 * directly via XSI. So reset the context. 21696 */ 21697 pctxt->nberrors = 0; 21698 pctxt->err = 0; 21699 pctxt->doc = bucket->doc; 21700 21701 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21702 if (ret == -1) { 21703 pctxt->doc = NULL; 21704 goto exit_failure; 21705 } 21706 /* Paranoid error channelling. */ 21707 if ((ret == 0) && (pctxt->nberrors != 0)) 21708 ret = pctxt->err; 21709 if (pctxt->nberrors == 0) { 21710 /* 21711 * Only bother to fixup pending components, if there was 21712 * no error yet. 21713 * For every XSI acquired schema (and its sub-schemata) we will 21714 * fixup the components. 21715 */ 21716 xmlSchemaFixupComponents(pctxt, bucket); 21717 ret = pctxt->err; 21718 /* 21719 * Not nice, but we need somehow to channel the schema parser 21720 * error to the validation context. 21721 */ 21722 if ((ret != 0) && (vctxt->err == 0)) 21723 vctxt->err = ret; 21724 vctxt->nberrors += pctxt->nberrors; 21725 } else { 21726 /* Add to validation error sum. */ 21727 vctxt->nberrors += pctxt->nberrors; 21728 } 21729 pctxt->doc = NULL; 21730 return(ret); 21731 exit_failure: 21732 pctxt->doc = NULL; 21733 return (-1); 21734 } 21735 21736 static xmlSchemaAttrInfoPtr 21737 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21738 int metaType) 21739 { 21740 if (vctxt->nbAttrInfos == 0) 21741 return (NULL); 21742 { 21743 int i; 21744 xmlSchemaAttrInfoPtr iattr; 21745 21746 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21747 iattr = vctxt->attrInfos[i]; 21748 if (iattr->metaType == metaType) 21749 return (iattr); 21750 } 21751 21752 } 21753 return (NULL); 21754 } 21755 21756 /** 21757 * xmlSchemaAssembleByXSI: 21758 * @vctxt: a schema validation context 21759 * 21760 * Expands an existing schema by an additional schema using 21761 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21762 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21763 * must be set to 1. 21764 * 21765 * Returns 0 if the new schema is correct, a positive error code 21766 * number otherwise and -1 in case of an internal or API error. 21767 */ 21768 static int 21769 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21770 { 21771 const xmlChar *cur, *end; 21772 const xmlChar *nsname = NULL, *location; 21773 int count = 0; 21774 int ret = 0; 21775 xmlSchemaAttrInfoPtr iattr; 21776 21777 /* 21778 * Parse the value; we will assume an even number of values 21779 * to be given (this is how Xerces and XSV work). 21780 * 21781 * URGENT TODO: !! This needs to work for both 21782 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21783 * element !! 21784 */ 21785 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21786 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21787 if (iattr == NULL) 21788 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21789 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21790 if (iattr == NULL) 21791 return (0); 21792 cur = iattr->value; 21793 do { 21794 /* 21795 * TODO: Move the string parsing mechanism away from here. 21796 */ 21797 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21798 /* 21799 * Get the namespace name. 21800 */ 21801 while (IS_BLANK_CH(*cur)) 21802 cur++; 21803 end = cur; 21804 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21805 end++; 21806 if (end == cur) 21807 break; 21808 count++; /* TODO: Don't use the schema's dict. */ 21809 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21810 cur = end; 21811 } 21812 /* 21813 * Get the URI. 21814 */ 21815 while (IS_BLANK_CH(*cur)) 21816 cur++; 21817 end = cur; 21818 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21819 end++; 21820 if (end == cur) { 21821 if (iattr->metaType == 21822 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21823 { 21824 /* 21825 * If using @schemaLocation then tuples are expected. 21826 * I.e. the namespace name *and* the document's URI. 21827 */ 21828 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21829 iattr->node, NULL, 21830 "The value must consist of tuples: the target namespace " 21831 "name and the document's URI", NULL, NULL, NULL); 21832 } 21833 break; 21834 } 21835 count++; /* TODO: Don't use the schema's dict. */ 21836 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21837 cur = end; 21838 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21839 iattr->node, nsname, location); 21840 if (ret == -1) { 21841 VERROR_INT("xmlSchemaAssembleByXSI", 21842 "assembling schemata"); 21843 return (-1); 21844 } 21845 } while (*cur != 0); 21846 return (ret); 21847 } 21848 21849 static const xmlChar * 21850 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21851 const xmlChar *prefix) 21852 { 21853 if (vctxt->sax != NULL) { 21854 int i, j; 21855 xmlSchemaNodeInfoPtr inode; 21856 21857 for (i = vctxt->depth; i >= 0; i--) { 21858 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21859 inode = vctxt->elemInfos[i]; 21860 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21861 if (((prefix == NULL) && 21862 (inode->nsBindings[j] == NULL)) || 21863 ((prefix != NULL) && xmlStrEqual(prefix, 21864 inode->nsBindings[j]))) { 21865 21866 /* 21867 * Note that the namespace bindings are already 21868 * in a string dict. 21869 */ 21870 return (inode->nsBindings[j+1]); 21871 } 21872 } 21873 } 21874 } 21875 return (NULL); 21876 #ifdef LIBXML_READER_ENABLED 21877 } else if (vctxt->reader != NULL) { 21878 xmlChar *nsName; 21879 21880 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21881 if (nsName != NULL) { 21882 const xmlChar *ret; 21883 21884 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21885 xmlFree(nsName); 21886 return (ret); 21887 } else 21888 return (NULL); 21889 #endif 21890 } else { 21891 xmlNsPtr ns; 21892 21893 if ((vctxt->inode->node == NULL) || 21894 (vctxt->inode->node->doc == NULL)) { 21895 VERROR_INT("xmlSchemaLookupNamespace", 21896 "no node or node's doc avaliable"); 21897 return (NULL); 21898 } 21899 ns = xmlSearchNs(vctxt->inode->node->doc, 21900 vctxt->inode->node, prefix); 21901 if (ns != NULL) 21902 return (ns->href); 21903 return (NULL); 21904 } 21905 } 21906 21907 /* 21908 * This one works on the schema of the validation context. 21909 */ 21910 static int 21911 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21912 xmlSchemaPtr schema, 21913 xmlNodePtr node, 21914 const xmlChar *value, 21915 xmlSchemaValPtr *val, 21916 int valNeeded) 21917 { 21918 int ret; 21919 21920 if (vctxt && (vctxt->schema == NULL)) { 21921 VERROR_INT("xmlSchemaValidateNotation", 21922 "a schema is needed on the validation context"); 21923 return (-1); 21924 } 21925 ret = xmlValidateQName(value, 1); 21926 if (ret != 0) 21927 return (ret); 21928 { 21929 xmlChar *localName = NULL; 21930 xmlChar *prefix = NULL; 21931 21932 localName = xmlSplitQName2(value, &prefix); 21933 if (prefix != NULL) { 21934 const xmlChar *nsName = NULL; 21935 21936 if (vctxt != NULL) 21937 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21938 else if (node != NULL) { 21939 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21940 if (ns != NULL) 21941 nsName = ns->href; 21942 } else { 21943 xmlFree(prefix); 21944 xmlFree(localName); 21945 return (1); 21946 } 21947 if (nsName == NULL) { 21948 xmlFree(prefix); 21949 xmlFree(localName); 21950 return (1); 21951 } 21952 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21953 if ((valNeeded) && (val != NULL)) { 21954 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21955 xmlStrdup(nsName)); 21956 if (*val == NULL) 21957 ret = -1; 21958 } 21959 } else 21960 ret = 1; 21961 xmlFree(prefix); 21962 xmlFree(localName); 21963 } else { 21964 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21965 if (valNeeded && (val != NULL)) { 21966 (*val) = xmlSchemaNewNOTATIONValue( 21967 BAD_CAST xmlStrdup(value), NULL); 21968 if (*val == NULL) 21969 ret = -1; 21970 } 21971 } else 21972 return (1); 21973 } 21974 } 21975 return (ret); 21976 } 21977 21978 static int 21979 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21980 const xmlChar* lname, 21981 const xmlChar* nsname) 21982 { 21983 int i; 21984 21985 lname = xmlDictLookup(vctxt->dict, lname, -1); 21986 if (lname == NULL) 21987 return(-1); 21988 if (nsname != NULL) { 21989 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21990 if (nsname == NULL) 21991 return(-1); 21992 } 21993 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21994 if ((vctxt->nodeQNames->items [i] == lname) && 21995 (vctxt->nodeQNames->items[i +1] == nsname)) 21996 /* Already there */ 21997 return(i); 21998 } 21999 /* Add new entry. */ 22000 i = vctxt->nodeQNames->nbItems; 22001 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 22002 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 22003 return(i); 22004 } 22005 22006 /************************************************************************ 22007 * * 22008 * Validation of identity-constraints (IDC) * 22009 * * 22010 ************************************************************************/ 22011 22012 /** 22013 * xmlSchemaAugmentIDC: 22014 * @idcDef: the IDC definition 22015 * 22016 * Creates an augmented IDC definition item. 22017 * 22018 * Returns the item, or NULL on internal errors. 22019 */ 22020 static void 22021 xmlSchemaAugmentIDC(void *payload, void *data, 22022 const xmlChar *name ATTRIBUTE_UNUSED) 22023 { 22024 xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload; 22025 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; 22026 xmlSchemaIDCAugPtr aidc; 22027 22028 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 22029 if (aidc == NULL) { 22030 xmlSchemaVErrMemory(vctxt, 22031 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 22032 NULL); 22033 return; 22034 } 22035 aidc->keyrefDepth = -1; 22036 aidc->def = idcDef; 22037 aidc->next = NULL; 22038 if (vctxt->aidcs == NULL) 22039 vctxt->aidcs = aidc; 22040 else { 22041 aidc->next = vctxt->aidcs; 22042 vctxt->aidcs = aidc; 22043 } 22044 /* 22045 * Save if we have keyrefs at all. 22046 */ 22047 if ((vctxt->hasKeyrefs == 0) && 22048 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 22049 vctxt->hasKeyrefs = 1; 22050 } 22051 22052 /** 22053 * xmlSchemaAugmentImportedIDC: 22054 * @imported: the imported schema 22055 * 22056 * Creates an augmented IDC definition for the imported schema. 22057 */ 22058 static void 22059 xmlSchemaAugmentImportedIDC(void *payload, void *data, 22060 const xmlChar *name ATTRIBUTE_UNUSED) { 22061 xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload; 22062 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; 22063 if (imported->schema->idcDef != NULL) { 22064 xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt); 22065 } 22066 } 22067 22068 /** 22069 * xmlSchemaIDCNewBinding: 22070 * @idcDef: the IDC definition of this binding 22071 * 22072 * Creates a new IDC binding. 22073 * 22074 * Returns the new IDC binding, NULL on internal errors. 22075 */ 22076 static xmlSchemaPSVIIDCBindingPtr 22077 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22078 { 22079 xmlSchemaPSVIIDCBindingPtr ret; 22080 22081 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22082 sizeof(xmlSchemaPSVIIDCBinding)); 22083 if (ret == NULL) { 22084 xmlSchemaVErrMemory(NULL, 22085 "allocating a PSVI IDC binding item", NULL); 22086 return (NULL); 22087 } 22088 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22089 ret->definition = idcDef; 22090 return (ret); 22091 } 22092 22093 /** 22094 * xmlSchemaIDCStoreNodeTableItem: 22095 * @vctxt: the WXS validation context 22096 * @item: the IDC node table item 22097 * 22098 * The validation context is used to store IDC node table items. 22099 * They are stored to avoid copying them if IDC node-tables are merged 22100 * with corresponding parent IDC node-tables (bubbling). 22101 * 22102 * Returns 0 if succeeded, -1 on internal errors. 22103 */ 22104 static int 22105 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22106 xmlSchemaPSVIIDCNodePtr item) 22107 { 22108 /* 22109 * Add to gobal list. 22110 */ 22111 if (vctxt->idcNodes == NULL) { 22112 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22113 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22114 if (vctxt->idcNodes == NULL) { 22115 xmlSchemaVErrMemory(vctxt, 22116 "allocating the IDC node table item list", NULL); 22117 return (-1); 22118 } 22119 vctxt->sizeIdcNodes = 20; 22120 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22121 vctxt->sizeIdcNodes *= 2; 22122 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22123 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22124 sizeof(xmlSchemaPSVIIDCNodePtr)); 22125 if (vctxt->idcNodes == NULL) { 22126 xmlSchemaVErrMemory(vctxt, 22127 "re-allocating the IDC node table item list", NULL); 22128 return (-1); 22129 } 22130 } 22131 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22132 22133 return (0); 22134 } 22135 22136 /** 22137 * xmlSchemaIDCStoreKey: 22138 * @vctxt: the WXS validation context 22139 * @item: the IDC key 22140 * 22141 * The validation context is used to store an IDC key. 22142 * 22143 * Returns 0 if succeeded, -1 on internal errors. 22144 */ 22145 static int 22146 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22147 xmlSchemaPSVIIDCKeyPtr key) 22148 { 22149 /* 22150 * Add to gobal list. 22151 */ 22152 if (vctxt->idcKeys == NULL) { 22153 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22154 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22155 if (vctxt->idcKeys == NULL) { 22156 xmlSchemaVErrMemory(vctxt, 22157 "allocating the IDC key storage list", NULL); 22158 return (-1); 22159 } 22160 vctxt->sizeIdcKeys = 40; 22161 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22162 vctxt->sizeIdcKeys *= 2; 22163 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22164 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22165 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22166 if (vctxt->idcKeys == NULL) { 22167 xmlSchemaVErrMemory(vctxt, 22168 "re-allocating the IDC key storage list", NULL); 22169 return (-1); 22170 } 22171 } 22172 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22173 22174 return (0); 22175 } 22176 22177 /** 22178 * xmlSchemaIDCAppendNodeTableItem: 22179 * @bind: the IDC binding 22180 * @ntItem: the node-table item 22181 * 22182 * Appends the IDC node-table item to the binding. 22183 * 22184 * Returns 0 on success and -1 on internal errors. 22185 */ 22186 static int 22187 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22188 xmlSchemaPSVIIDCNodePtr ntItem) 22189 { 22190 if (bind->nodeTable == NULL) { 22191 bind->sizeNodes = 10; 22192 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22193 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22194 if (bind->nodeTable == NULL) { 22195 xmlSchemaVErrMemory(NULL, 22196 "allocating an array of IDC node-table items", NULL); 22197 return(-1); 22198 } 22199 } else if (bind->sizeNodes <= bind->nbNodes) { 22200 bind->sizeNodes *= 2; 22201 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22202 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22203 sizeof(xmlSchemaPSVIIDCNodePtr)); 22204 if (bind->nodeTable == NULL) { 22205 xmlSchemaVErrMemory(NULL, 22206 "re-allocating an array of IDC node-table items", NULL); 22207 return(-1); 22208 } 22209 } 22210 bind->nodeTable[bind->nbNodes++] = ntItem; 22211 return(0); 22212 } 22213 22214 /** 22215 * xmlSchemaIDCAcquireBinding: 22216 * @vctxt: the WXS validation context 22217 * @matcher: the IDC matcher 22218 * 22219 * Looks up an PSVI IDC binding, for the IDC definition and 22220 * of the given matcher. If none found, a new one is created 22221 * and added to the IDC table. 22222 * 22223 * Returns an IDC binding or NULL on internal errors. 22224 */ 22225 static xmlSchemaPSVIIDCBindingPtr 22226 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22227 xmlSchemaIDCMatcherPtr matcher) 22228 { 22229 xmlSchemaNodeInfoPtr ielem; 22230 22231 ielem = vctxt->elemInfos[matcher->depth]; 22232 22233 if (ielem->idcTable == NULL) { 22234 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22235 if (ielem->idcTable == NULL) 22236 return (NULL); 22237 return(ielem->idcTable); 22238 } else { 22239 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22240 22241 bind = ielem->idcTable; 22242 do { 22243 if (bind->definition == matcher->aidc->def) 22244 return(bind); 22245 if (bind->next == NULL) { 22246 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22247 if (bind->next == NULL) 22248 return (NULL); 22249 return(bind->next); 22250 } 22251 bind = bind->next; 22252 } while (bind != NULL); 22253 } 22254 return (NULL); 22255 } 22256 22257 static xmlSchemaItemListPtr 22258 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22259 xmlSchemaIDCMatcherPtr matcher) 22260 { 22261 if (matcher->targets == NULL) 22262 matcher->targets = xmlSchemaItemListCreate(); 22263 return(matcher->targets); 22264 } 22265 22266 /** 22267 * xmlSchemaIDCFreeKey: 22268 * @key: the IDC key 22269 * 22270 * Frees an IDC key together with its compiled value. 22271 */ 22272 static void 22273 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22274 { 22275 if (key->val != NULL) 22276 xmlSchemaFreeValue(key->val); 22277 xmlFree(key); 22278 } 22279 22280 /** 22281 * xmlSchemaIDCFreeBinding: 22282 * 22283 * Frees an IDC binding. Note that the node table-items 22284 * are not freed. 22285 */ 22286 static void 22287 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22288 { 22289 if (bind->nodeTable != NULL) 22290 xmlFree(bind->nodeTable); 22291 if (bind->dupls != NULL) 22292 xmlSchemaItemListFree(bind->dupls); 22293 xmlFree(bind); 22294 } 22295 22296 /** 22297 * xmlSchemaIDCFreeIDCTable: 22298 * @bind: the first IDC binding in the list 22299 * 22300 * Frees an IDC table, i.e. all the IDC bindings in the list. 22301 */ 22302 static void 22303 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22304 { 22305 xmlSchemaPSVIIDCBindingPtr prev; 22306 22307 while (bind != NULL) { 22308 prev = bind; 22309 bind = bind->next; 22310 xmlSchemaIDCFreeBinding(prev); 22311 } 22312 } 22313 22314 /** 22315 * xmlSchemaIDCFreeMatcherList: 22316 * @matcher: the first IDC matcher in the list 22317 * 22318 * Frees a list of IDC matchers. 22319 */ 22320 static void 22321 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22322 { 22323 xmlSchemaIDCMatcherPtr next; 22324 22325 while (matcher != NULL) { 22326 next = matcher->next; 22327 if (matcher->keySeqs != NULL) { 22328 int i; 22329 for (i = 0; i < matcher->sizeKeySeqs; i++) 22330 if (matcher->keySeqs[i] != NULL) 22331 xmlFree(matcher->keySeqs[i]); 22332 xmlFree(matcher->keySeqs); 22333 } 22334 if (matcher->targets != NULL) { 22335 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22336 int i; 22337 xmlSchemaPSVIIDCNodePtr idcNode; 22338 /* 22339 * Node-table items for keyrefs are not stored globally 22340 * to the validation context, since they are not bubbled. 22341 * We need to free them here. 22342 */ 22343 for (i = 0; i < matcher->targets->nbItems; i++) { 22344 idcNode = 22345 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22346 xmlFree(idcNode->keys); 22347 xmlFree(idcNode); 22348 } 22349 } 22350 xmlSchemaItemListFree(matcher->targets); 22351 } 22352 xmlFree(matcher); 22353 matcher = next; 22354 } 22355 } 22356 22357 /** 22358 * xmlSchemaIDCReleaseMatcherList: 22359 * @vctxt: the WXS validation context 22360 * @matcher: the first IDC matcher in the list 22361 * 22362 * Caches a list of IDC matchers for reuse. 22363 */ 22364 static void 22365 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22366 xmlSchemaIDCMatcherPtr matcher) 22367 { 22368 xmlSchemaIDCMatcherPtr next; 22369 22370 while (matcher != NULL) { 22371 next = matcher->next; 22372 if (matcher->keySeqs != NULL) { 22373 int i; 22374 /* 22375 * Don't free the array, but only the content. 22376 */ 22377 for (i = 0; i < matcher->sizeKeySeqs; i++) 22378 if (matcher->keySeqs[i] != NULL) { 22379 xmlFree(matcher->keySeqs[i]); 22380 matcher->keySeqs[i] = NULL; 22381 } 22382 } 22383 if (matcher->targets) { 22384 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22385 int i; 22386 xmlSchemaPSVIIDCNodePtr idcNode; 22387 /* 22388 * Node-table items for keyrefs are not stored globally 22389 * to the validation context, since they are not bubbled. 22390 * We need to free them here. 22391 */ 22392 for (i = 0; i < matcher->targets->nbItems; i++) { 22393 idcNode = 22394 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22395 xmlFree(idcNode->keys); 22396 xmlFree(idcNode); 22397 } 22398 } 22399 xmlSchemaItemListFree(matcher->targets); 22400 matcher->targets = NULL; 22401 } 22402 matcher->next = NULL; 22403 /* 22404 * Cache the matcher. 22405 */ 22406 if (vctxt->idcMatcherCache != NULL) 22407 matcher->nextCached = vctxt->idcMatcherCache; 22408 vctxt->idcMatcherCache = matcher; 22409 22410 matcher = next; 22411 } 22412 } 22413 22414 /** 22415 * xmlSchemaIDCAddStateObject: 22416 * @vctxt: the WXS validation context 22417 * @matcher: the IDC matcher 22418 * @sel: the XPath information 22419 * @parent: the parent "selector" state object if any 22420 * @type: "selector" or "field" 22421 * 22422 * Creates/reuses and activates state objects for the given 22423 * XPath information; if the XPath expression consists of unions, 22424 * multiple state objects are created for every unioned expression. 22425 * 22426 * Returns 0 on success and -1 on internal errors. 22427 */ 22428 static int 22429 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22430 xmlSchemaIDCMatcherPtr matcher, 22431 xmlSchemaIDCSelectPtr sel, 22432 int type) 22433 { 22434 xmlSchemaIDCStateObjPtr sto; 22435 22436 /* 22437 * Reuse the state objects from the pool. 22438 */ 22439 if (vctxt->xpathStatePool != NULL) { 22440 sto = vctxt->xpathStatePool; 22441 vctxt->xpathStatePool = sto->next; 22442 sto->next = NULL; 22443 } else { 22444 /* 22445 * Create a new state object. 22446 */ 22447 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22448 if (sto == NULL) { 22449 xmlSchemaVErrMemory(NULL, 22450 "allocating an IDC state object", NULL); 22451 return (-1); 22452 } 22453 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22454 } 22455 /* 22456 * Add to global list. 22457 */ 22458 if (vctxt->xpathStates != NULL) 22459 sto->next = vctxt->xpathStates; 22460 vctxt->xpathStates = sto; 22461 22462 /* 22463 * Free the old xpath validation context. 22464 */ 22465 if (sto->xpathCtxt != NULL) 22466 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22467 22468 /* 22469 * Create a new XPath (pattern) validation context. 22470 */ 22471 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22472 (xmlPatternPtr) sel->xpathComp); 22473 if (sto->xpathCtxt == NULL) { 22474 VERROR_INT("xmlSchemaIDCAddStateObject", 22475 "failed to create an XPath validation context"); 22476 return (-1); 22477 } 22478 sto->type = type; 22479 sto->depth = vctxt->depth; 22480 sto->matcher = matcher; 22481 sto->sel = sel; 22482 sto->nbHistory = 0; 22483 22484 #ifdef DEBUG_IDC 22485 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22486 sto->sel->xpath); 22487 #endif 22488 return (0); 22489 } 22490 22491 /** 22492 * xmlSchemaXPathEvaluate: 22493 * @vctxt: the WXS validation context 22494 * @nodeType: the nodeType of the current node 22495 * 22496 * Evaluates all active XPath state objects. 22497 * 22498 * Returns the number of IC "field" state objects which resolved to 22499 * this node, 0 if none resolved and -1 on internal errors. 22500 */ 22501 static int 22502 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22503 xmlElementType nodeType) 22504 { 22505 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22506 int res, resolved = 0, depth = vctxt->depth; 22507 22508 if (vctxt->xpathStates == NULL) 22509 return (0); 22510 22511 if (nodeType == XML_ATTRIBUTE_NODE) 22512 depth++; 22513 #ifdef DEBUG_IDC 22514 { 22515 xmlChar *str = NULL; 22516 xmlGenericError(xmlGenericErrorContext, 22517 "IDC: EVAL on %s, depth %d, type %d\n", 22518 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22519 vctxt->inode->localName), depth, nodeType); 22520 FREE_AND_NULL(str) 22521 } 22522 #endif 22523 /* 22524 * Process all active XPath state objects. 22525 */ 22526 first = vctxt->xpathStates; 22527 sto = first; 22528 while (sto != head) { 22529 #ifdef DEBUG_IDC 22530 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22531 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22532 sto->matcher->aidc->def->name, sto->sel->xpath); 22533 else 22534 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22535 sto->matcher->aidc->def->name, sto->sel->xpath); 22536 #endif 22537 if (nodeType == XML_ELEMENT_NODE) 22538 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22539 vctxt->inode->localName, vctxt->inode->nsName); 22540 else 22541 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22542 vctxt->inode->localName, vctxt->inode->nsName); 22543 22544 if (res == -1) { 22545 VERROR_INT("xmlSchemaXPathEvaluate", 22546 "calling xmlStreamPush()"); 22547 return (-1); 22548 } 22549 if (res == 0) 22550 goto next_sto; 22551 /* 22552 * Full match. 22553 */ 22554 #ifdef DEBUG_IDC 22555 xmlGenericError(xmlGenericErrorContext, "IDC: " 22556 "MATCH\n"); 22557 #endif 22558 /* 22559 * Register a match in the state object history. 22560 */ 22561 if (sto->history == NULL) { 22562 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22563 if (sto->history == NULL) { 22564 xmlSchemaVErrMemory(NULL, 22565 "allocating the state object history", NULL); 22566 return(-1); 22567 } 22568 sto->sizeHistory = 5; 22569 } else if (sto->sizeHistory <= sto->nbHistory) { 22570 sto->sizeHistory *= 2; 22571 sto->history = (int *) xmlRealloc(sto->history, 22572 sto->sizeHistory * sizeof(int)); 22573 if (sto->history == NULL) { 22574 xmlSchemaVErrMemory(NULL, 22575 "re-allocating the state object history", NULL); 22576 return(-1); 22577 } 22578 } 22579 sto->history[sto->nbHistory++] = depth; 22580 22581 #ifdef DEBUG_IDC 22582 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22583 vctxt->depth); 22584 #endif 22585 22586 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22587 xmlSchemaIDCSelectPtr sel; 22588 /* 22589 * Activate state objects for the IDC fields of 22590 * the IDC selector. 22591 */ 22592 #ifdef DEBUG_IDC 22593 xmlGenericError(xmlGenericErrorContext, "IDC: " 22594 "activating field states\n"); 22595 #endif 22596 sel = sto->matcher->aidc->def->fields; 22597 while (sel != NULL) { 22598 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22599 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22600 return (-1); 22601 sel = sel->next; 22602 } 22603 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22604 /* 22605 * An IDC key node was found by the IDC field. 22606 */ 22607 #ifdef DEBUG_IDC 22608 xmlGenericError(xmlGenericErrorContext, 22609 "IDC: key found\n"); 22610 #endif 22611 /* 22612 * Notify that the character value of this node is 22613 * needed. 22614 */ 22615 if (resolved == 0) { 22616 if ((vctxt->inode->flags & 22617 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22618 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22619 } 22620 resolved++; 22621 } 22622 next_sto: 22623 if (sto->next == NULL) { 22624 /* 22625 * Evaluate field state objects created on this node as well. 22626 */ 22627 head = first; 22628 sto = vctxt->xpathStates; 22629 } else 22630 sto = sto->next; 22631 } 22632 return (resolved); 22633 } 22634 22635 static const xmlChar * 22636 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22637 xmlChar **buf, 22638 xmlSchemaPSVIIDCKeyPtr *seq, 22639 int count) 22640 { 22641 int i, res; 22642 xmlChar *value = NULL; 22643 22644 *buf = xmlStrdup(BAD_CAST "["); 22645 for (i = 0; i < count; i++) { 22646 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22647 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22648 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22649 &value); 22650 if (res == 0) 22651 *buf = xmlStrcat(*buf, BAD_CAST value); 22652 else { 22653 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22654 "failed to compute a canonical value"); 22655 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22656 } 22657 if (i < count -1) 22658 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22659 else 22660 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22661 if (value != NULL) { 22662 xmlFree(value); 22663 value = NULL; 22664 } 22665 } 22666 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22667 22668 return (BAD_CAST *buf); 22669 } 22670 22671 /** 22672 * xmlSchemaXPathPop: 22673 * @vctxt: the WXS validation context 22674 * 22675 * Pops all XPath states. 22676 * 22677 * Returns 0 on success and -1 on internal errors. 22678 */ 22679 static int 22680 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22681 { 22682 xmlSchemaIDCStateObjPtr sto; 22683 int res; 22684 22685 if (vctxt->xpathStates == NULL) 22686 return(0); 22687 sto = vctxt->xpathStates; 22688 do { 22689 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22690 if (res == -1) 22691 return (-1); 22692 sto = sto->next; 22693 } while (sto != NULL); 22694 return(0); 22695 } 22696 22697 /** 22698 * xmlSchemaXPathProcessHistory: 22699 * @vctxt: the WXS validation context 22700 * @type: the simple/complex type of the current node if any at all 22701 * @val: the precompiled value 22702 * 22703 * Processes and pops the history items of the IDC state objects. 22704 * IDC key-sequences are validated/created on IDC bindings. 22705 * 22706 * Returns 0 on success and -1 on internal errors. 22707 */ 22708 static int 22709 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22710 int depth) 22711 { 22712 xmlSchemaIDCStateObjPtr sto, nextsto; 22713 int res, matchDepth; 22714 xmlSchemaPSVIIDCKeyPtr key = NULL; 22715 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22716 22717 if (vctxt->xpathStates == NULL) 22718 return (0); 22719 sto = vctxt->xpathStates; 22720 22721 #ifdef DEBUG_IDC 22722 { 22723 xmlChar *str = NULL; 22724 xmlGenericError(xmlGenericErrorContext, 22725 "IDC: BACK on %s, depth %d\n", 22726 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22727 vctxt->inode->localName), vctxt->depth); 22728 FREE_AND_NULL(str) 22729 } 22730 #endif 22731 /* 22732 * Evaluate the state objects. 22733 */ 22734 while (sto != NULL) { 22735 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22736 if (res == -1) { 22737 VERROR_INT("xmlSchemaXPathProcessHistory", 22738 "calling xmlStreamPop()"); 22739 return (-1); 22740 } 22741 #ifdef DEBUG_IDC 22742 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22743 sto->sel->xpath); 22744 #endif 22745 if (sto->nbHistory == 0) 22746 goto deregister_check; 22747 22748 matchDepth = sto->history[sto->nbHistory -1]; 22749 22750 /* 22751 * Only matches at the current depth are of interest. 22752 */ 22753 if (matchDepth != depth) { 22754 sto = sto->next; 22755 continue; 22756 } 22757 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22758 /* 22759 * NOTE: According to 22760 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22761 * ... the simple-content of complex types is also allowed. 22762 */ 22763 22764 if (WXS_IS_COMPLEX(type)) { 22765 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22766 /* 22767 * Sanity check for complex types with simple content. 22768 */ 22769 simpleType = type->contentTypeDef; 22770 if (simpleType == NULL) { 22771 VERROR_INT("xmlSchemaXPathProcessHistory", 22772 "field resolves to a CT with simple content " 22773 "but the CT is missing the ST definition"); 22774 return (-1); 22775 } 22776 } else 22777 simpleType = NULL; 22778 } else 22779 simpleType = type; 22780 if (simpleType == NULL) { 22781 xmlChar *str = NULL; 22782 22783 /* 22784 * Not qualified if the field resolves to a node of non 22785 * simple type. 22786 */ 22787 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22788 XML_SCHEMAV_CVC_IDC, NULL, 22789 WXS_BASIC_CAST sto->matcher->aidc->def, 22790 "The XPath '%s' of a field of %s does evaluate to a node of " 22791 "non-simple type", 22792 sto->sel->xpath, 22793 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22794 FREE_AND_NULL(str); 22795 sto->nbHistory--; 22796 goto deregister_check; 22797 } 22798 22799 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22800 /* 22801 * Failed to provide the normalized value; maybe 22802 * the value was invalid. 22803 */ 22804 VERROR(XML_SCHEMAV_CVC_IDC, 22805 WXS_BASIC_CAST sto->matcher->aidc->def, 22806 "Warning: No precomputed value available, the value " 22807 "was either invalid or something strange happend"); 22808 sto->nbHistory--; 22809 goto deregister_check; 22810 } else { 22811 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22812 xmlSchemaPSVIIDCKeyPtr *keySeq; 22813 int pos, idx; 22814 22815 /* 22816 * The key will be anchored on the matcher's list of 22817 * key-sequences. The position in this list is determined 22818 * by the target node's depth relative to the matcher's 22819 * depth of creation (i.e. the depth of the scope element). 22820 * 22821 * Element Depth Pos List-entries 22822 * <scope> 0 NULL 22823 * <bar> 1 NULL 22824 * <target/> 2 2 target 22825 * <bar> 22826 * </scope> 22827 * 22828 * The size of the list is only dependant on the depth of 22829 * the tree. 22830 * An entry will be NULLed in selector_leave, i.e. when 22831 * we hit the target's 22832 */ 22833 pos = sto->depth - matcher->depth; 22834 idx = sto->sel->index; 22835 22836 /* 22837 * Create/grow the array of key-sequences. 22838 */ 22839 if (matcher->keySeqs == NULL) { 22840 if (pos > 9) 22841 matcher->sizeKeySeqs = pos * 2; 22842 else 22843 matcher->sizeKeySeqs = 10; 22844 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22845 xmlMalloc(matcher->sizeKeySeqs * 22846 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22847 if (matcher->keySeqs == NULL) { 22848 xmlSchemaVErrMemory(NULL, 22849 "allocating an array of key-sequences", 22850 NULL); 22851 return(-1); 22852 } 22853 memset(matcher->keySeqs, 0, 22854 matcher->sizeKeySeqs * 22855 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22856 } else if (pos >= matcher->sizeKeySeqs) { 22857 int i = matcher->sizeKeySeqs; 22858 22859 matcher->sizeKeySeqs *= 2; 22860 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22861 xmlRealloc(matcher->keySeqs, 22862 matcher->sizeKeySeqs * 22863 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22864 if (matcher->keySeqs == NULL) { 22865 xmlSchemaVErrMemory(NULL, 22866 "reallocating an array of key-sequences", 22867 NULL); 22868 return (-1); 22869 } 22870 /* 22871 * The array needs to be NULLed. 22872 * TODO: Use memset? 22873 */ 22874 for (; i < matcher->sizeKeySeqs; i++) 22875 matcher->keySeqs[i] = NULL; 22876 } 22877 22878 /* 22879 * Get/create the key-sequence. 22880 */ 22881 keySeq = matcher->keySeqs[pos]; 22882 if (keySeq == NULL) { 22883 goto create_sequence; 22884 } else if (keySeq[idx] != NULL) { 22885 xmlChar *str = NULL; 22886 /* 22887 * cvc-identity-constraint: 22888 * 3 For each node in the `target node set` all 22889 * of the {fields}, with that node as the context 22890 * node, evaluate to either an empty node-set or 22891 * a node-set with exactly one member, which must 22892 * have a simple type. 22893 * 22894 * The key was already set; report an error. 22895 */ 22896 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22897 XML_SCHEMAV_CVC_IDC, NULL, 22898 WXS_BASIC_CAST matcher->aidc->def, 22899 "The XPath '%s' of a field of %s evaluates to a " 22900 "node-set with more than one member", 22901 sto->sel->xpath, 22902 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22903 FREE_AND_NULL(str); 22904 sto->nbHistory--; 22905 goto deregister_check; 22906 } else 22907 goto create_key; 22908 22909 create_sequence: 22910 /* 22911 * Create a key-sequence. 22912 */ 22913 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22914 matcher->aidc->def->nbFields * 22915 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22916 if (keySeq == NULL) { 22917 xmlSchemaVErrMemory(NULL, 22918 "allocating an IDC key-sequence", NULL); 22919 return(-1); 22920 } 22921 memset(keySeq, 0, matcher->aidc->def->nbFields * 22922 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22923 matcher->keySeqs[pos] = keySeq; 22924 create_key: 22925 /* 22926 * Create a key once per node only. 22927 */ 22928 if (key == NULL) { 22929 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22930 sizeof(xmlSchemaPSVIIDCKey)); 22931 if (key == NULL) { 22932 xmlSchemaVErrMemory(NULL, 22933 "allocating a IDC key", NULL); 22934 xmlFree(keySeq); 22935 matcher->keySeqs[pos] = NULL; 22936 return(-1); 22937 } 22938 /* 22939 * Consume the compiled value. 22940 */ 22941 key->type = simpleType; 22942 key->val = vctxt->inode->val; 22943 vctxt->inode->val = NULL; 22944 /* 22945 * Store the key in a global list. 22946 */ 22947 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22948 xmlSchemaIDCFreeKey(key); 22949 return (-1); 22950 } 22951 } 22952 keySeq[idx] = key; 22953 } 22954 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22955 22956 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22957 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22958 xmlSchemaPSVIIDCNodePtr ntItem; 22959 xmlSchemaIDCMatcherPtr matcher; 22960 xmlSchemaIDCPtr idc; 22961 xmlSchemaItemListPtr targets; 22962 int pos, i, j, nbKeys; 22963 /* 22964 * Here we have the following scenario: 22965 * An IDC 'selector' state object resolved to a target node, 22966 * during the time this target node was in the 22967 * ancestor-or-self axis, the 'field' state object(s) looked 22968 * out for matching nodes to create a key-sequence for this 22969 * target node. Now we are back to this target node and need 22970 * to put the key-sequence, together with the target node 22971 * itself, into the node-table of the corresponding IDC 22972 * binding. 22973 */ 22974 matcher = sto->matcher; 22975 idc = matcher->aidc->def; 22976 nbKeys = idc->nbFields; 22977 pos = depth - matcher->depth; 22978 /* 22979 * Check if the matcher has any key-sequences at all, plus 22980 * if it has a key-sequence for the current target node. 22981 */ 22982 if ((matcher->keySeqs == NULL) || 22983 (matcher->sizeKeySeqs <= pos)) { 22984 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22985 goto selector_key_error; 22986 else 22987 goto selector_leave; 22988 } 22989 22990 keySeq = &(matcher->keySeqs[pos]); 22991 if (*keySeq == NULL) { 22992 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22993 goto selector_key_error; 22994 else 22995 goto selector_leave; 22996 } 22997 22998 for (i = 0; i < nbKeys; i++) { 22999 if ((*keySeq)[i] == NULL) { 23000 /* 23001 * Not qualified, if not all fields did resolve. 23002 */ 23003 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 23004 /* 23005 * All fields of a "key" IDC must resolve. 23006 */ 23007 goto selector_key_error; 23008 } 23009 goto selector_leave; 23010 } 23011 } 23012 /* 23013 * All fields did resolve. 23014 */ 23015 23016 /* 23017 * 4.1 If the {identity-constraint category} is unique(/key), 23018 * then no two members of the `qualified node set` have 23019 * `key-sequences` whose members are pairwise equal, as 23020 * defined by Equal in [XML Schemas: Datatypes]. 23021 * 23022 * Get the IDC binding from the matcher and check for 23023 * duplicate key-sequences. 23024 */ 23025 #if 0 23026 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23027 #endif 23028 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 23029 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 23030 (targets->nbItems != 0)) { 23031 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 23032 23033 i = 0; 23034 res = 0; 23035 /* 23036 * Compare the key-sequences, key by key. 23037 */ 23038 do { 23039 bkeySeq = 23040 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 23041 for (j = 0; j < nbKeys; j++) { 23042 ckey = (*keySeq)[j]; 23043 bkey = bkeySeq[j]; 23044 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 23045 if (res == -1) { 23046 return (-1); 23047 } else if (res == 0) { 23048 /* 23049 * One of the keys differs, so the key-sequence 23050 * won't be equal; get out. 23051 */ 23052 break; 23053 } 23054 } 23055 if (res == 1) { 23056 /* 23057 * Duplicate key-sequence found. 23058 */ 23059 break; 23060 } 23061 i++; 23062 } while (i < targets->nbItems); 23063 if (i != targets->nbItems) { 23064 xmlChar *str = NULL, *strB = NULL; 23065 /* 23066 * TODO: Try to report the key-sequence. 23067 */ 23068 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23069 XML_SCHEMAV_CVC_IDC, NULL, 23070 WXS_BASIC_CAST idc, 23071 "Duplicate key-sequence %s in %s", 23072 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23073 (*keySeq), nbKeys), 23074 xmlSchemaGetIDCDesignation(&strB, idc)); 23075 FREE_AND_NULL(str); 23076 FREE_AND_NULL(strB); 23077 goto selector_leave; 23078 } 23079 } 23080 /* 23081 * Add a node-table item to the IDC binding. 23082 */ 23083 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23084 sizeof(xmlSchemaPSVIIDCNode)); 23085 if (ntItem == NULL) { 23086 xmlSchemaVErrMemory(NULL, 23087 "allocating an IDC node-table item", NULL); 23088 xmlFree(*keySeq); 23089 *keySeq = NULL; 23090 return(-1); 23091 } 23092 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23093 23094 /* 23095 * Store the node-table item in a global list. 23096 */ 23097 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23098 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23099 xmlFree(ntItem); 23100 xmlFree(*keySeq); 23101 *keySeq = NULL; 23102 return (-1); 23103 } 23104 ntItem->nodeQNameID = -1; 23105 } else { 23106 /* 23107 * Save a cached QName for this node on the IDC node, to be 23108 * able to report it, even if the node is not saved. 23109 */ 23110 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23111 vctxt->inode->localName, vctxt->inode->nsName); 23112 if (ntItem->nodeQNameID == -1) { 23113 xmlFree(ntItem); 23114 xmlFree(*keySeq); 23115 *keySeq = NULL; 23116 return (-1); 23117 } 23118 } 23119 /* 23120 * Init the node-table item: Save the node, position and 23121 * consume the key-sequence. 23122 */ 23123 ntItem->node = vctxt->node; 23124 ntItem->nodeLine = vctxt->inode->nodeLine; 23125 ntItem->keys = *keySeq; 23126 *keySeq = NULL; 23127 #if 0 23128 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23129 #endif 23130 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23131 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23132 /* 23133 * Free the item, since keyref items won't be 23134 * put on a global list. 23135 */ 23136 xmlFree(ntItem->keys); 23137 xmlFree(ntItem); 23138 } 23139 return (-1); 23140 } 23141 23142 goto selector_leave; 23143 selector_key_error: 23144 { 23145 xmlChar *str = NULL; 23146 /* 23147 * 4.2.1 (KEY) The `target node set` and the 23148 * `qualified node set` are equal, that is, every 23149 * member of the `target node set` is also a member 23150 * of the `qualified node set` and vice versa. 23151 */ 23152 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23153 XML_SCHEMAV_CVC_IDC, NULL, 23154 WXS_BASIC_CAST idc, 23155 "Not all fields of %s evaluate to a node", 23156 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23157 FREE_AND_NULL(str); 23158 } 23159 selector_leave: 23160 /* 23161 * Free the key-sequence if not added to the IDC table. 23162 */ 23163 if ((keySeq != NULL) && (*keySeq != NULL)) { 23164 xmlFree(*keySeq); 23165 *keySeq = NULL; 23166 } 23167 } /* if selector */ 23168 23169 sto->nbHistory--; 23170 23171 deregister_check: 23172 /* 23173 * Deregister state objects if they reach the depth of creation. 23174 */ 23175 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23176 #ifdef DEBUG_IDC 23177 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23178 sto->sel->xpath); 23179 #endif 23180 if (vctxt->xpathStates != sto) { 23181 VERROR_INT("xmlSchemaXPathProcessHistory", 23182 "The state object to be removed is not the first " 23183 "in the list"); 23184 } 23185 nextsto = sto->next; 23186 /* 23187 * Unlink from the list of active XPath state objects. 23188 */ 23189 vctxt->xpathStates = sto->next; 23190 sto->next = vctxt->xpathStatePool; 23191 /* 23192 * Link it to the pool of reusable state objects. 23193 */ 23194 vctxt->xpathStatePool = sto; 23195 sto = nextsto; 23196 } else 23197 sto = sto->next; 23198 } /* while (sto != NULL) */ 23199 return (0); 23200 } 23201 23202 /** 23203 * xmlSchemaIDCRegisterMatchers: 23204 * @vctxt: the WXS validation context 23205 * @elemDecl: the element declaration 23206 * 23207 * Creates helper objects to evaluate IDC selectors/fields 23208 * successively. 23209 * 23210 * Returns 0 if OK and -1 on internal errors. 23211 */ 23212 static int 23213 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23214 xmlSchemaElementPtr elemDecl) 23215 { 23216 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23217 xmlSchemaIDCPtr idc, refIdc; 23218 xmlSchemaIDCAugPtr aidc; 23219 23220 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23221 if (idc == NULL) 23222 return (0); 23223 23224 #ifdef DEBUG_IDC 23225 { 23226 xmlChar *str = NULL; 23227 xmlGenericError(xmlGenericErrorContext, 23228 "IDC: REGISTER on %s, depth %d\n", 23229 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23230 vctxt->inode->localName), vctxt->depth); 23231 FREE_AND_NULL(str) 23232 } 23233 #endif 23234 if (vctxt->inode->idcMatchers != NULL) { 23235 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23236 "The chain of IDC matchers is expected to be empty"); 23237 return (-1); 23238 } 23239 do { 23240 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23241 /* 23242 * Since IDCs bubbles are expensive we need to know the 23243 * depth at which the bubbles should stop; this will be 23244 * the depth of the top-most keyref IDC. If no keyref 23245 * references a key/unique IDC, the keyrefDepth will 23246 * be -1, indicating that no bubbles are needed. 23247 */ 23248 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23249 if (refIdc != NULL) { 23250 /* 23251 * Remember that we have keyrefs on this node. 23252 */ 23253 vctxt->inode->hasKeyrefs = 1; 23254 /* 23255 * Lookup the referenced augmented IDC info. 23256 */ 23257 aidc = vctxt->aidcs; 23258 while (aidc != NULL) { 23259 if (aidc->def == refIdc) 23260 break; 23261 aidc = aidc->next; 23262 } 23263 if (aidc == NULL) { 23264 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23265 "Could not find an augmented IDC item for an IDC " 23266 "definition"); 23267 return (-1); 23268 } 23269 if ((aidc->keyrefDepth == -1) || 23270 (vctxt->depth < aidc->keyrefDepth)) 23271 aidc->keyrefDepth = vctxt->depth; 23272 } 23273 } 23274 /* 23275 * Lookup the augmented IDC item for the IDC definition. 23276 */ 23277 aidc = vctxt->aidcs; 23278 while (aidc != NULL) { 23279 if (aidc->def == idc) 23280 break; 23281 aidc = aidc->next; 23282 } 23283 if (aidc == NULL) { 23284 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23285 "Could not find an augmented IDC item for an IDC definition"); 23286 return (-1); 23287 } 23288 /* 23289 * Create an IDC matcher for every IDC definition. 23290 */ 23291 if (vctxt->idcMatcherCache != NULL) { 23292 /* 23293 * Reuse a cached matcher. 23294 */ 23295 matcher = vctxt->idcMatcherCache; 23296 vctxt->idcMatcherCache = matcher->nextCached; 23297 matcher->nextCached = NULL; 23298 } else { 23299 matcher = (xmlSchemaIDCMatcherPtr) 23300 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23301 if (matcher == NULL) { 23302 xmlSchemaVErrMemory(vctxt, 23303 "allocating an IDC matcher", NULL); 23304 return (-1); 23305 } 23306 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23307 } 23308 if (last == NULL) 23309 vctxt->inode->idcMatchers = matcher; 23310 else 23311 last->next = matcher; 23312 last = matcher; 23313 23314 matcher->type = IDC_MATCHER; 23315 matcher->depth = vctxt->depth; 23316 matcher->aidc = aidc; 23317 matcher->idcType = aidc->def->type; 23318 #ifdef DEBUG_IDC 23319 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23320 #endif 23321 /* 23322 * Init the automaton state object. 23323 */ 23324 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23325 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23326 return (-1); 23327 23328 idc = idc->next; 23329 } while (idc != NULL); 23330 return (0); 23331 } 23332 23333 static int 23334 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23335 xmlSchemaNodeInfoPtr ielem) 23336 { 23337 xmlSchemaPSVIIDCBindingPtr bind; 23338 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23339 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23340 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23341 23342 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23343 /* vctxt->createIDCNodeTables */ 23344 while (matcher != NULL) { 23345 /* 23346 * Skip keyref IDCs and empty IDC target-lists. 23347 */ 23348 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23349 WXS_ILIST_IS_EMPTY(matcher->targets)) 23350 { 23351 matcher = matcher->next; 23352 continue; 23353 } 23354 /* 23355 * If we _want_ the IDC node-table to be created in any case 23356 * then do so. Otherwise create them only if keyrefs need them. 23357 */ 23358 if ((! vctxt->createIDCNodeTables) && 23359 ((matcher->aidc->keyrefDepth == -1) || 23360 (matcher->aidc->keyrefDepth > vctxt->depth))) 23361 { 23362 matcher = matcher->next; 23363 continue; 23364 } 23365 /* 23366 * Get/create the IDC binding on this element for the IDC definition. 23367 */ 23368 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23369 23370 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23371 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23372 nbDupls = bind->dupls->nbItems; 23373 } else { 23374 dupls = NULL; 23375 nbDupls = 0; 23376 } 23377 if (bind->nodeTable != NULL) { 23378 nbNodeTable = bind->nbNodes; 23379 } else { 23380 nbNodeTable = 0; 23381 } 23382 23383 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23384 /* 23385 * Transfer all IDC target-nodes to the IDC node-table. 23386 */ 23387 bind->nodeTable = 23388 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23389 bind->sizeNodes = matcher->targets->sizeItems; 23390 bind->nbNodes = matcher->targets->nbItems; 23391 23392 matcher->targets->items = NULL; 23393 matcher->targets->sizeItems = 0; 23394 matcher->targets->nbItems = 0; 23395 } else { 23396 /* 23397 * Compare the key-sequences and add to the IDC node-table. 23398 */ 23399 nbTargets = matcher->targets->nbItems; 23400 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23401 nbFields = matcher->aidc->def->nbFields; 23402 i = 0; 23403 do { 23404 keys = targets[i]->keys; 23405 if (nbDupls) { 23406 /* 23407 * Search in already found duplicates first. 23408 */ 23409 j = 0; 23410 do { 23411 if (nbFields == 1) { 23412 res = xmlSchemaAreValuesEqual(keys[0]->val, 23413 dupls[j]->keys[0]->val); 23414 if (res == -1) 23415 goto internal_error; 23416 if (res == 1) { 23417 /* 23418 * Equal key-sequence. 23419 */ 23420 goto next_target; 23421 } 23422 } else { 23423 res = 0; 23424 ntkeys = dupls[j]->keys; 23425 for (k = 0; k < nbFields; k++) { 23426 res = xmlSchemaAreValuesEqual(keys[k]->val, 23427 ntkeys[k]->val); 23428 if (res == -1) 23429 goto internal_error; 23430 if (res == 0) { 23431 /* 23432 * One of the keys differs. 23433 */ 23434 break; 23435 } 23436 } 23437 if (res == 1) { 23438 /* 23439 * Equal key-sequence found. 23440 */ 23441 goto next_target; 23442 } 23443 } 23444 j++; 23445 } while (j < nbDupls); 23446 } 23447 if (nbNodeTable) { 23448 j = 0; 23449 do { 23450 if (nbFields == 1) { 23451 res = xmlSchemaAreValuesEqual(keys[0]->val, 23452 bind->nodeTable[j]->keys[0]->val); 23453 if (res == -1) 23454 goto internal_error; 23455 if (res == 0) { 23456 /* 23457 * The key-sequence differs. 23458 */ 23459 goto next_node_table_entry; 23460 } 23461 } else { 23462 res = 0; 23463 ntkeys = bind->nodeTable[j]->keys; 23464 for (k = 0; k < nbFields; k++) { 23465 res = xmlSchemaAreValuesEqual(keys[k]->val, 23466 ntkeys[k]->val); 23467 if (res == -1) 23468 goto internal_error; 23469 if (res == 0) { 23470 /* 23471 * One of the keys differs. 23472 */ 23473 goto next_node_table_entry; 23474 } 23475 } 23476 } 23477 /* 23478 * Add the duplicate to the list of duplicates. 23479 */ 23480 if (bind->dupls == NULL) { 23481 bind->dupls = xmlSchemaItemListCreate(); 23482 if (bind->dupls == NULL) 23483 goto internal_error; 23484 } 23485 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23486 goto internal_error; 23487 /* 23488 * Remove the duplicate entry from the IDC node-table. 23489 */ 23490 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23491 bind->nbNodes--; 23492 23493 goto next_target; 23494 23495 next_node_table_entry: 23496 j++; 23497 } while (j < nbNodeTable); 23498 } 23499 /* 23500 * If everything is fine, then add the IDC target-node to 23501 * the IDC node-table. 23502 */ 23503 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23504 goto internal_error; 23505 23506 next_target: 23507 i++; 23508 } while (i < nbTargets); 23509 } 23510 matcher = matcher->next; 23511 } 23512 return(0); 23513 23514 internal_error: 23515 return(-1); 23516 } 23517 23518 /** 23519 * xmlSchemaBubbleIDCNodeTables: 23520 * @depth: the current tree depth 23521 * 23522 * Merges IDC bindings of an element at @depth into the corresponding IDC 23523 * bindings of its parent element. If a duplicate note-table entry is found, 23524 * both, the parent node-table entry and child entry are discarded from the 23525 * node-table of the parent. 23526 * 23527 * Returns 0 if OK and -1 on internal errors. 23528 */ 23529 static int 23530 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23531 { 23532 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23533 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23534 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23535 xmlSchemaIDCAugPtr aidc; 23536 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23537 23538 bind = vctxt->inode->idcTable; 23539 if (bind == NULL) { 23540 /* Fine, no table, no bubbles. */ 23541 return (0); 23542 } 23543 23544 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23545 /* 23546 * Walk all bindings; create new or add to existing bindings. 23547 * Remove duplicate key-sequences. 23548 */ 23549 while (bind != NULL) { 23550 23551 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23552 goto next_binding; 23553 /* 23554 * Check if the key/unique IDC table needs to be bubbled. 23555 */ 23556 if (! vctxt->createIDCNodeTables) { 23557 aidc = vctxt->aidcs; 23558 do { 23559 if (aidc->def == bind->definition) { 23560 if ((aidc->keyrefDepth == -1) || 23561 (aidc->keyrefDepth >= vctxt->depth)) { 23562 goto next_binding; 23563 } 23564 break; 23565 } 23566 aidc = aidc->next; 23567 } while (aidc != NULL); 23568 } 23569 23570 if (parTable != NULL) 23571 parBind = *parTable; 23572 /* 23573 * Search a matching parent binding for the 23574 * IDC definition. 23575 */ 23576 while (parBind != NULL) { 23577 if (parBind->definition == bind->definition) 23578 break; 23579 parBind = parBind->next; 23580 } 23581 23582 if (parBind != NULL) { 23583 /* 23584 * Compare every node-table entry of the child node, 23585 * i.e. the key-sequence within, ... 23586 */ 23587 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23588 23589 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23590 oldDupls = parBind->dupls->nbItems; 23591 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23592 } else { 23593 dupls = NULL; 23594 oldDupls = 0; 23595 } 23596 23597 parNodes = parBind->nodeTable; 23598 nbFields = bind->definition->nbFields; 23599 23600 for (i = 0; i < bind->nbNodes; i++) { 23601 node = bind->nodeTable[i]; 23602 if (node == NULL) 23603 continue; 23604 /* 23605 * ...with every key-sequence of the parent node, already 23606 * evaluated to be a duplicate key-sequence. 23607 */ 23608 if (oldDupls) { 23609 j = 0; 23610 while (j < oldDupls) { 23611 if (nbFields == 1) { 23612 ret = xmlSchemaAreValuesEqual( 23613 node->keys[0]->val, 23614 dupls[j]->keys[0]->val); 23615 if (ret == -1) 23616 goto internal_error; 23617 if (ret == 0) { 23618 j++; 23619 continue; 23620 } 23621 } else { 23622 parNode = dupls[j]; 23623 for (k = 0; k < nbFields; k++) { 23624 ret = xmlSchemaAreValuesEqual( 23625 node->keys[k]->val, 23626 parNode->keys[k]->val); 23627 if (ret == -1) 23628 goto internal_error; 23629 if (ret == 0) 23630 break; 23631 } 23632 } 23633 if (ret == 1) 23634 /* Duplicate found. */ 23635 break; 23636 j++; 23637 } 23638 if (j != oldDupls) { 23639 /* Duplicate found. Skip this entry. */ 23640 continue; 23641 } 23642 } 23643 /* 23644 * ... and with every key-sequence of the parent node. 23645 */ 23646 if (oldNum) { 23647 j = 0; 23648 while (j < oldNum) { 23649 parNode = parNodes[j]; 23650 if (nbFields == 1) { 23651 ret = xmlSchemaAreValuesEqual( 23652 node->keys[0]->val, 23653 parNode->keys[0]->val); 23654 if (ret == -1) 23655 goto internal_error; 23656 if (ret == 0) { 23657 j++; 23658 continue; 23659 } 23660 } else { 23661 for (k = 0; k < nbFields; k++) { 23662 ret = xmlSchemaAreValuesEqual( 23663 node->keys[k]->val, 23664 parNode->keys[k]->val); 23665 if (ret == -1) 23666 goto internal_error; 23667 if (ret == 0) 23668 break; 23669 } 23670 } 23671 if (ret == 1) 23672 /* Duplicate found. */ 23673 break; 23674 j++; 23675 } 23676 if (j != oldNum) { 23677 /* 23678 * Handle duplicates. Move the duplicate in 23679 * the parent's node-table to the list of 23680 * duplicates. 23681 */ 23682 oldNum--; 23683 parBind->nbNodes--; 23684 /* 23685 * Move last old item to pos of duplicate. 23686 */ 23687 parNodes[j] = parNodes[oldNum]; 23688 23689 if (parBind->nbNodes != oldNum) { 23690 /* 23691 * If new items exist, move last new item to 23692 * last of old items. 23693 */ 23694 parNodes[oldNum] = 23695 parNodes[parBind->nbNodes]; 23696 } 23697 if (parBind->dupls == NULL) { 23698 parBind->dupls = xmlSchemaItemListCreate(); 23699 if (parBind->dupls == NULL) 23700 goto internal_error; 23701 } 23702 xmlSchemaItemListAdd(parBind->dupls, parNode); 23703 } else { 23704 /* 23705 * Add the node-table entry (node and key-sequence) of 23706 * the child node to the node table of the parent node. 23707 */ 23708 if (parBind->nodeTable == NULL) { 23709 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23710 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23711 if (parBind->nodeTable == NULL) { 23712 xmlSchemaVErrMemory(NULL, 23713 "allocating IDC list of node-table items", NULL); 23714 goto internal_error; 23715 } 23716 parBind->sizeNodes = 1; 23717 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23718 parBind->sizeNodes *= 2; 23719 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23720 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23721 sizeof(xmlSchemaPSVIIDCNodePtr)); 23722 if (parBind->nodeTable == NULL) { 23723 xmlSchemaVErrMemory(NULL, 23724 "re-allocating IDC list of node-table items", NULL); 23725 goto internal_error; 23726 } 23727 } 23728 parNodes = parBind->nodeTable; 23729 /* 23730 * Append the new node-table entry to the 'new node-table 23731 * entries' section. 23732 */ 23733 parNodes[parBind->nbNodes++] = node; 23734 } 23735 23736 } 23737 23738 } 23739 } else { 23740 /* 23741 * No binding for the IDC was found: create a new one and 23742 * copy all node-tables. 23743 */ 23744 parBind = xmlSchemaIDCNewBinding(bind->definition); 23745 if (parBind == NULL) 23746 goto internal_error; 23747 23748 /* 23749 * TODO: Hmm, how to optimize the initial number of 23750 * allocated entries? 23751 */ 23752 if (bind->nbNodes != 0) { 23753 /* 23754 * Add all IDC node-table entries. 23755 */ 23756 if (! vctxt->psviExposeIDCNodeTables) { 23757 /* 23758 * Just move the entries. 23759 * NOTE: this is quite save here, since 23760 * all the keyref lookups have already been 23761 * performed. 23762 */ 23763 parBind->nodeTable = bind->nodeTable; 23764 bind->nodeTable = NULL; 23765 parBind->sizeNodes = bind->sizeNodes; 23766 bind->sizeNodes = 0; 23767 parBind->nbNodes = bind->nbNodes; 23768 bind->nbNodes = 0; 23769 } else { 23770 /* 23771 * Copy the entries. 23772 */ 23773 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23774 xmlMalloc(bind->nbNodes * 23775 sizeof(xmlSchemaPSVIIDCNodePtr)); 23776 if (parBind->nodeTable == NULL) { 23777 xmlSchemaVErrMemory(NULL, 23778 "allocating an array of IDC node-table " 23779 "items", NULL); 23780 xmlSchemaIDCFreeBinding(parBind); 23781 goto internal_error; 23782 } 23783 parBind->sizeNodes = bind->nbNodes; 23784 parBind->nbNodes = bind->nbNodes; 23785 memcpy(parBind->nodeTable, bind->nodeTable, 23786 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23787 } 23788 } 23789 if (bind->dupls) { 23790 /* 23791 * Move the duplicates. 23792 */ 23793 if (parBind->dupls != NULL) 23794 xmlSchemaItemListFree(parBind->dupls); 23795 parBind->dupls = bind->dupls; 23796 bind->dupls = NULL; 23797 } 23798 if (parTable != NULL) { 23799 if (*parTable == NULL) 23800 *parTable = parBind; 23801 else { 23802 parBind->next = *parTable; 23803 *parTable = parBind; 23804 } 23805 } 23806 } 23807 23808 next_binding: 23809 bind = bind->next; 23810 } 23811 return (0); 23812 23813 internal_error: 23814 return(-1); 23815 } 23816 23817 /** 23818 * xmlSchemaCheckCVCIDCKeyRef: 23819 * @vctxt: the WXS validation context 23820 * @elemDecl: the element declaration 23821 * 23822 * Check the cvc-idc-keyref constraints. 23823 */ 23824 static int 23825 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23826 { 23827 xmlSchemaIDCMatcherPtr matcher; 23828 xmlSchemaPSVIIDCBindingPtr bind; 23829 23830 matcher = vctxt->inode->idcMatchers; 23831 /* 23832 * Find a keyref. 23833 */ 23834 while (matcher != NULL) { 23835 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23836 matcher->targets && 23837 matcher->targets->nbItems) 23838 { 23839 int i, j, k, res, nbFields, hasDupls; 23840 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23841 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23842 23843 nbFields = matcher->aidc->def->nbFields; 23844 23845 /* 23846 * Find the IDC node-table for the referenced IDC key/unique. 23847 */ 23848 bind = vctxt->inode->idcTable; 23849 while (bind != NULL) { 23850 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23851 bind->definition) 23852 break; 23853 bind = bind->next; 23854 } 23855 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23856 /* 23857 * Search for a matching key-sequences. 23858 */ 23859 for (i = 0; i < matcher->targets->nbItems; i++) { 23860 res = 0; 23861 refNode = matcher->targets->items[i]; 23862 if (bind != NULL) { 23863 refKeys = refNode->keys; 23864 for (j = 0; j < bind->nbNodes; j++) { 23865 keys = bind->nodeTable[j]->keys; 23866 for (k = 0; k < nbFields; k++) { 23867 res = xmlSchemaAreValuesEqual(keys[k]->val, 23868 refKeys[k]->val); 23869 if (res == 0) 23870 break; 23871 else if (res == -1) { 23872 return (-1); 23873 } 23874 } 23875 if (res == 1) { 23876 /* 23877 * Match found. 23878 */ 23879 break; 23880 } 23881 } 23882 if ((res == 0) && hasDupls) { 23883 /* 23884 * Search in duplicates 23885 */ 23886 for (j = 0; j < bind->dupls->nbItems; j++) { 23887 keys = ((xmlSchemaPSVIIDCNodePtr) 23888 bind->dupls->items[j])->keys; 23889 for (k = 0; k < nbFields; k++) { 23890 res = xmlSchemaAreValuesEqual(keys[k]->val, 23891 refKeys[k]->val); 23892 if (res == 0) 23893 break; 23894 else if (res == -1) { 23895 return (-1); 23896 } 23897 } 23898 if (res == 1) { 23899 /* 23900 * Match in duplicates found. 23901 */ 23902 xmlChar *str = NULL, *strB = NULL; 23903 xmlSchemaKeyrefErr(vctxt, 23904 XML_SCHEMAV_CVC_IDC, refNode, 23905 (xmlSchemaTypePtr) matcher->aidc->def, 23906 "More than one match found for " 23907 "key-sequence %s of keyref '%s'", 23908 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23909 refNode->keys, nbFields), 23910 xmlSchemaGetComponentQName(&strB, 23911 matcher->aidc->def)); 23912 FREE_AND_NULL(str); 23913 FREE_AND_NULL(strB); 23914 break; 23915 } 23916 } 23917 } 23918 } 23919 23920 if (res == 0) { 23921 xmlChar *str = NULL, *strB = NULL; 23922 xmlSchemaKeyrefErr(vctxt, 23923 XML_SCHEMAV_CVC_IDC, refNode, 23924 (xmlSchemaTypePtr) matcher->aidc->def, 23925 "No match found for key-sequence %s of keyref '%s'", 23926 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23927 refNode->keys, nbFields), 23928 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23929 FREE_AND_NULL(str); 23930 FREE_AND_NULL(strB); 23931 } 23932 } 23933 } 23934 matcher = matcher->next; 23935 } 23936 /* TODO: Return an error if any error encountered. */ 23937 return (0); 23938 } 23939 23940 /************************************************************************ 23941 * * 23942 * XML Reader validation code * 23943 * * 23944 ************************************************************************/ 23945 23946 static xmlSchemaAttrInfoPtr 23947 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23948 { 23949 xmlSchemaAttrInfoPtr iattr; 23950 /* 23951 * Grow/create list of attribute infos. 23952 */ 23953 if (vctxt->attrInfos == NULL) { 23954 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23955 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23956 vctxt->sizeAttrInfos = 1; 23957 if (vctxt->attrInfos == NULL) { 23958 xmlSchemaVErrMemory(vctxt, 23959 "allocating attribute info list", NULL); 23960 return (NULL); 23961 } 23962 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23963 vctxt->sizeAttrInfos++; 23964 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23965 xmlRealloc(vctxt->attrInfos, 23966 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23967 if (vctxt->attrInfos == NULL) { 23968 xmlSchemaVErrMemory(vctxt, 23969 "re-allocating attribute info list", NULL); 23970 return (NULL); 23971 } 23972 } else { 23973 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23974 if (iattr->localName != NULL) { 23975 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23976 "attr info not cleared"); 23977 return (NULL); 23978 } 23979 iattr->nodeType = XML_ATTRIBUTE_NODE; 23980 return (iattr); 23981 } 23982 /* 23983 * Create an attribute info. 23984 */ 23985 iattr = (xmlSchemaAttrInfoPtr) 23986 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23987 if (iattr == NULL) { 23988 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23989 return (NULL); 23990 } 23991 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23992 iattr->nodeType = XML_ATTRIBUTE_NODE; 23993 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23994 23995 return (iattr); 23996 } 23997 23998 static int 23999 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 24000 xmlNodePtr attrNode, 24001 int nodeLine, 24002 const xmlChar *localName, 24003 const xmlChar *nsName, 24004 int ownedNames, 24005 xmlChar *value, 24006 int ownedValue) 24007 { 24008 xmlSchemaAttrInfoPtr attr; 24009 24010 attr = xmlSchemaGetFreshAttrInfo(vctxt); 24011 if (attr == NULL) { 24012 VERROR_INT("xmlSchemaPushAttribute", 24013 "calling xmlSchemaGetFreshAttrInfo()"); 24014 return (-1); 24015 } 24016 attr->node = attrNode; 24017 attr->nodeLine = nodeLine; 24018 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 24019 attr->localName = localName; 24020 attr->nsName = nsName; 24021 if (ownedNames) 24022 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 24023 /* 24024 * Evaluate if it's an XSI attribute. 24025 */ 24026 if (nsName != NULL) { 24027 if (xmlStrEqual(localName, BAD_CAST "nil")) { 24028 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24029 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 24030 } 24031 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 24032 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24033 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 24034 } 24035 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 24036 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24037 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 24038 } 24039 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 24040 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24041 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 24042 } 24043 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 24044 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 24045 } 24046 } 24047 attr->value = value; 24048 if (ownedValue) 24049 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 24050 if (attr->metaType != 0) 24051 attr->state = XML_SCHEMAS_ATTR_META; 24052 return (0); 24053 } 24054 24055 /** 24056 * xmlSchemaClearElemInfo: 24057 * @vctxt: the WXS validation context 24058 * @ielem: the element information item 24059 */ 24060 static void 24061 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 24062 xmlSchemaNodeInfoPtr ielem) 24063 { 24064 ielem->hasKeyrefs = 0; 24065 ielem->appliedXPath = 0; 24066 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 24067 FREE_AND_NULL(ielem->localName); 24068 FREE_AND_NULL(ielem->nsName); 24069 } else { 24070 ielem->localName = NULL; 24071 ielem->nsName = NULL; 24072 } 24073 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24074 FREE_AND_NULL(ielem->value); 24075 } else { 24076 ielem->value = NULL; 24077 } 24078 if (ielem->val != NULL) { 24079 /* 24080 * PSVI TODO: Be careful not to free it when the value is 24081 * exposed via PSVI. 24082 */ 24083 xmlSchemaFreeValue(ielem->val); 24084 ielem->val = NULL; 24085 } 24086 if (ielem->idcMatchers != NULL) { 24087 /* 24088 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24089 * Does it work? 24090 */ 24091 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24092 #if 0 24093 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24094 #endif 24095 ielem->idcMatchers = NULL; 24096 } 24097 if (ielem->idcTable != NULL) { 24098 /* 24099 * OPTIMIZE TODO: Use a pool of IDC tables??. 24100 */ 24101 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24102 ielem->idcTable = NULL; 24103 } 24104 if (ielem->regexCtxt != NULL) { 24105 xmlRegFreeExecCtxt(ielem->regexCtxt); 24106 ielem->regexCtxt = NULL; 24107 } 24108 if (ielem->nsBindings != NULL) { 24109 xmlFree((xmlChar **)ielem->nsBindings); 24110 ielem->nsBindings = NULL; 24111 ielem->nbNsBindings = 0; 24112 ielem->sizeNsBindings = 0; 24113 } 24114 } 24115 24116 /** 24117 * xmlSchemaGetFreshElemInfo: 24118 * @vctxt: the schema validation context 24119 * 24120 * Creates/reuses and initializes the element info item for 24121 * the currect tree depth. 24122 * 24123 * Returns the element info item or NULL on API or internal errors. 24124 */ 24125 static xmlSchemaNodeInfoPtr 24126 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24127 { 24128 xmlSchemaNodeInfoPtr info = NULL; 24129 24130 if (vctxt->depth > vctxt->sizeElemInfos) { 24131 VERROR_INT("xmlSchemaGetFreshElemInfo", 24132 "inconsistent depth encountered"); 24133 return (NULL); 24134 } 24135 if (vctxt->elemInfos == NULL) { 24136 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24137 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24138 if (vctxt->elemInfos == NULL) { 24139 xmlSchemaVErrMemory(vctxt, 24140 "allocating the element info array", NULL); 24141 return (NULL); 24142 } 24143 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24144 vctxt->sizeElemInfos = 10; 24145 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24146 int i = vctxt->sizeElemInfos; 24147 24148 vctxt->sizeElemInfos *= 2; 24149 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24150 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24151 sizeof(xmlSchemaNodeInfoPtr)); 24152 if (vctxt->elemInfos == NULL) { 24153 xmlSchemaVErrMemory(vctxt, 24154 "re-allocating the element info array", NULL); 24155 return (NULL); 24156 } 24157 /* 24158 * We need the new memory to be NULLed. 24159 * TODO: Use memset instead? 24160 */ 24161 for (; i < vctxt->sizeElemInfos; i++) 24162 vctxt->elemInfos[i] = NULL; 24163 } else 24164 info = vctxt->elemInfos[vctxt->depth]; 24165 24166 if (info == NULL) { 24167 info = (xmlSchemaNodeInfoPtr) 24168 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24169 if (info == NULL) { 24170 xmlSchemaVErrMemory(vctxt, 24171 "allocating an element info", NULL); 24172 return (NULL); 24173 } 24174 vctxt->elemInfos[vctxt->depth] = info; 24175 } else { 24176 if (info->localName != NULL) { 24177 VERROR_INT("xmlSchemaGetFreshElemInfo", 24178 "elem info has not been cleared"); 24179 return (NULL); 24180 } 24181 } 24182 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24183 info->nodeType = XML_ELEMENT_NODE; 24184 info->depth = vctxt->depth; 24185 24186 return (info); 24187 } 24188 24189 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24190 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24191 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24192 24193 static int 24194 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24195 xmlNodePtr node, 24196 xmlSchemaTypePtr type, 24197 xmlSchemaValType valType, 24198 const xmlChar * value, 24199 xmlSchemaValPtr val, 24200 unsigned long length, 24201 int fireErrors) 24202 { 24203 int ret, error = 0; 24204 24205 xmlSchemaTypePtr tmpType; 24206 xmlSchemaFacetLinkPtr facetLink; 24207 xmlSchemaFacetPtr facet; 24208 unsigned long len = 0; 24209 xmlSchemaWhitespaceValueType ws; 24210 24211 /* 24212 * In Libxml2, derived built-in types have currently no explicit facets. 24213 */ 24214 if (type->type == XML_SCHEMA_TYPE_BASIC) 24215 return (0); 24216 24217 /* 24218 * NOTE: Do not jump away, if the facetSet of the given type is 24219 * empty: until now, "pattern" and "enumeration" facets of the 24220 * *base types* need to be checked as well. 24221 */ 24222 if (type->facetSet == NULL) 24223 goto pattern_and_enum; 24224 24225 if (! WXS_IS_ATOMIC(type)) { 24226 if (WXS_IS_LIST(type)) 24227 goto WXS_IS_LIST; 24228 else 24229 goto pattern_and_enum; 24230 } 24231 24232 /* 24233 * Whitespace handling is only of importance for string-based 24234 * types. 24235 */ 24236 tmpType = xmlSchemaGetPrimitiveType(type); 24237 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24238 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24239 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24240 } else 24241 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24242 24243 /* 24244 * If the value was not computed (for string or 24245 * anySimpleType based types), then use the provided 24246 * type. 24247 */ 24248 if (val != NULL) 24249 valType = xmlSchemaGetValType(val); 24250 24251 ret = 0; 24252 for (facetLink = type->facetSet; facetLink != NULL; 24253 facetLink = facetLink->next) { 24254 /* 24255 * Skip the pattern "whiteSpace": it is used to 24256 * format the character content beforehand. 24257 */ 24258 switch (facetLink->facet->type) { 24259 case XML_SCHEMA_FACET_WHITESPACE: 24260 case XML_SCHEMA_FACET_PATTERN: 24261 case XML_SCHEMA_FACET_ENUMERATION: 24262 continue; 24263 case XML_SCHEMA_FACET_LENGTH: 24264 case XML_SCHEMA_FACET_MINLENGTH: 24265 case XML_SCHEMA_FACET_MAXLENGTH: 24266 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24267 valType, value, val, &len, ws); 24268 break; 24269 default: 24270 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24271 valType, value, val, ws); 24272 break; 24273 } 24274 if (ret < 0) { 24275 AERROR_INT("xmlSchemaValidateFacets", 24276 "validating against a atomic type facet"); 24277 return (-1); 24278 } else if (ret > 0) { 24279 if (fireErrors) 24280 xmlSchemaFacetErr(actxt, ret, node, 24281 value, len, type, facetLink->facet, NULL, NULL, NULL); 24282 else 24283 return (ret); 24284 if (error == 0) 24285 error = ret; 24286 } 24287 ret = 0; 24288 } 24289 24290 WXS_IS_LIST: 24291 if (! WXS_IS_LIST(type)) 24292 goto pattern_and_enum; 24293 /* 24294 * "length", "minLength" and "maxLength" of list types. 24295 */ 24296 ret = 0; 24297 for (facetLink = type->facetSet; facetLink != NULL; 24298 facetLink = facetLink->next) { 24299 24300 switch (facetLink->facet->type) { 24301 case XML_SCHEMA_FACET_LENGTH: 24302 case XML_SCHEMA_FACET_MINLENGTH: 24303 case XML_SCHEMA_FACET_MAXLENGTH: 24304 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24305 value, length, NULL); 24306 break; 24307 default: 24308 continue; 24309 } 24310 if (ret < 0) { 24311 AERROR_INT("xmlSchemaValidateFacets", 24312 "validating against a list type facet"); 24313 return (-1); 24314 } else if (ret > 0) { 24315 if (fireErrors) 24316 xmlSchemaFacetErr(actxt, ret, node, 24317 value, length, type, facetLink->facet, NULL, NULL, NULL); 24318 else 24319 return (ret); 24320 if (error == 0) 24321 error = ret; 24322 } 24323 ret = 0; 24324 } 24325 24326 pattern_and_enum: 24327 if (error >= 0) { 24328 int found = 0; 24329 /* 24330 * Process enumerations. Facet values are in the value space 24331 * of the defining type's base type. This seems to be a bug in the 24332 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24333 * Only the first set of enumerations in the ancestor-or-self axis 24334 * is used for validation. 24335 */ 24336 ret = 0; 24337 tmpType = type; 24338 do { 24339 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24340 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24341 continue; 24342 found = 1; 24343 ret = xmlSchemaAreValuesEqual(facet->val, val); 24344 if (ret == 1) 24345 break; 24346 else if (ret < 0) { 24347 AERROR_INT("xmlSchemaValidateFacets", 24348 "validating against an enumeration facet"); 24349 return (-1); 24350 } 24351 } 24352 if (ret != 0) 24353 break; 24354 /* 24355 * Break on the first set of enumerations. Any additional 24356 * enumerations which might be existent on the ancestors 24357 * of the current type are restricted by this set; thus 24358 * *must* *not* be taken into account. 24359 */ 24360 if (found) 24361 break; 24362 tmpType = tmpType->baseType; 24363 } while ((tmpType != NULL) && 24364 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24365 if (found && (ret == 0)) { 24366 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24367 if (fireErrors) { 24368 xmlSchemaFacetErr(actxt, ret, node, 24369 value, 0, type, NULL, NULL, NULL, NULL); 24370 } else 24371 return (ret); 24372 if (error == 0) 24373 error = ret; 24374 } 24375 } 24376 24377 if (error >= 0) { 24378 int found; 24379 /* 24380 * Process patters. Pattern facets are ORed at type level 24381 * and ANDed if derived. Walk the base type axis. 24382 */ 24383 tmpType = type; 24384 facet = NULL; 24385 do { 24386 found = 0; 24387 for (facetLink = tmpType->facetSet; facetLink != NULL; 24388 facetLink = facetLink->next) { 24389 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24390 continue; 24391 found = 1; 24392 /* 24393 * NOTE that for patterns, @value needs to be the 24394 * normalized vaule. 24395 */ 24396 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24397 if (ret == 1) 24398 break; 24399 else if (ret < 0) { 24400 AERROR_INT("xmlSchemaValidateFacets", 24401 "validating against a pattern facet"); 24402 return (-1); 24403 } else { 24404 /* 24405 * Save the last non-validating facet. 24406 */ 24407 facet = facetLink->facet; 24408 } 24409 } 24410 if (found && (ret != 1)) { 24411 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24412 if (fireErrors) { 24413 xmlSchemaFacetErr(actxt, ret, node, 24414 value, 0, type, facet, NULL, NULL, NULL); 24415 } else 24416 return (ret); 24417 if (error == 0) 24418 error = ret; 24419 break; 24420 } 24421 tmpType = tmpType->baseType; 24422 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24423 } 24424 24425 return (error); 24426 } 24427 24428 static xmlChar * 24429 xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24430 const xmlChar *value) 24431 { 24432 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24433 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24434 return (xmlSchemaCollapseString(value)); 24435 case XML_SCHEMA_WHITESPACE_REPLACE: 24436 return (xmlSchemaWhiteSpaceReplace(value)); 24437 default: 24438 return (NULL); 24439 } 24440 } 24441 24442 static int 24443 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24444 const xmlChar *value, 24445 xmlSchemaValPtr *val, 24446 int valNeeded) 24447 { 24448 int ret; 24449 const xmlChar *nsName; 24450 xmlChar *local, *prefix = NULL; 24451 24452 ret = xmlValidateQName(value, 1); 24453 if (ret != 0) { 24454 if (ret == -1) { 24455 VERROR_INT("xmlSchemaValidateQName", 24456 "calling xmlValidateQName()"); 24457 return (-1); 24458 } 24459 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24460 } 24461 /* 24462 * NOTE: xmlSplitQName2 will always return a duplicated 24463 * strings. 24464 */ 24465 local = xmlSplitQName2(value, &prefix); 24466 if (local == NULL) 24467 local = xmlStrdup(value); 24468 /* 24469 * OPTIMIZE TODO: Use flags for: 24470 * - is there any namespace binding? 24471 * - is there a default namespace? 24472 */ 24473 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24474 24475 if (prefix != NULL) { 24476 xmlFree(prefix); 24477 /* 24478 * A namespace must be found if the prefix is 24479 * NOT NULL. 24480 */ 24481 if (nsName == NULL) { 24482 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24483 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24484 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24485 "The QName value '%s' has no " 24486 "corresponding namespace declaration in " 24487 "scope", value, NULL); 24488 if (local != NULL) 24489 xmlFree(local); 24490 return (ret); 24491 } 24492 } 24493 if (valNeeded && val) { 24494 if (nsName != NULL) 24495 *val = xmlSchemaNewQNameValue( 24496 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24497 else 24498 *val = xmlSchemaNewQNameValue(NULL, 24499 BAD_CAST local); 24500 } else 24501 xmlFree(local); 24502 return (0); 24503 } 24504 24505 /* 24506 * cvc-simple-type 24507 */ 24508 static int 24509 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24510 xmlNodePtr node, 24511 xmlSchemaTypePtr type, 24512 const xmlChar *value, 24513 xmlSchemaValPtr *retVal, 24514 int fireErrors, 24515 int normalize, 24516 int isNormalized) 24517 { 24518 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24519 xmlSchemaValPtr val = NULL; 24520 /* xmlSchemaWhitespaceValueType ws; */ 24521 xmlChar *normValue = NULL; 24522 24523 #define NORMALIZE(atype) \ 24524 if ((! isNormalized) && \ 24525 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24526 normValue = xmlSchemaNormalizeValue(atype, value); \ 24527 if (normValue != NULL) \ 24528 value = normValue; \ 24529 isNormalized = 1; \ 24530 } 24531 24532 if ((retVal != NULL) && (*retVal != NULL)) { 24533 xmlSchemaFreeValue(*retVal); 24534 *retVal = NULL; 24535 } 24536 /* 24537 * 3.14.4 Simple Type Definition Validation Rules 24538 * Validation Rule: String Valid 24539 */ 24540 /* 24541 * 1 It is schema-valid with respect to that definition as defined 24542 * by Datatype Valid in [XML Schemas: Datatypes]. 24543 */ 24544 /* 24545 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24546 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then 24547 * the string must be a `declared entity name`. 24548 */ 24549 /* 24550 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24551 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), 24552 * then every whitespace-delimited substring of the string must be a `declared 24553 * entity name`. 24554 */ 24555 /* 24556 * 2.3 otherwise no further condition applies. 24557 */ 24558 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24559 valNeeded = 1; 24560 if (value == NULL) 24561 value = BAD_CAST ""; 24562 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24563 xmlSchemaTypePtr biType; /* The built-in type. */ 24564 /* 24565 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match` 24566 * a literal in the `lexical space` of {base type definition}" 24567 */ 24568 /* 24569 * Whitespace-normalize. 24570 */ 24571 NORMALIZE(type); 24572 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24573 /* 24574 * Get the built-in type. 24575 */ 24576 biType = type->baseType; 24577 while ((biType != NULL) && 24578 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24579 biType = biType->baseType; 24580 24581 if (biType == NULL) { 24582 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24583 "could not get the built-in type"); 24584 goto internal_error; 24585 } 24586 } else 24587 biType = type; 24588 /* 24589 * NOTATIONs need to be processed here, since they need 24590 * to lookup in the hashtable of NOTATION declarations of the schema. 24591 */ 24592 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24593 switch (biType->builtInType) { 24594 case XML_SCHEMAS_NOTATION: 24595 ret = xmlSchemaValidateNotation( 24596 (xmlSchemaValidCtxtPtr) actxt, 24597 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24598 NULL, value, &val, valNeeded); 24599 break; 24600 case XML_SCHEMAS_QNAME: 24601 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24602 value, &val, valNeeded); 24603 break; 24604 default: 24605 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24606 if (valNeeded) 24607 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24608 value, &val, node); 24609 else 24610 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24611 value, NULL, node); 24612 break; 24613 } 24614 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24615 switch (biType->builtInType) { 24616 case XML_SCHEMAS_NOTATION: 24617 ret = xmlSchemaValidateNotation(NULL, 24618 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24619 value, &val, valNeeded); 24620 break; 24621 default: 24622 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24623 if (valNeeded) 24624 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24625 value, &val, node); 24626 else 24627 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24628 value, NULL, node); 24629 break; 24630 } 24631 } else { 24632 /* 24633 * Validation via a public API is not implemented yet. 24634 */ 24635 TODO 24636 goto internal_error; 24637 } 24638 if (ret != 0) { 24639 if (ret < 0) { 24640 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24641 "validating against a built-in type"); 24642 goto internal_error; 24643 } 24644 if (WXS_IS_LIST(type)) 24645 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24646 else 24647 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24648 } 24649 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24650 /* 24651 * Check facets. 24652 */ 24653 ret = xmlSchemaValidateFacets(actxt, node, type, 24654 (xmlSchemaValType) biType->builtInType, value, val, 24655 0, fireErrors); 24656 if (ret != 0) { 24657 if (ret < 0) { 24658 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24659 "validating facets of atomic simple type"); 24660 goto internal_error; 24661 } 24662 if (WXS_IS_LIST(type)) 24663 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24664 else 24665 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24666 } 24667 } 24668 if (fireErrors && (ret > 0)) 24669 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24670 } else if (WXS_IS_LIST(type)) { 24671 24672 xmlSchemaTypePtr itemType; 24673 const xmlChar *cur, *end; 24674 xmlChar *tmpValue = NULL; 24675 unsigned long len = 0; 24676 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24677 /* 1.2.2 if {variety} is `list` then the string must be a sequence 24678 * of white space separated tokens, each of which `match`es a literal 24679 * in the `lexical space` of {item type definition} 24680 */ 24681 /* 24682 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24683 * the list type has an enum or pattern facet. 24684 */ 24685 NORMALIZE(type); 24686 /* 24687 * VAL TODO: Optimize validation of empty values. 24688 * VAL TODO: We do not have computed values for lists. 24689 */ 24690 itemType = WXS_LIST_ITEMTYPE(type); 24691 cur = value; 24692 do { 24693 while (IS_BLANK_CH(*cur)) 24694 cur++; 24695 end = cur; 24696 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24697 end++; 24698 if (end == cur) 24699 break; 24700 tmpValue = xmlStrndup(cur, end - cur); 24701 len++; 24702 24703 if (valNeeded) 24704 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24705 tmpValue, &curVal, fireErrors, 0, 1); 24706 else 24707 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24708 tmpValue, NULL, fireErrors, 0, 1); 24709 FREE_AND_NULL(tmpValue); 24710 if (curVal != NULL) { 24711 /* 24712 * Add to list of computed values. 24713 */ 24714 if (val == NULL) 24715 val = curVal; 24716 else 24717 xmlSchemaValueAppend(prevVal, curVal); 24718 prevVal = curVal; 24719 curVal = NULL; 24720 } 24721 if (ret != 0) { 24722 if (ret < 0) { 24723 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24724 "validating an item of list simple type"); 24725 goto internal_error; 24726 } 24727 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24728 break; 24729 } 24730 cur = end; 24731 } while (*cur != 0); 24732 FREE_AND_NULL(tmpValue); 24733 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24734 /* 24735 * Apply facets (pattern, enumeration). 24736 */ 24737 ret = xmlSchemaValidateFacets(actxt, node, type, 24738 XML_SCHEMAS_UNKNOWN, value, val, 24739 len, fireErrors); 24740 if (ret != 0) { 24741 if (ret < 0) { 24742 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24743 "validating facets of list simple type"); 24744 goto internal_error; 24745 } 24746 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24747 } 24748 } 24749 if (fireErrors && (ret > 0)) { 24750 /* 24751 * Report the normalized value. 24752 */ 24753 normalize = 1; 24754 NORMALIZE(type); 24755 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24756 } 24757 } else if (WXS_IS_UNION(type)) { 24758 xmlSchemaTypeLinkPtr memberLink; 24759 /* 24760 * TODO: For all datatypes `derived` by `union` whiteSpace does 24761 * not apply directly; however, the normalization behavior of `union` 24762 * types is controlled by the value of whiteSpace on that one of the 24763 * `memberTypes` against which the `union` is successfully validated. 24764 * 24765 * This means that the value is normalized by the first validating 24766 * member type, then the facets of the union type are applied. This 24767 * needs changing of the value! 24768 */ 24769 24770 /* 24771 * 1.2.3 if {variety} is `union` then the string must `match` a 24772 * literal in the `lexical space` of at least one member of 24773 * {member type definitions} 24774 */ 24775 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24776 if (memberLink == NULL) { 24777 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24778 "union simple type has no member types"); 24779 goto internal_error; 24780 } 24781 /* 24782 * Always normalize union type values, since we currently 24783 * cannot store the whitespace information with the value 24784 * itself; otherwise a later value-comparison would be 24785 * not possible. 24786 */ 24787 while (memberLink != NULL) { 24788 if (valNeeded) 24789 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24790 memberLink->type, value, &val, 0, 1, 0); 24791 else 24792 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24793 memberLink->type, value, NULL, 0, 1, 0); 24794 if (ret <= 0) 24795 break; 24796 memberLink = memberLink->next; 24797 } 24798 if (ret != 0) { 24799 if (ret < 0) { 24800 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24801 "validating members of union simple type"); 24802 goto internal_error; 24803 } 24804 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24805 } 24806 /* 24807 * Apply facets (pattern, enumeration). 24808 */ 24809 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24810 /* 24811 * The normalization behavior of `union` types is controlled by 24812 * the value of whiteSpace on that one of the `memberTypes` 24813 * against which the `union` is successfully validated. 24814 */ 24815 NORMALIZE(memberLink->type); 24816 ret = xmlSchemaValidateFacets(actxt, node, type, 24817 XML_SCHEMAS_UNKNOWN, value, val, 24818 0, fireErrors); 24819 if (ret != 0) { 24820 if (ret < 0) { 24821 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24822 "validating facets of union simple type"); 24823 goto internal_error; 24824 } 24825 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24826 } 24827 } 24828 if (fireErrors && (ret > 0)) 24829 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24830 } 24831 24832 if (normValue != NULL) 24833 xmlFree(normValue); 24834 if (ret == 0) { 24835 if (retVal != NULL) 24836 *retVal = val; 24837 else if (val != NULL) 24838 xmlSchemaFreeValue(val); 24839 } else if (val != NULL) 24840 xmlSchemaFreeValue(val); 24841 return (ret); 24842 internal_error: 24843 if (normValue != NULL) 24844 xmlFree(normValue); 24845 if (val != NULL) 24846 xmlSchemaFreeValue(val); 24847 return (-1); 24848 } 24849 24850 static int 24851 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24852 const xmlChar *value, 24853 const xmlChar **nsName, 24854 const xmlChar **localName) 24855 { 24856 int ret = 0; 24857 24858 if ((nsName == NULL) || (localName == NULL)) 24859 return (-1); 24860 *nsName = NULL; 24861 *localName = NULL; 24862 24863 ret = xmlValidateQName(value, 1); 24864 if (ret == -1) 24865 return (-1); 24866 if (ret > 0) { 24867 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24868 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24869 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24870 return (1); 24871 } 24872 { 24873 xmlChar *local = NULL; 24874 xmlChar *prefix; 24875 24876 /* 24877 * NOTE: xmlSplitQName2 will return a duplicated 24878 * string. 24879 */ 24880 local = xmlSplitQName2(value, &prefix); 24881 if (local == NULL) 24882 *localName = xmlDictLookup(vctxt->dict, value, -1); 24883 else { 24884 *localName = xmlDictLookup(vctxt->dict, local, -1); 24885 xmlFree(local); 24886 } 24887 24888 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24889 24890 if (prefix != NULL) { 24891 xmlFree(prefix); 24892 /* 24893 * A namespace must be found if the prefix is NOT NULL. 24894 */ 24895 if (*nsName == NULL) { 24896 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24897 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24898 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24899 "The QName value '%s' has no " 24900 "corresponding namespace declaration in scope", 24901 value, NULL); 24902 return (2); 24903 } 24904 } 24905 } 24906 return (0); 24907 } 24908 24909 static int 24910 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24911 xmlSchemaAttrInfoPtr iattr, 24912 xmlSchemaTypePtr *localType, 24913 xmlSchemaElementPtr elemDecl) 24914 { 24915 int ret = 0; 24916 /* 24917 * cvc-elt (3.3.4) : (4) 24918 * AND 24919 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24920 * (1.2.1.2.1) - (1.2.1.2.4) 24921 * Handle 'xsi:type'. 24922 */ 24923 if (localType == NULL) 24924 return (-1); 24925 *localType = NULL; 24926 if (iattr == NULL) 24927 return (0); 24928 else { 24929 const xmlChar *nsName = NULL, *local = NULL; 24930 /* 24931 * TODO: We should report a *warning* that the type was overriden 24932 * by the instance. 24933 */ 24934 ACTIVATE_ATTRIBUTE(iattr); 24935 /* 24936 * (cvc-elt) (3.3.4) : (4.1) 24937 * (cvc-assess-elt) (1.2.1.2.2) 24938 */ 24939 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24940 &nsName, &local); 24941 if (ret != 0) { 24942 if (ret < 0) { 24943 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24944 "calling xmlSchemaQNameExpand() to validate the " 24945 "attribute 'xsi:type'"); 24946 goto internal_error; 24947 } 24948 goto exit; 24949 } 24950 /* 24951 * (cvc-elt) (3.3.4) : (4.2) 24952 * (cvc-assess-elt) (1.2.1.2.3) 24953 */ 24954 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24955 if (*localType == NULL) { 24956 xmlChar *str = NULL; 24957 24958 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24959 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24960 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24961 "The QName value '%s' of the xsi:type attribute does not " 24962 "resolve to a type definition", 24963 xmlSchemaFormatQName(&str, nsName, local), NULL); 24964 FREE_AND_NULL(str); 24965 ret = vctxt->err; 24966 goto exit; 24967 } 24968 if (elemDecl != NULL) { 24969 int set = 0; 24970 24971 /* 24972 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24973 * "The `local type definition` must be validly 24974 * derived from the {type definition} given the union of 24975 * the {disallowed substitutions} and the {type definition}'s 24976 * {prohibited substitutions}, as defined in 24977 * Type Derivation OK (Complex) ($3.4.6) 24978 * (if it is a complex type definition), 24979 * or given {disallowed substitutions} as defined in Type 24980 * Derivation OK (Simple) ($3.14.6) (if it is a simple type 24981 * definition)." 24982 * 24983 * {disallowed substitutions}: the "block" on the element decl. 24984 * {prohibited substitutions}: the "block" on the type def. 24985 */ 24986 /* 24987 * OPTIMIZE TODO: We could map types already evaluated 24988 * to be validly derived from other types to avoid checking 24989 * this over and over for the same types. 24990 */ 24991 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24992 (elemDecl->subtypes->flags & 24993 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24994 set |= SUBSET_EXTENSION; 24995 24996 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24997 (elemDecl->subtypes->flags & 24998 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24999 set |= SUBSET_RESTRICTION; 25000 25001 /* 25002 * REMOVED and CHANGED since this produced a parser context 25003 * which adds to the string dict of the schema. So this would 25004 * change the schema and we don't want this. We don't need 25005 * the parser context anymore. 25006 * 25007 * if ((vctxt->pctxt == NULL) && 25008 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 25009 * return (-1); 25010 */ 25011 25012 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 25013 elemDecl->subtypes, set) != 0) { 25014 xmlChar *str = NULL; 25015 25016 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25017 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 25018 "The type definition '%s', specified by xsi:type, is " 25019 "blocked or not validly derived from the type definition " 25020 "of the element declaration", 25021 xmlSchemaFormatQName(&str, 25022 (*localType)->targetNamespace, 25023 (*localType)->name), 25024 NULL); 25025 FREE_AND_NULL(str); 25026 ret = vctxt->err; 25027 *localType = NULL; 25028 } 25029 } 25030 } 25031 exit: 25032 ACTIVATE_ELEM; 25033 return (ret); 25034 internal_error: 25035 ACTIVATE_ELEM; 25036 return (-1); 25037 } 25038 25039 static int 25040 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 25041 { 25042 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 25043 xmlSchemaTypePtr actualType; 25044 25045 /* 25046 * cvc-elt (3.3.4) : 1 25047 */ 25048 if (elemDecl == NULL) { 25049 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 25050 "No matching declaration available"); 25051 return (vctxt->err); 25052 } 25053 actualType = WXS_ELEM_TYPEDEF(elemDecl); 25054 /* 25055 * cvc-elt (3.3.4) : 2 25056 */ 25057 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 25058 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 25059 "The element declaration is abstract"); 25060 return (vctxt->err); 25061 } 25062 if (actualType == NULL) { 25063 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25064 "The type definition is absent"); 25065 return (XML_SCHEMAV_CVC_TYPE_1); 25066 } 25067 if (vctxt->nbAttrInfos != 0) { 25068 int ret; 25069 xmlSchemaAttrInfoPtr iattr; 25070 /* 25071 * cvc-elt (3.3.4) : 3 25072 * Handle 'xsi:nil'. 25073 */ 25074 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25075 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25076 if (iattr) { 25077 ACTIVATE_ATTRIBUTE(iattr); 25078 /* 25079 * Validate the value. 25080 */ 25081 ret = xmlSchemaVCheckCVCSimpleType( 25082 ACTXT_CAST vctxt, NULL, 25083 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25084 iattr->value, &(iattr->val), 1, 0, 0); 25085 ACTIVATE_ELEM; 25086 if (ret < 0) { 25087 VERROR_INT("xmlSchemaValidateElemDecl", 25088 "calling xmlSchemaVCheckCVCSimpleType() to " 25089 "validate the attribute 'xsi:nil'"); 25090 return (-1); 25091 } 25092 if (ret == 0) { 25093 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25094 /* 25095 * cvc-elt (3.3.4) : 3.1 25096 */ 25097 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25098 "The element is not 'nillable'"); 25099 /* Does not return an error on purpose. */ 25100 } else { 25101 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25102 /* 25103 * cvc-elt (3.3.4) : 3.2.2 25104 */ 25105 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25106 (elemDecl->value != NULL)) { 25107 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25108 "The element cannot be 'nilled' because " 25109 "there is a fixed value constraint defined " 25110 "for it"); 25111 /* Does not return an error on purpose. */ 25112 } else 25113 vctxt->inode->flags |= 25114 XML_SCHEMA_ELEM_INFO_NILLED; 25115 } 25116 } 25117 } 25118 } 25119 /* 25120 * cvc-elt (3.3.4) : 4 25121 * Handle 'xsi:type'. 25122 */ 25123 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25124 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25125 if (iattr) { 25126 xmlSchemaTypePtr localType = NULL; 25127 25128 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25129 elemDecl); 25130 if (ret != 0) { 25131 if (ret == -1) { 25132 VERROR_INT("xmlSchemaValidateElemDecl", 25133 "calling xmlSchemaProcessXSIType() to " 25134 "process the attribute 'xsi:type'"); 25135 return (-1); 25136 } 25137 /* Does not return an error on purpose. */ 25138 } 25139 if (localType != NULL) { 25140 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25141 actualType = localType; 25142 } 25143 } 25144 } 25145 /* 25146 * IDC: Register identity-constraint XPath matchers. 25147 */ 25148 if ((elemDecl->idcs != NULL) && 25149 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25150 return (-1); 25151 /* 25152 * No actual type definition. 25153 */ 25154 if (actualType == NULL) { 25155 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25156 "The type definition is absent"); 25157 return (XML_SCHEMAV_CVC_TYPE_1); 25158 } 25159 /* 25160 * Remember the actual type definition. 25161 */ 25162 vctxt->inode->typeDef = actualType; 25163 25164 return (0); 25165 } 25166 25167 static int 25168 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25169 { 25170 xmlSchemaAttrInfoPtr iattr; 25171 int ret = 0, i; 25172 25173 /* 25174 * SPEC cvc-type (3.1.1) 25175 * "The attributes of must be empty, excepting those whose namespace 25176 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25177 * whose local name is one of type, nil, schemaLocation or 25178 * noNamespaceSchemaLocation." 25179 */ 25180 if (vctxt->nbAttrInfos == 0) 25181 return (0); 25182 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25183 iattr = vctxt->attrInfos[i]; 25184 if (! iattr->metaType) { 25185 ACTIVATE_ATTRIBUTE(iattr) 25186 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25187 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25188 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25189 } 25190 } 25191 ACTIVATE_ELEM 25192 return (ret); 25193 } 25194 25195 /* 25196 * Cleanup currently used attribute infos. 25197 */ 25198 static void 25199 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25200 { 25201 int i; 25202 xmlSchemaAttrInfoPtr attr; 25203 25204 if (vctxt->nbAttrInfos == 0) 25205 return; 25206 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25207 attr = vctxt->attrInfos[i]; 25208 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25209 if (attr->localName != NULL) 25210 xmlFree((xmlChar *) attr->localName); 25211 if (attr->nsName != NULL) 25212 xmlFree((xmlChar *) attr->nsName); 25213 } 25214 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25215 if (attr->value != NULL) 25216 xmlFree((xmlChar *) attr->value); 25217 } 25218 if (attr->val != NULL) { 25219 xmlSchemaFreeValue(attr->val); 25220 attr->val = NULL; 25221 } 25222 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25223 } 25224 vctxt->nbAttrInfos = 0; 25225 } 25226 25227 /* 25228 * 3.4.4 Complex Type Definition Validation Rules 25229 * Element Locally Valid (Complex Type) (cvc-complex-type) 25230 * 3.2.4 Attribute Declaration Validation Rules 25231 * Validation Rule: Attribute Locally Valid (cvc-attribute) 25232 * Attribute Locally Valid (Use) (cvc-au) 25233 * 25234 * Only "assessed" attribute information items will be visible to 25235 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25236 */ 25237 static int 25238 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25239 { 25240 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25241 xmlSchemaItemListPtr attrUseList; 25242 xmlSchemaAttributeUsePtr attrUse = NULL; 25243 xmlSchemaAttributePtr attrDecl = NULL; 25244 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25245 int i, j, found, nbAttrs, nbUses; 25246 int xpathRes = 0, res, wildIDs = 0, fixed; 25247 xmlNodePtr defAttrOwnerElem = NULL; 25248 25249 /* 25250 * SPEC (cvc-attribute) 25251 * (1) "The declaration must not be `absent` (see Missing 25252 * Sub-components ($5.3) for how this can fail to be 25253 * the case)." 25254 * (2) "Its {type definition} must not be absent." 25255 * 25256 * NOTE (1) + (2): This is not handled here, since we currently do not 25257 * allow validation against schemas which have missing sub-components. 25258 * 25259 * SPEC (cvc-complex-type) 25260 * (3) "For each attribute information item in the element information 25261 * item's [attributes] excepting those whose [namespace name] is 25262 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25263 * [local name] is one of type, nil, schemaLocation or 25264 * noNamespaceSchemaLocation, the appropriate case among the following 25265 * must be true: 25266 * 25267 */ 25268 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25269 /* 25270 * @nbAttrs is the number of attributes present in the instance. 25271 */ 25272 nbAttrs = vctxt->nbAttrInfos; 25273 if (attrUseList != NULL) 25274 nbUses = attrUseList->nbItems; 25275 else 25276 nbUses = 0; 25277 for (i = 0; i < nbUses; i++) { 25278 found = 0; 25279 attrUse = attrUseList->items[i]; 25280 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25281 for (j = 0; j < nbAttrs; j++) { 25282 iattr = vctxt->attrInfos[j]; 25283 /* 25284 * SPEC (cvc-complex-type) (3) 25285 * Skip meta attributes. 25286 */ 25287 if (iattr->metaType) 25288 continue; 25289 if (iattr->localName[0] != attrDecl->name[0]) 25290 continue; 25291 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25292 continue; 25293 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25294 continue; 25295 found = 1; 25296 /* 25297 * SPEC (cvc-complex-type) 25298 * (3.1) "If there is among the {attribute uses} an attribute 25299 * use with an {attribute declaration} whose {name} matches 25300 * the attribute information item's [local name] and whose 25301 * {target namespace} is identical to the attribute information 25302 * item's [namespace name] (where an `absent` {target namespace} 25303 * is taken to be identical to a [namespace name] with no value), 25304 * then the attribute information must be `valid` with respect 25305 * to that attribute use as per Attribute Locally Valid (Use) 25306 * ($3.5.4). In this case the {attribute declaration} of that 25307 * attribute use is the `context-determined declaration` for the 25308 * attribute information item with respect to Schema-Validity 25309 * Assessment (Attribute) ($3.2.4) and 25310 * Assessment Outcome (Attribute) ($3.2.5). 25311 */ 25312 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25313 iattr->use = attrUse; 25314 /* 25315 * Context-determined declaration. 25316 */ 25317 iattr->decl = attrDecl; 25318 iattr->typeDef = attrDecl->subtypes; 25319 break; 25320 } 25321 25322 if (found) 25323 continue; 25324 25325 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25326 /* 25327 * Handle non-existent, required attributes. 25328 * 25329 * SPEC (cvc-complex-type) 25330 * (4) "The {attribute declaration} of each attribute use in 25331 * the {attribute uses} whose {required} is true matches one 25332 * of the attribute information items in the element information 25333 * item's [attributes] as per clause 3.1 above." 25334 */ 25335 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25336 if (tmpiattr == NULL) { 25337 VERROR_INT( 25338 "xmlSchemaVAttributesComplex", 25339 "calling xmlSchemaGetFreshAttrInfo()"); 25340 return (-1); 25341 } 25342 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25343 tmpiattr->use = attrUse; 25344 tmpiattr->decl = attrDecl; 25345 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25346 ((attrUse->defValue != NULL) || 25347 (attrDecl->defValue != NULL))) { 25348 /* 25349 * Handle non-existent, optional, default/fixed attributes. 25350 */ 25351 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25352 if (tmpiattr == NULL) { 25353 VERROR_INT( 25354 "xmlSchemaVAttributesComplex", 25355 "calling xmlSchemaGetFreshAttrInfo()"); 25356 return (-1); 25357 } 25358 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25359 tmpiattr->use = attrUse; 25360 tmpiattr->decl = attrDecl; 25361 tmpiattr->typeDef = attrDecl->subtypes; 25362 tmpiattr->localName = attrDecl->name; 25363 tmpiattr->nsName = attrDecl->targetNamespace; 25364 } 25365 } 25366 25367 if (vctxt->nbAttrInfos == 0) 25368 return (0); 25369 /* 25370 * Validate against the wildcard. 25371 */ 25372 if (type->attributeWildcard != NULL) { 25373 /* 25374 * SPEC (cvc-complex-type) 25375 * (3.2.1) "There must be an {attribute wildcard}." 25376 */ 25377 for (i = 0; i < nbAttrs; i++) { 25378 iattr = vctxt->attrInfos[i]; 25379 /* 25380 * SPEC (cvc-complex-type) (3) 25381 * Skip meta attributes. 25382 */ 25383 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25384 continue; 25385 /* 25386 * SPEC (cvc-complex-type) 25387 * (3.2.2) "The attribute information item must be `valid` with 25388 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)." 25389 * 25390 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25391 * "... its [namespace name] must be `valid` with respect to 25392 * the wildcard constraint, as defined in Wildcard allows 25393 * Namespace Name ($3.10.4)." 25394 */ 25395 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25396 iattr->nsName) == 0) { 25397 /* 25398 * Handle processContents. 25399 * 25400 * SPEC (cvc-wildcard): 25401 * processContents | context-determined declaration: 25402 * "strict" "mustFind" 25403 * "lax" "none" 25404 * "skip" "skip" 25405 */ 25406 if (type->attributeWildcard->processContents == 25407 XML_SCHEMAS_ANY_SKIP) { 25408 /* 25409 * context-determined declaration = "skip" 25410 * 25411 * SPEC PSVI Assessment Outcome (Attribute) 25412 * [validity] = "notKnown" 25413 * [validation attempted] = "none" 25414 */ 25415 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25416 continue; 25417 } 25418 /* 25419 * Find an attribute declaration. 25420 */ 25421 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25422 iattr->localName, iattr->nsName); 25423 if (iattr->decl != NULL) { 25424 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25425 /* 25426 * SPEC (cvc-complex-type) 25427 * (5) "Let [Definition:] the wild IDs be the set of 25428 * all attribute information item to which clause 3.2 25429 * applied and whose `validation` resulted in a 25430 * `context-determined declaration` of mustFind or no 25431 * `context-determined declaration` at all, and whose 25432 * [local name] and [namespace name] resolve (as 25433 * defined by QName resolution (Instance) ($3.15.4)) to 25434 * an attribute declaration whose {type definition} is 25435 * or is derived from ID. Then all of the following 25436 * must be true:" 25437 */ 25438 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25439 if (xmlSchemaIsDerivedFromBuiltInType( 25440 iattr->typeDef, XML_SCHEMAS_ID)) { 25441 /* 25442 * SPEC (5.1) "There must be no more than one 25443 * item in `wild IDs`." 25444 */ 25445 if (wildIDs != 0) { 25446 /* VAL TODO */ 25447 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25448 TODO 25449 continue; 25450 } 25451 wildIDs++; 25452 /* 25453 * SPEC (cvc-complex-type) 25454 * (5.2) "If `wild IDs` is non-empty, there must not 25455 * be any attribute uses among the {attribute uses} 25456 * whose {attribute declaration}'s {type definition} 25457 * is or is derived from ID." 25458 */ 25459 if (attrUseList != NULL) { 25460 for (j = 0; j < attrUseList->nbItems; j++) { 25461 if (xmlSchemaIsDerivedFromBuiltInType( 25462 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25463 XML_SCHEMAS_ID)) { 25464 /* URGENT VAL TODO: implement */ 25465 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25466 TODO 25467 break; 25468 } 25469 } 25470 } 25471 } 25472 } else if (type->attributeWildcard->processContents == 25473 XML_SCHEMAS_ANY_LAX) { 25474 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25475 /* 25476 * SPEC PSVI Assessment Outcome (Attribute) 25477 * [validity] = "notKnown" 25478 * [validation attempted] = "none" 25479 */ 25480 } else { 25481 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25482 } 25483 } 25484 } 25485 } 25486 25487 if (vctxt->nbAttrInfos == 0) 25488 return (0); 25489 25490 /* 25491 * Get the owner element; needed for creation of default attributes. 25492 * This fixes bug #341337, reported by David Grohmann. 25493 */ 25494 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25495 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25496 if (ielem && ielem->node && ielem->node->doc) 25497 defAttrOwnerElem = ielem->node; 25498 } 25499 /* 25500 * Validate values, create default attributes, evaluate IDCs. 25501 */ 25502 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25503 iattr = vctxt->attrInfos[i]; 25504 /* 25505 * VAL TODO: Note that we won't try to resolve IDCs to 25506 * "lax" and "skip" validated attributes. Check what to 25507 * do in this case. 25508 */ 25509 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25510 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25511 continue; 25512 /* 25513 * VAL TODO: What to do if the type definition is missing? 25514 */ 25515 if (iattr->typeDef == NULL) { 25516 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25517 continue; 25518 } 25519 25520 ACTIVATE_ATTRIBUTE(iattr); 25521 fixed = 0; 25522 xpathRes = 0; 25523 25524 if (vctxt->xpathStates != NULL) { 25525 /* 25526 * Evaluate IDCs. 25527 */ 25528 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25529 XML_ATTRIBUTE_NODE); 25530 if (xpathRes == -1) { 25531 VERROR_INT("xmlSchemaVAttributesComplex", 25532 "calling xmlSchemaXPathEvaluate()"); 25533 goto internal_error; 25534 } 25535 } 25536 25537 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25538 /* 25539 * Default/fixed attributes. 25540 * We need the value only if we need to resolve IDCs or 25541 * will create default attributes. 25542 */ 25543 if ((xpathRes) || (defAttrOwnerElem)) { 25544 if (iattr->use->defValue != NULL) { 25545 iattr->value = (xmlChar *) iattr->use->defValue; 25546 iattr->val = iattr->use->defVal; 25547 } else { 25548 iattr->value = (xmlChar *) iattr->decl->defValue; 25549 iattr->val = iattr->decl->defVal; 25550 } 25551 /* 25552 * IDCs will consume the precomputed default value, 25553 * so we need to clone it. 25554 */ 25555 if (iattr->val == NULL) { 25556 VERROR_INT("xmlSchemaVAttributesComplex", 25557 "default/fixed value on an attribute use was " 25558 "not precomputed"); 25559 goto internal_error; 25560 } 25561 iattr->val = xmlSchemaCopyValue(iattr->val); 25562 if (iattr->val == NULL) { 25563 VERROR_INT("xmlSchemaVAttributesComplex", 25564 "calling xmlSchemaCopyValue()"); 25565 goto internal_error; 25566 } 25567 } 25568 /* 25569 * PSVI: Add the default attribute to the current element. 25570 * VAL TODO: Should we use the *normalized* value? This currently 25571 * uses the *initial* value. 25572 */ 25573 25574 if (defAttrOwnerElem) { 25575 xmlChar *normValue; 25576 const xmlChar *value; 25577 25578 value = iattr->value; 25579 /* 25580 * Normalize the value. 25581 */ 25582 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25583 iattr->value); 25584 if (normValue != NULL) 25585 value = BAD_CAST normValue; 25586 25587 if (iattr->nsName == NULL) { 25588 if (xmlNewProp(defAttrOwnerElem, 25589 iattr->localName, value) == NULL) { 25590 VERROR_INT("xmlSchemaVAttributesComplex", 25591 "calling xmlNewProp()"); 25592 if (normValue != NULL) 25593 xmlFree(normValue); 25594 goto internal_error; 25595 } 25596 } else { 25597 xmlNsPtr ns; 25598 25599 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25600 defAttrOwnerElem, iattr->nsName); 25601 if (ns == NULL) { 25602 xmlChar prefix[12]; 25603 int counter = 0; 25604 25605 /* 25606 * Create a namespace declaration on the validation 25607 * root node if no namespace declaration is in scope. 25608 */ 25609 do { 25610 snprintf((char *) prefix, 12, "p%d", counter++); 25611 ns = xmlSearchNs(defAttrOwnerElem->doc, 25612 defAttrOwnerElem, BAD_CAST prefix); 25613 if (counter > 1000) { 25614 VERROR_INT( 25615 "xmlSchemaVAttributesComplex", 25616 "could not compute a ns prefix for a " 25617 "default/fixed attribute"); 25618 if (normValue != NULL) 25619 xmlFree(normValue); 25620 goto internal_error; 25621 } 25622 } while (ns != NULL); 25623 ns = xmlNewNs(vctxt->validationRoot, 25624 iattr->nsName, BAD_CAST prefix); 25625 } 25626 /* 25627 * TODO: 25628 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25629 * If we have QNames: do we need to ensure there's a 25630 * prefix defined for the QName? 25631 */ 25632 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25633 } 25634 if (normValue != NULL) 25635 xmlFree(normValue); 25636 } 25637 /* 25638 * Go directly to IDC evaluation. 25639 */ 25640 goto eval_idcs; 25641 } 25642 /* 25643 * Validate the value. 25644 */ 25645 if (vctxt->value != NULL) { 25646 /* 25647 * Free last computed value; just for safety reasons. 25648 */ 25649 xmlSchemaFreeValue(vctxt->value); 25650 vctxt->value = NULL; 25651 } 25652 /* 25653 * Note that the attribute *use* can be unavailable, if 25654 * the attribute was a wild attribute. 25655 */ 25656 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25657 ((iattr->use != NULL) && 25658 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25659 fixed = 1; 25660 else 25661 fixed = 0; 25662 /* 25663 * SPEC (cvc-attribute) 25664 * (3) "The item's `normalized value` must be locally `valid` 25665 * with respect to that {type definition} as per 25666 * String Valid ($3.14.4)." 25667 * 25668 * VAL TODO: Do we already have the 25669 * "normalized attribute value" here? 25670 */ 25671 if (xpathRes || fixed) { 25672 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25673 /* 25674 * Request a computed value. 25675 */ 25676 res = xmlSchemaVCheckCVCSimpleType( 25677 ACTXT_CAST vctxt, 25678 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25679 1, 1, 0); 25680 } else { 25681 res = xmlSchemaVCheckCVCSimpleType( 25682 ACTXT_CAST vctxt, 25683 iattr->node, iattr->typeDef, iattr->value, NULL, 25684 1, 0, 0); 25685 } 25686 25687 if (res != 0) { 25688 if (res == -1) { 25689 VERROR_INT("xmlSchemaVAttributesComplex", 25690 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25691 goto internal_error; 25692 } 25693 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25694 /* 25695 * SPEC PSVI Assessment Outcome (Attribute) 25696 * [validity] = "invalid" 25697 */ 25698 goto eval_idcs; 25699 } 25700 25701 if (fixed) { 25702 /* 25703 * SPEC Attribute Locally Valid (Use) (cvc-au) 25704 * "For an attribute information item to be `valid` 25705 * with respect to an attribute use its *normalized* 25706 * value must match the *canonical* lexical 25707 * representation of the attribute use's {value 25708 * constraint}value, if it is present and fixed." 25709 * 25710 * VAL TODO: The requirement for the *canonical* value 25711 * will be removed in XML Schema 1.1. 25712 */ 25713 /* 25714 * SPEC Attribute Locally Valid (cvc-attribute) 25715 * (4) "The item's *actual* value must match the *value* of 25716 * the {value constraint}, if it is present and fixed." 25717 */ 25718 if (iattr->val == NULL) { 25719 /* VAL TODO: A value was not precomputed. */ 25720 TODO 25721 goto eval_idcs; 25722 } 25723 if ((iattr->use != NULL) && 25724 (iattr->use->defValue != NULL)) { 25725 if (iattr->use->defVal == NULL) { 25726 /* VAL TODO: A default value was not precomputed. */ 25727 TODO 25728 goto eval_idcs; 25729 } 25730 iattr->vcValue = iattr->use->defValue; 25731 /* 25732 if (xmlSchemaCompareValuesWhtsp(attr->val, 25733 (xmlSchemaWhitespaceValueType) ws, 25734 attr->use->defVal, 25735 (xmlSchemaWhitespaceValueType) ws) != 0) { 25736 */ 25737 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25738 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25739 } else { 25740 if (iattr->decl->defVal == NULL) { 25741 /* VAL TODO: A default value was not precomputed. */ 25742 TODO 25743 goto eval_idcs; 25744 } 25745 iattr->vcValue = iattr->decl->defValue; 25746 /* 25747 if (xmlSchemaCompareValuesWhtsp(attr->val, 25748 (xmlSchemaWhitespaceValueType) ws, 25749 attrDecl->defVal, 25750 (xmlSchemaWhitespaceValueType) ws) != 0) { 25751 */ 25752 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25753 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25754 } 25755 /* 25756 * [validity] = "valid" 25757 */ 25758 } 25759 eval_idcs: 25760 /* 25761 * Evaluate IDCs. 25762 */ 25763 if (xpathRes) { 25764 if (xmlSchemaXPathProcessHistory(vctxt, 25765 vctxt->depth +1) == -1) { 25766 VERROR_INT("xmlSchemaVAttributesComplex", 25767 "calling xmlSchemaXPathEvaluate()"); 25768 goto internal_error; 25769 } 25770 } else if (vctxt->xpathStates != NULL) 25771 xmlSchemaXPathPop(vctxt); 25772 } 25773 25774 /* 25775 * Report errors. 25776 */ 25777 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25778 iattr = vctxt->attrInfos[i]; 25779 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25780 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25781 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25782 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25783 continue; 25784 ACTIVATE_ATTRIBUTE(iattr); 25785 switch (iattr->state) { 25786 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25787 xmlChar *str = NULL; 25788 ACTIVATE_ELEM; 25789 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25790 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25791 "The attribute '%s' is required but missing", 25792 xmlSchemaFormatQName(&str, 25793 iattr->decl->targetNamespace, 25794 iattr->decl->name), 25795 NULL); 25796 FREE_AND_NULL(str) 25797 break; 25798 } 25799 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25800 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25801 "The type definition is absent"); 25802 break; 25803 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25804 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25805 XML_SCHEMAV_CVC_AU, NULL, NULL, 25806 "The value '%s' does not match the fixed " 25807 "value constraint '%s'", 25808 iattr->value, iattr->vcValue); 25809 break; 25810 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25811 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25812 "No matching global attribute declaration available, but " 25813 "demanded by the strict wildcard"); 25814 break; 25815 case XML_SCHEMAS_ATTR_UNKNOWN: 25816 if (iattr->metaType) 25817 break; 25818 /* 25819 * MAYBE VAL TODO: One might report different error messages 25820 * for the following errors. 25821 */ 25822 if (type->attributeWildcard == NULL) { 25823 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25824 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25825 } else { 25826 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25827 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25828 } 25829 break; 25830 default: 25831 break; 25832 } 25833 } 25834 25835 ACTIVATE_ELEM; 25836 return (0); 25837 internal_error: 25838 ACTIVATE_ELEM; 25839 return (-1); 25840 } 25841 25842 static int 25843 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25844 int *skip) 25845 { 25846 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25847 /* 25848 * The namespace of the element was already identified to be 25849 * matching the wildcard. 25850 */ 25851 if ((skip == NULL) || (wild == NULL) || 25852 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25853 VERROR_INT("xmlSchemaValidateElemWildcard", 25854 "bad arguments"); 25855 return (-1); 25856 } 25857 *skip = 0; 25858 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25859 /* 25860 * URGENT VAL TODO: Either we need to position the stream to the 25861 * next sibling, or walk the whole subtree. 25862 */ 25863 *skip = 1; 25864 return (0); 25865 } 25866 { 25867 xmlSchemaElementPtr decl = NULL; 25868 25869 decl = xmlSchemaGetElem(vctxt->schema, 25870 vctxt->inode->localName, vctxt->inode->nsName); 25871 if (decl != NULL) { 25872 vctxt->inode->decl = decl; 25873 return (0); 25874 } 25875 } 25876 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25877 /* VAL TODO: Change to proper error code. */ 25878 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25879 "No matching global element declaration available, but " 25880 "demanded by the strict wildcard"); 25881 return (vctxt->err); 25882 } 25883 if (vctxt->nbAttrInfos != 0) { 25884 xmlSchemaAttrInfoPtr iattr; 25885 /* 25886 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25887 * (1.2.1.2.1) - (1.2.1.2.3 ) 25888 * 25889 * Use the xsi:type attribute for the type definition. 25890 */ 25891 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25892 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25893 if (iattr != NULL) { 25894 if (xmlSchemaProcessXSIType(vctxt, iattr, 25895 &(vctxt->inode->typeDef), NULL) == -1) { 25896 VERROR_INT("xmlSchemaValidateElemWildcard", 25897 "calling xmlSchemaProcessXSIType() to " 25898 "process the attribute 'xsi:nil'"); 25899 return (-1); 25900 } 25901 /* 25902 * Don't return an error on purpose. 25903 */ 25904 return (0); 25905 } 25906 } 25907 /* 25908 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25909 * 25910 * Fallback to "anyType". 25911 */ 25912 vctxt->inode->typeDef = 25913 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25914 return (0); 25915 } 25916 25917 /* 25918 * xmlSchemaCheckCOSValidDefault: 25919 * 25920 * This will be called if: not nilled, no content and a default/fixed 25921 * value is provided. 25922 */ 25923 25924 static int 25925 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25926 const xmlChar *value, 25927 xmlSchemaValPtr *val) 25928 { 25929 int ret = 0; 25930 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25931 25932 /* 25933 * cos-valid-default: 25934 * Schema Component Constraint: Element Default Valid (Immediate) 25935 * For a string to be a valid default with respect to a type 25936 * definition the appropriate case among the following must be true: 25937 */ 25938 if WXS_IS_COMPLEX(inode->typeDef) { 25939 /* 25940 * Complex type. 25941 * 25942 * SPEC (2.1) "its {content type} must be a simple type definition 25943 * or mixed." 25944 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25945 * type}'s particle must be `emptiable` as defined by 25946 * Particle Emptiable ($3.9.6)." 25947 */ 25948 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25949 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25950 (! WXS_EMPTIABLE(inode->typeDef)))) { 25951 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25952 /* NOTE that this covers (2.2.2) as well. */ 25953 VERROR(ret, NULL, 25954 "For a string to be a valid default, the type definition " 25955 "must be a simple type or a complex type with simple content " 25956 "or mixed content and a particle emptiable"); 25957 return(ret); 25958 } 25959 } 25960 /* 25961 * 1 If the type definition is a simple type definition, then the string 25962 * must be `valid` with respect to that definition as defined by String 25963 * Valid ($3.14.4). 25964 * 25965 * AND 25966 * 25967 * 2.2.1 If the {content type} is a simple type definition, then the 25968 * string must be `valid` with respect to that simple type definition 25969 * as defined by String Valid ($3.14.4). 25970 */ 25971 if (WXS_IS_SIMPLE(inode->typeDef)) { 25972 25973 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25974 NULL, inode->typeDef, value, val, 1, 1, 0); 25975 25976 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25977 25978 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25979 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25980 } 25981 if (ret < 0) { 25982 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25983 "calling xmlSchemaVCheckCVCSimpleType()"); 25984 } 25985 return (ret); 25986 } 25987 25988 static void 25989 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED, 25990 const xmlChar * name ATTRIBUTE_UNUSED, 25991 void *transdata, void *inputdata) 25992 { 25993 xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata; 25994 xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata; 25995 inode->decl = item; 25996 #ifdef DEBUG_CONTENT 25997 { 25998 xmlChar *str = NULL; 25999 26000 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 26001 xmlGenericError(xmlGenericErrorContext, 26002 "AUTOMATON callback for '%s' [declaration]\n", 26003 xmlSchemaFormatQName(&str, 26004 inode->localName, inode->nsName)); 26005 } else { 26006 xmlGenericError(xmlGenericErrorContext, 26007 "AUTOMATON callback for '%s' [wildcard]\n", 26008 xmlSchemaFormatQName(&str, 26009 inode->localName, inode->nsName)); 26010 26011 } 26012 FREE_AND_NULL(str) 26013 } 26014 #endif 26015 } 26016 26017 static int 26018 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 26019 { 26020 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 26021 if (vctxt->inode == NULL) { 26022 VERROR_INT("xmlSchemaValidatorPushElem", 26023 "calling xmlSchemaGetFreshElemInfo()"); 26024 return (-1); 26025 } 26026 vctxt->nbAttrInfos = 0; 26027 return (0); 26028 } 26029 26030 static int 26031 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 26032 xmlSchemaNodeInfoPtr inode, 26033 xmlSchemaTypePtr type, 26034 const xmlChar *value) 26035 { 26036 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 26037 return (xmlSchemaVCheckCVCSimpleType( 26038 ACTXT_CAST vctxt, NULL, 26039 type, value, &(inode->val), 1, 1, 0)); 26040 else 26041 return (xmlSchemaVCheckCVCSimpleType( 26042 ACTXT_CAST vctxt, NULL, 26043 type, value, NULL, 1, 0, 0)); 26044 } 26045 26046 26047 26048 /* 26049 * Process END of element. 26050 */ 26051 static int 26052 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 26053 { 26054 int ret = 0; 26055 xmlSchemaNodeInfoPtr inode = vctxt->inode; 26056 26057 if (vctxt->nbAttrInfos != 0) 26058 xmlSchemaClearAttrInfos(vctxt); 26059 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 26060 /* 26061 * This element was not expected; 26062 * we will not validate child elements of broken parents. 26063 * Skip validation of all content of the parent. 26064 */ 26065 vctxt->skipDepth = vctxt->depth -1; 26066 goto end_elem; 26067 } 26068 if ((inode->typeDef == NULL) || 26069 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 26070 /* 26071 * 1. the type definition might be missing if the element was 26072 * error prone 26073 * 2. it might be abstract. 26074 */ 26075 goto end_elem; 26076 } 26077 /* 26078 * Check the content model. 26079 */ 26080 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26081 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26082 26083 /* 26084 * Workaround for "anyType". 26085 */ 26086 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26087 goto character_content; 26088 26089 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26090 xmlChar *values[10]; 26091 int terminal, nbval = 10, nbneg; 26092 26093 if (inode->regexCtxt == NULL) { 26094 /* 26095 * Create the regex context. 26096 */ 26097 inode->regexCtxt = 26098 xmlRegNewExecCtxt(inode->typeDef->contModel, 26099 xmlSchemaVContentModelCallback, vctxt); 26100 if (inode->regexCtxt == NULL) { 26101 VERROR_INT("xmlSchemaValidatorPopElem", 26102 "failed to create a regex context"); 26103 goto internal_error; 26104 } 26105 #ifdef DEBUG_AUTOMATA 26106 xmlGenericError(xmlGenericErrorContext, 26107 "AUTOMATON create on '%s'\n", inode->localName); 26108 #endif 26109 } 26110 26111 /* 26112 * Do not check further content if the node has been nilled 26113 */ 26114 if (INODE_NILLED(inode)) { 26115 ret = 0; 26116 #ifdef DEBUG_AUTOMATA 26117 xmlGenericError(xmlGenericErrorContext, 26118 "AUTOMATON succeeded on nilled '%s'\n", 26119 inode->localName); 26120 #endif 26121 goto skip_nilled; 26122 } 26123 26124 /* 26125 * Get hold of the still expected content, since a further 26126 * call to xmlRegExecPushString() will lose this information. 26127 */ 26128 xmlRegExecNextValues(inode->regexCtxt, 26129 &nbval, &nbneg, &values[0], &terminal); 26130 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26131 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26132 /* 26133 * Still missing something. 26134 */ 26135 ret = 1; 26136 inode->flags |= 26137 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26138 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26139 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26140 "Missing child element(s)", 26141 nbval, nbneg, values); 26142 #ifdef DEBUG_AUTOMATA 26143 xmlGenericError(xmlGenericErrorContext, 26144 "AUTOMATON missing ERROR on '%s'\n", 26145 inode->localName); 26146 #endif 26147 } else { 26148 /* 26149 * Content model is satisfied. 26150 */ 26151 ret = 0; 26152 #ifdef DEBUG_AUTOMATA 26153 xmlGenericError(xmlGenericErrorContext, 26154 "AUTOMATON succeeded on '%s'\n", 26155 inode->localName); 26156 #endif 26157 } 26158 26159 } 26160 } 26161 26162 skip_nilled: 26163 26164 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26165 goto end_elem; 26166 26167 character_content: 26168 26169 if (vctxt->value != NULL) { 26170 xmlSchemaFreeValue(vctxt->value); 26171 vctxt->value = NULL; 26172 } 26173 /* 26174 * Check character content. 26175 */ 26176 if (inode->decl == NULL) { 26177 /* 26178 * Speedup if no declaration exists. 26179 */ 26180 if (WXS_IS_SIMPLE(inode->typeDef)) { 26181 ret = xmlSchemaVCheckINodeDataType(vctxt, 26182 inode, inode->typeDef, inode->value); 26183 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26184 ret = xmlSchemaVCheckINodeDataType(vctxt, 26185 inode, inode->typeDef->contentTypeDef, 26186 inode->value); 26187 } 26188 if (ret < 0) { 26189 VERROR_INT("xmlSchemaValidatorPopElem", 26190 "calling xmlSchemaVCheckCVCSimpleType()"); 26191 goto internal_error; 26192 } 26193 goto end_elem; 26194 } 26195 /* 26196 * cvc-elt (3.3.4) : 5 26197 * The appropriate case among the following must be true: 26198 */ 26199 /* 26200 * cvc-elt (3.3.4) : 5.1 26201 * If the declaration has a {value constraint}, 26202 * the item has neither element nor character [children] and 26203 * clause 3.2 has not applied, then all of the following must be true: 26204 */ 26205 if ((inode->decl->value != NULL) && 26206 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26207 (! INODE_NILLED(inode))) { 26208 /* 26209 * cvc-elt (3.3.4) : 5.1.1 26210 * If the `actual type definition` is a `local type definition` 26211 * then the canonical lexical representation of the {value constraint} 26212 * value must be a valid default for the `actual type definition` as 26213 * defined in Element Default Valid (Immediate) ($3.3.6). 26214 */ 26215 /* 26216 * NOTE: 'local' above means types acquired by xsi:type. 26217 * NOTE: Although the *canonical* value is stated, it is not 26218 * relevant if canonical or not. Additionally XML Schema 1.1 26219 * will removed this requirement as well. 26220 */ 26221 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26222 26223 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26224 inode->decl->value, &(inode->val)); 26225 if (ret != 0) { 26226 if (ret < 0) { 26227 VERROR_INT("xmlSchemaValidatorPopElem", 26228 "calling xmlSchemaCheckCOSValidDefault()"); 26229 goto internal_error; 26230 } 26231 goto end_elem; 26232 } 26233 /* 26234 * Stop here, to avoid redundant validation of the value 26235 * (see following). 26236 */ 26237 goto default_psvi; 26238 } 26239 /* 26240 * cvc-elt (3.3.4) : 5.1.2 26241 * The element information item with the canonical lexical 26242 * representation of the {value constraint} value used as its 26243 * `normalized value` must be `valid` with respect to the 26244 * `actual type definition` as defined by Element Locally Valid (Type) 26245 * ($3.3.4). 26246 */ 26247 if (WXS_IS_SIMPLE(inode->typeDef)) { 26248 ret = xmlSchemaVCheckINodeDataType(vctxt, 26249 inode, inode->typeDef, inode->decl->value); 26250 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26251 ret = xmlSchemaVCheckINodeDataType(vctxt, 26252 inode, inode->typeDef->contentTypeDef, 26253 inode->decl->value); 26254 } 26255 if (ret != 0) { 26256 if (ret < 0) { 26257 VERROR_INT("xmlSchemaValidatorPopElem", 26258 "calling xmlSchemaVCheckCVCSimpleType()"); 26259 goto internal_error; 26260 } 26261 goto end_elem; 26262 } 26263 26264 default_psvi: 26265 /* 26266 * PSVI: Create a text node on the instance element. 26267 */ 26268 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26269 (inode->node != NULL)) { 26270 xmlNodePtr textChild; 26271 xmlChar *normValue; 26272 /* 26273 * VAL TODO: Normalize the value. 26274 */ 26275 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26276 inode->decl->value); 26277 if (normValue != NULL) { 26278 textChild = xmlNewText(BAD_CAST normValue); 26279 xmlFree(normValue); 26280 } else 26281 textChild = xmlNewText(inode->decl->value); 26282 if (textChild == NULL) { 26283 VERROR_INT("xmlSchemaValidatorPopElem", 26284 "calling xmlNewText()"); 26285 goto internal_error; 26286 } else 26287 xmlAddChild(inode->node, textChild); 26288 } 26289 26290 } else if (! INODE_NILLED(inode)) { 26291 /* 26292 * 5.2.1 The element information item must be `valid` with respect 26293 * to the `actual type definition` as defined by Element Locally 26294 * Valid (Type) ($3.3.4). 26295 */ 26296 if (WXS_IS_SIMPLE(inode->typeDef)) { 26297 /* 26298 * SPEC (cvc-type) (3.1) 26299 * "If the type definition is a simple type definition, ..." 26300 * (3.1.3) "If clause 3.2 of Element Locally Valid 26301 * (Element) ($3.3.4) did not apply, then the `normalized value` 26302 * must be `valid` with respect to the type definition as defined 26303 * by String Valid ($3.14.4). 26304 */ 26305 ret = xmlSchemaVCheckINodeDataType(vctxt, 26306 inode, inode->typeDef, inode->value); 26307 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26308 /* 26309 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26310 * definition, then the element information item must be 26311 * `valid` with respect to the type definition as per 26312 * Element Locally Valid (Complex Type) ($3.4.4);" 26313 * 26314 * SPEC (cvc-complex-type) (2.2) 26315 * "If the {content type} is a simple type definition, ... 26316 * the `normalized value` of the element information item is 26317 * `valid` with respect to that simple type definition as 26318 * defined by String Valid ($3.14.4)." 26319 */ 26320 ret = xmlSchemaVCheckINodeDataType(vctxt, 26321 inode, inode->typeDef->contentTypeDef, inode->value); 26322 } 26323 if (ret != 0) { 26324 if (ret < 0) { 26325 VERROR_INT("xmlSchemaValidatorPopElem", 26326 "calling xmlSchemaVCheckCVCSimpleType()"); 26327 goto internal_error; 26328 } 26329 goto end_elem; 26330 } 26331 /* 26332 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26333 * not applied, all of the following must be true: 26334 */ 26335 if ((inode->decl->value != NULL) && 26336 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26337 26338 /* 26339 * TODO: We will need a computed value, when comparison is 26340 * done on computed values. 26341 */ 26342 /* 26343 * 5.2.2.1 The element information item must have no element 26344 * information item [children]. 26345 */ 26346 if (inode->flags & 26347 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26348 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26349 VERROR(ret, NULL, 26350 "The content must not containt element nodes since " 26351 "there is a fixed value constraint"); 26352 goto end_elem; 26353 } else { 26354 /* 26355 * 5.2.2.2 The appropriate case among the following must 26356 * be true: 26357 */ 26358 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26359 /* 26360 * 5.2.2.2.1 If the {content type} of the `actual type 26361 * definition` is mixed, then the *initial value* of the 26362 * item must match the canonical lexical representation 26363 * of the {value constraint} value. 26364 * 26365 * ... the *initial value* of an element information 26366 * item is the string composed of, in order, the 26367 * [character code] of each character information item in 26368 * the [children] of that element information item. 26369 */ 26370 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26371 /* 26372 * VAL TODO: Report invalid & expected values as well. 26373 * VAL TODO: Implement the canonical stuff. 26374 */ 26375 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26376 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26377 ret, NULL, NULL, 26378 "The initial value '%s' does not match the fixed " 26379 "value constraint '%s'", 26380 inode->value, inode->decl->value); 26381 goto end_elem; 26382 } 26383 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26384 /* 26385 * 5.2.2.2.2 If the {content type} of the `actual type 26386 * definition` is a simple type definition, then the 26387 * *actual value* of the item must match the canonical 26388 * lexical representation of the {value constraint} value. 26389 */ 26390 /* 26391 * VAL TODO: *actual value* is the normalized value, impl. 26392 * this. 26393 * VAL TODO: Report invalid & expected values as well. 26394 * VAL TODO: Implement a comparison with the computed values. 26395 */ 26396 if (! xmlStrEqual(inode->value, 26397 inode->decl->value)) { 26398 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26399 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26400 ret, NULL, NULL, 26401 "The actual value '%s' does not match the fixed " 26402 "value constraint '%s'", 26403 inode->value, 26404 inode->decl->value); 26405 goto end_elem; 26406 } 26407 } 26408 } 26409 } 26410 } 26411 26412 end_elem: 26413 if (vctxt->depth < 0) { 26414 /* TODO: raise error? */ 26415 return (0); 26416 } 26417 if (vctxt->depth == vctxt->skipDepth) 26418 vctxt->skipDepth = -1; 26419 /* 26420 * Evaluate the history of XPath state objects. 26421 */ 26422 if (inode->appliedXPath && 26423 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26424 goto internal_error; 26425 /* 26426 * MAYBE TODO: 26427 * SPEC (6) "The element information item must be `valid` with 26428 * respect to each of the {identity-constraint definitions} as per 26429 * Identity-constraint Satisfied ($3.11.4)." 26430 */ 26431 /* 26432 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26433 * need to be built in any case. 26434 * We will currently build IDC node-tables and bubble them only if 26435 * keyrefs do exist. 26436 */ 26437 26438 /* 26439 * Add the current IDC target-nodes to the IDC node-tables. 26440 */ 26441 if ((inode->idcMatchers != NULL) && 26442 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26443 { 26444 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26445 goto internal_error; 26446 } 26447 /* 26448 * Validate IDC keyrefs. 26449 */ 26450 if (vctxt->inode->hasKeyrefs) 26451 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26452 goto internal_error; 26453 /* 26454 * Merge/free the IDC table. 26455 */ 26456 if (inode->idcTable != NULL) { 26457 #ifdef DEBUG_IDC_NODE_TABLE 26458 xmlSchemaDebugDumpIDCTable(stdout, 26459 inode->nsName, 26460 inode->localName, 26461 inode->idcTable); 26462 #endif 26463 if ((vctxt->depth > 0) && 26464 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26465 { 26466 /* 26467 * Merge the IDC node table with the table of the parent node. 26468 */ 26469 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26470 goto internal_error; 26471 } 26472 } 26473 /* 26474 * Clear the current ielem. 26475 * VAL TODO: Don't free the PSVI IDC tables if they are 26476 * requested for the PSVI. 26477 */ 26478 xmlSchemaClearElemInfo(vctxt, inode); 26479 /* 26480 * Skip further processing if we are on the validation root. 26481 */ 26482 if (vctxt->depth == 0) { 26483 vctxt->depth--; 26484 vctxt->inode = NULL; 26485 return (0); 26486 } 26487 /* 26488 * Reset the keyrefDepth if needed. 26489 */ 26490 if (vctxt->aidcs != NULL) { 26491 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26492 do { 26493 if (aidc->keyrefDepth == vctxt->depth) { 26494 /* 26495 * A 'keyrefDepth' of a key/unique IDC matches the current 26496 * depth, this means that we are leaving the scope of the 26497 * top-most keyref IDC which refers to this IDC. 26498 */ 26499 aidc->keyrefDepth = -1; 26500 } 26501 aidc = aidc->next; 26502 } while (aidc != NULL); 26503 } 26504 vctxt->depth--; 26505 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26506 /* 26507 * VAL TODO: 7 If the element information item is the `validation root`, it must be 26508 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4). 26509 */ 26510 return (ret); 26511 26512 internal_error: 26513 vctxt->err = -1; 26514 return (-1); 26515 } 26516 26517 /* 26518 * 3.4.4 Complex Type Definition Validation Rules 26519 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26520 */ 26521 static int 26522 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26523 { 26524 xmlSchemaNodeInfoPtr pielem; 26525 xmlSchemaTypePtr ptype; 26526 int ret = 0; 26527 26528 if (vctxt->depth <= 0) { 26529 VERROR_INT("xmlSchemaValidateChildElem", 26530 "not intended for the validation root"); 26531 return (-1); 26532 } 26533 pielem = vctxt->elemInfos[vctxt->depth -1]; 26534 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26535 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26536 /* 26537 * Handle 'nilled' elements. 26538 */ 26539 if (INODE_NILLED(pielem)) { 26540 /* 26541 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26542 */ 26543 ACTIVATE_PARENT_ELEM; 26544 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26545 VERROR(ret, NULL, 26546 "Neither character nor element content is allowed, " 26547 "because the element was 'nilled'"); 26548 ACTIVATE_ELEM; 26549 goto unexpected_elem; 26550 } 26551 26552 ptype = pielem->typeDef; 26553 26554 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26555 /* 26556 * Workaround for "anyType": we have currently no content model 26557 * assigned for "anyType", so handle it explicitely. 26558 * "anyType" has an unbounded, lax "any" wildcard. 26559 */ 26560 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26561 vctxt->inode->localName, 26562 vctxt->inode->nsName); 26563 26564 if (vctxt->inode->decl == NULL) { 26565 xmlSchemaAttrInfoPtr iattr; 26566 /* 26567 * Process "xsi:type". 26568 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26569 */ 26570 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26571 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26572 if (iattr != NULL) { 26573 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26574 &(vctxt->inode->typeDef), NULL); 26575 if (ret != 0) { 26576 if (ret == -1) { 26577 VERROR_INT("xmlSchemaValidateChildElem", 26578 "calling xmlSchemaProcessXSIType() to " 26579 "process the attribute 'xsi:nil'"); 26580 return (-1); 26581 } 26582 return (ret); 26583 } 26584 } else { 26585 /* 26586 * Fallback to "anyType". 26587 * 26588 * SPEC (cvc-assess-elt) 26589 * "If the item cannot be `strictly assessed`, [...] 26590 * an element information item's schema validity may be laxly 26591 * assessed if its `context-determined declaration` is not 26592 * skip by `validating` with respect to the `ur-type 26593 * definition` as per Element Locally Valid (Type) ($3.3.4)." 26594 */ 26595 vctxt->inode->typeDef = 26596 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26597 } 26598 } 26599 return (0); 26600 } 26601 26602 switch (ptype->contentType) { 26603 case XML_SCHEMA_CONTENT_EMPTY: 26604 /* 26605 * SPEC (2.1) "If the {content type} is empty, then the 26606 * element information item has no character or element 26607 * information item [children]." 26608 */ 26609 ACTIVATE_PARENT_ELEM 26610 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26611 VERROR(ret, NULL, 26612 "Element content is not allowed, " 26613 "because the content type is empty"); 26614 ACTIVATE_ELEM 26615 goto unexpected_elem; 26616 break; 26617 26618 case XML_SCHEMA_CONTENT_MIXED: 26619 case XML_SCHEMA_CONTENT_ELEMENTS: { 26620 xmlRegExecCtxtPtr regexCtxt; 26621 xmlChar *values[10]; 26622 int terminal, nbval = 10, nbneg; 26623 26624 /* VAL TODO: Optimized "anyType" validation.*/ 26625 26626 if (ptype->contModel == NULL) { 26627 VERROR_INT("xmlSchemaValidateChildElem", 26628 "type has elem content but no content model"); 26629 return (-1); 26630 } 26631 /* 26632 * Safety belf for evaluation if the cont. model was already 26633 * examined to be invalid. 26634 */ 26635 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26636 VERROR_INT("xmlSchemaValidateChildElem", 26637 "validating elem, but elem content is already invalid"); 26638 return (-1); 26639 } 26640 26641 regexCtxt = pielem->regexCtxt; 26642 if (regexCtxt == NULL) { 26643 /* 26644 * Create the regex context. 26645 */ 26646 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26647 xmlSchemaVContentModelCallback, vctxt); 26648 if (regexCtxt == NULL) { 26649 VERROR_INT("xmlSchemaValidateChildElem", 26650 "failed to create a regex context"); 26651 return (-1); 26652 } 26653 pielem->regexCtxt = regexCtxt; 26654 #ifdef DEBUG_AUTOMATA 26655 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26656 pielem->localName); 26657 #endif 26658 } 26659 26660 /* 26661 * SPEC (2.4) "If the {content type} is element-only or mixed, 26662 * then the sequence of the element information item's 26663 * element information item [children], if any, taken in 26664 * order, is `valid` with respect to the {content type}'s 26665 * particle, as defined in Element Sequence Locally Valid 26666 * (Particle) ($3.9.4)." 26667 */ 26668 ret = xmlRegExecPushString2(regexCtxt, 26669 vctxt->inode->localName, 26670 vctxt->inode->nsName, 26671 vctxt->inode); 26672 #ifdef DEBUG_AUTOMATA 26673 if (ret < 0) 26674 xmlGenericError(xmlGenericErrorContext, 26675 "AUTOMATON push ERROR for '%s' on '%s'\n", 26676 vctxt->inode->localName, pielem->localName); 26677 else 26678 xmlGenericError(xmlGenericErrorContext, 26679 "AUTOMATON push OK for '%s' on '%s'\n", 26680 vctxt->inode->localName, pielem->localName); 26681 #endif 26682 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26683 VERROR_INT("xmlSchemaValidateChildElem", 26684 "calling xmlRegExecPushString2()"); 26685 return (-1); 26686 } 26687 if (ret < 0) { 26688 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26689 &values[0], &terminal); 26690 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26691 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26692 "This element is not expected", 26693 nbval, nbneg, values); 26694 ret = vctxt->err; 26695 goto unexpected_elem; 26696 } else 26697 ret = 0; 26698 } 26699 break; 26700 case XML_SCHEMA_CONTENT_SIMPLE: 26701 case XML_SCHEMA_CONTENT_BASIC: 26702 ACTIVATE_PARENT_ELEM 26703 if (WXS_IS_COMPLEX(ptype)) { 26704 /* 26705 * SPEC (cvc-complex-type) (2.2) 26706 * "If the {content type} is a simple type definition, then 26707 * the element information item has no element information 26708 * item [children], ..." 26709 */ 26710 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26711 VERROR(ret, NULL, "Element content is not allowed, " 26712 "because the content type is a simple type definition"); 26713 } else { 26714 /* 26715 * SPEC (cvc-type) (3.1.2) "The element information item must 26716 * have no element information item [children]." 26717 */ 26718 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26719 VERROR(ret, NULL, "Element content is not allowed, " 26720 "because the type definition is simple"); 26721 } 26722 ACTIVATE_ELEM 26723 ret = vctxt->err; 26724 goto unexpected_elem; 26725 break; 26726 26727 default: 26728 break; 26729 } 26730 return (ret); 26731 unexpected_elem: 26732 /* 26733 * Pop this element and set the skipDepth to skip 26734 * all further content of the parent element. 26735 */ 26736 vctxt->skipDepth = vctxt->depth; 26737 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26738 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26739 return (ret); 26740 } 26741 26742 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26743 #define XML_SCHEMA_PUSH_TEXT_CREATED 2 26744 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26745 26746 static int 26747 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26748 int nodeType, const xmlChar *value, int len, 26749 int mode, int *consumed) 26750 { 26751 /* 26752 * Unfortunately we have to duplicate the text sometimes. 26753 * OPTIMIZE: Maybe we could skip it, if: 26754 * 1. content type is simple 26755 * 2. whitespace is "collapse" 26756 * 3. it consists of whitespace only 26757 * 26758 * Process character content. 26759 */ 26760 if (consumed != NULL) 26761 *consumed = 0; 26762 if (INODE_NILLED(vctxt->inode)) { 26763 /* 26764 * SPEC cvc-elt (3.3.4 - 3.2.1) 26765 * "The element information item must have no character or 26766 * element information item [children]." 26767 */ 26768 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26769 "Neither character nor element content is allowed " 26770 "because the element is 'nilled'"); 26771 return (vctxt->err); 26772 } 26773 /* 26774 * SPEC (2.1) "If the {content type} is empty, then the 26775 * element information item has no character or element 26776 * information item [children]." 26777 */ 26778 if (vctxt->inode->typeDef->contentType == 26779 XML_SCHEMA_CONTENT_EMPTY) { 26780 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26781 "Character content is not allowed, " 26782 "because the content type is empty"); 26783 return (vctxt->err); 26784 } 26785 26786 if (vctxt->inode->typeDef->contentType == 26787 XML_SCHEMA_CONTENT_ELEMENTS) { 26788 if ((nodeType != XML_TEXT_NODE) || 26789 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26790 /* 26791 * SPEC cvc-complex-type (2.3) 26792 * "If the {content type} is element-only, then the 26793 * element information item has no character information 26794 * item [children] other than those whose [character 26795 * code] is defined as a white space in [XML 1.0 (Second 26796 * Edition)]." 26797 */ 26798 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26799 "Character content other than whitespace is not allowed " 26800 "because the content type is 'element-only'"); 26801 return (vctxt->err); 26802 } 26803 return (0); 26804 } 26805 26806 if ((value == NULL) || (value[0] == 0)) 26807 return (0); 26808 /* 26809 * Save the value. 26810 * NOTE that even if the content type is *mixed*, we need the 26811 * *initial value* for default/fixed value constraints. 26812 */ 26813 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26814 ((vctxt->inode->decl == NULL) || 26815 (vctxt->inode->decl->value == NULL))) 26816 return (0); 26817 26818 if (vctxt->inode->value == NULL) { 26819 /* 26820 * Set the value. 26821 */ 26822 switch (mode) { 26823 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26824 /* 26825 * When working on a tree. 26826 */ 26827 vctxt->inode->value = value; 26828 break; 26829 case XML_SCHEMA_PUSH_TEXT_CREATED: 26830 /* 26831 * When working with the reader. 26832 * The value will be freed by the element info. 26833 */ 26834 vctxt->inode->value = value; 26835 if (consumed != NULL) 26836 *consumed = 1; 26837 vctxt->inode->flags |= 26838 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26839 break; 26840 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26841 /* 26842 * When working with SAX. 26843 * The value will be freed by the element info. 26844 */ 26845 if (len != -1) 26846 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26847 else 26848 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26849 vctxt->inode->flags |= 26850 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26851 break; 26852 default: 26853 break; 26854 } 26855 } else { 26856 if (len < 0) 26857 len = xmlStrlen(value); 26858 /* 26859 * Concat the value. 26860 */ 26861 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26862 vctxt->inode->value = BAD_CAST xmlStrncat( 26863 (xmlChar *) vctxt->inode->value, value, len); 26864 } else { 26865 vctxt->inode->value = 26866 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26867 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26868 } 26869 } 26870 26871 return (0); 26872 } 26873 26874 static int 26875 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26876 { 26877 int ret = 0; 26878 26879 if ((vctxt->skipDepth != -1) && 26880 (vctxt->depth >= vctxt->skipDepth)) { 26881 VERROR_INT("xmlSchemaValidateElem", 26882 "in skip-state"); 26883 goto internal_error; 26884 } 26885 if (vctxt->xsiAssemble) { 26886 /* 26887 * We will stop validation if there was an error during 26888 * dynamic schema construction. 26889 * Note that we simply set @skipDepth to 0, this could 26890 * mean that a streaming document via SAX would be 26891 * still read to the end but it won't be validated any more. 26892 * TODO: If we are sure how to stop the validation at once 26893 * for all input scenarios, then this should be changed to 26894 * instantly stop the validation. 26895 */ 26896 ret = xmlSchemaAssembleByXSI(vctxt); 26897 if (ret != 0) { 26898 if (ret == -1) 26899 goto internal_error; 26900 vctxt->skipDepth = 0; 26901 return(ret); 26902 } 26903 /* 26904 * Augment the IDC definitions for the main schema and all imported ones 26905 * NOTE: main schema is the first in the imported list 26906 */ 26907 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, 26908 vctxt); 26909 } 26910 if (vctxt->depth > 0) { 26911 /* 26912 * Validate this element against the content model 26913 * of the parent. 26914 */ 26915 ret = xmlSchemaValidateChildElem(vctxt); 26916 if (ret != 0) { 26917 if (ret < 0) { 26918 VERROR_INT("xmlSchemaValidateElem", 26919 "calling xmlSchemaStreamValidateChildElement()"); 26920 goto internal_error; 26921 } 26922 goto exit; 26923 } 26924 if (vctxt->depth == vctxt->skipDepth) 26925 goto exit; 26926 if ((vctxt->inode->decl == NULL) && 26927 (vctxt->inode->typeDef == NULL)) { 26928 VERROR_INT("xmlSchemaValidateElem", 26929 "the child element was valid but neither the " 26930 "declaration nor the type was set"); 26931 goto internal_error; 26932 } 26933 } else { 26934 /* 26935 * Get the declaration of the validation root. 26936 */ 26937 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26938 vctxt->inode->localName, 26939 vctxt->inode->nsName); 26940 if (vctxt->inode->decl == NULL) { 26941 ret = XML_SCHEMAV_CVC_ELT_1; 26942 VERROR(ret, NULL, 26943 "No matching global declaration available " 26944 "for the validation root"); 26945 goto exit; 26946 } 26947 } 26948 26949 if (vctxt->inode->decl == NULL) 26950 goto type_validation; 26951 26952 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26953 int skip; 26954 /* 26955 * Wildcards. 26956 */ 26957 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26958 if (ret != 0) { 26959 if (ret < 0) { 26960 VERROR_INT("xmlSchemaValidateElem", 26961 "calling xmlSchemaValidateElemWildcard()"); 26962 goto internal_error; 26963 } 26964 goto exit; 26965 } 26966 if (skip) { 26967 vctxt->skipDepth = vctxt->depth; 26968 goto exit; 26969 } 26970 /* 26971 * The declaration might be set by the wildcard validation, 26972 * when the processContents is "lax" or "strict". 26973 */ 26974 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26975 /* 26976 * Clear the "decl" field to not confuse further processing. 26977 */ 26978 vctxt->inode->decl = NULL; 26979 goto type_validation; 26980 } 26981 } 26982 /* 26983 * Validate against the declaration. 26984 */ 26985 ret = xmlSchemaValidateElemDecl(vctxt); 26986 if (ret != 0) { 26987 if (ret < 0) { 26988 VERROR_INT("xmlSchemaValidateElem", 26989 "calling xmlSchemaValidateElemDecl()"); 26990 goto internal_error; 26991 } 26992 goto exit; 26993 } 26994 /* 26995 * Validate against the type definition. 26996 */ 26997 type_validation: 26998 26999 if (vctxt->inode->typeDef == NULL) { 27000 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 27001 ret = XML_SCHEMAV_CVC_TYPE_1; 27002 VERROR(ret, NULL, 27003 "The type definition is absent"); 27004 goto exit; 27005 } 27006 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 27007 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 27008 ret = XML_SCHEMAV_CVC_TYPE_2; 27009 VERROR(ret, NULL, 27010 "The type definition is abstract"); 27011 goto exit; 27012 } 27013 /* 27014 * Evaluate IDCs. Do it here, since new IDC matchers are registered 27015 * during validation against the declaration. This must be done 27016 * _before_ attribute validation. 27017 */ 27018 if (vctxt->xpathStates != NULL) { 27019 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 27020 vctxt->inode->appliedXPath = 1; 27021 if (ret == -1) { 27022 VERROR_INT("xmlSchemaValidateElem", 27023 "calling xmlSchemaXPathEvaluate()"); 27024 goto internal_error; 27025 } 27026 } 27027 /* 27028 * Validate attributes. 27029 */ 27030 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 27031 if ((vctxt->nbAttrInfos != 0) || 27032 (vctxt->inode->typeDef->attrUses != NULL)) { 27033 27034 ret = xmlSchemaVAttributesComplex(vctxt); 27035 } 27036 } else if (vctxt->nbAttrInfos != 0) { 27037 27038 ret = xmlSchemaVAttributesSimple(vctxt); 27039 } 27040 /* 27041 * Clear registered attributes. 27042 */ 27043 if (vctxt->nbAttrInfos != 0) 27044 xmlSchemaClearAttrInfos(vctxt); 27045 if (ret == -1) { 27046 VERROR_INT("xmlSchemaValidateElem", 27047 "calling attributes validation"); 27048 goto internal_error; 27049 } 27050 /* 27051 * Don't return an error if attributes are invalid on purpose. 27052 */ 27053 ret = 0; 27054 27055 exit: 27056 if (ret != 0) 27057 vctxt->skipDepth = vctxt->depth; 27058 return (ret); 27059 internal_error: 27060 return (-1); 27061 } 27062 27063 #ifdef XML_SCHEMA_READER_ENABLED 27064 static int 27065 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 27066 { 27067 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 27068 int depth, nodeType, ret = 0, consumed; 27069 xmlSchemaNodeInfoPtr ielem; 27070 27071 vctxt->depth = -1; 27072 ret = xmlTextReaderRead(vctxt->reader); 27073 /* 27074 * Move to the document element. 27075 */ 27076 while (ret == 1) { 27077 nodeType = xmlTextReaderNodeType(vctxt->reader); 27078 if (nodeType == XML_ELEMENT_NODE) 27079 goto root_found; 27080 ret = xmlTextReaderRead(vctxt->reader); 27081 } 27082 goto exit; 27083 27084 root_found: 27085 27086 do { 27087 depth = xmlTextReaderDepth(vctxt->reader); 27088 nodeType = xmlTextReaderNodeType(vctxt->reader); 27089 27090 if (nodeType == XML_ELEMENT_NODE) { 27091 27092 vctxt->depth++; 27093 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27094 VERROR_INT("xmlSchemaVReaderWalk", 27095 "calling xmlSchemaValidatorPushElem()"); 27096 goto internal_error; 27097 } 27098 ielem = vctxt->inode; 27099 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27100 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27101 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27102 /* 27103 * Is the element empty? 27104 */ 27105 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27106 if (ret == -1) { 27107 VERROR_INT("xmlSchemaVReaderWalk", 27108 "calling xmlTextReaderIsEmptyElement()"); 27109 goto internal_error; 27110 } 27111 if (ret) { 27112 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27113 } 27114 /* 27115 * Register attributes. 27116 */ 27117 vctxt->nbAttrInfos = 0; 27118 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27119 if (ret == -1) { 27120 VERROR_INT("xmlSchemaVReaderWalk", 27121 "calling xmlTextReaderMoveToFirstAttribute()"); 27122 goto internal_error; 27123 } 27124 if (ret == 1) { 27125 do { 27126 /* 27127 * VAL TODO: How do we know that the reader works on a 27128 * node tree, to be able to pass a node here? 27129 */ 27130 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27131 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27132 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27133 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27134 27135 VERROR_INT("xmlSchemaVReaderWalk", 27136 "calling xmlSchemaValidatorPushAttribute()"); 27137 goto internal_error; 27138 } 27139 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27140 if (ret == -1) { 27141 VERROR_INT("xmlSchemaVReaderWalk", 27142 "calling xmlTextReaderMoveToFirstAttribute()"); 27143 goto internal_error; 27144 } 27145 } while (ret == 1); 27146 /* 27147 * Back to element position. 27148 */ 27149 ret = xmlTextReaderMoveToElement(vctxt->reader); 27150 if (ret == -1) { 27151 VERROR_INT("xmlSchemaVReaderWalk", 27152 "calling xmlTextReaderMoveToElement()"); 27153 goto internal_error; 27154 } 27155 } 27156 /* 27157 * Validate the element. 27158 */ 27159 ret= xmlSchemaValidateElem(vctxt); 27160 if (ret != 0) { 27161 if (ret == -1) { 27162 VERROR_INT("xmlSchemaVReaderWalk", 27163 "calling xmlSchemaValidateElem()"); 27164 goto internal_error; 27165 } 27166 goto exit; 27167 } 27168 if (vctxt->depth == vctxt->skipDepth) { 27169 int curDepth; 27170 /* 27171 * Skip all content. 27172 */ 27173 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27174 ret = xmlTextReaderRead(vctxt->reader); 27175 curDepth = xmlTextReaderDepth(vctxt->reader); 27176 while ((ret == 1) && (curDepth != depth)) { 27177 ret = xmlTextReaderRead(vctxt->reader); 27178 curDepth = xmlTextReaderDepth(vctxt->reader); 27179 } 27180 if (ret < 0) { 27181 /* 27182 * VAL TODO: A reader error occurred; what to do here? 27183 */ 27184 ret = 1; 27185 goto exit; 27186 } 27187 } 27188 goto leave_elem; 27189 } 27190 /* 27191 * READER VAL TODO: Is an END_ELEM really never called 27192 * if the elem is empty? 27193 */ 27194 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27195 goto leave_elem; 27196 } else if (nodeType == END_ELEM) { 27197 /* 27198 * Process END of element. 27199 */ 27200 leave_elem: 27201 ret = xmlSchemaValidatorPopElem(vctxt); 27202 if (ret != 0) { 27203 if (ret < 0) { 27204 VERROR_INT("xmlSchemaVReaderWalk", 27205 "calling xmlSchemaValidatorPopElem()"); 27206 goto internal_error; 27207 } 27208 goto exit; 27209 } 27210 if (vctxt->depth >= 0) 27211 ielem = vctxt->inode; 27212 else 27213 ielem = NULL; 27214 } else if ((nodeType == XML_TEXT_NODE) || 27215 (nodeType == XML_CDATA_SECTION_NODE) || 27216 (nodeType == WHTSP) || 27217 (nodeType == SIGN_WHTSP)) { 27218 /* 27219 * Process character content. 27220 */ 27221 xmlChar *value; 27222 27223 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27224 nodeType = XML_TEXT_NODE; 27225 27226 value = xmlTextReaderValue(vctxt->reader); 27227 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27228 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27229 if (! consumed) 27230 xmlFree(value); 27231 if (ret == -1) { 27232 VERROR_INT("xmlSchemaVReaderWalk", 27233 "calling xmlSchemaVPushText()"); 27234 goto internal_error; 27235 } 27236 } else if ((nodeType == XML_ENTITY_NODE) || 27237 (nodeType == XML_ENTITY_REF_NODE)) { 27238 /* 27239 * VAL TODO: What to do with entities? 27240 */ 27241 TODO 27242 } 27243 /* 27244 * Read next node. 27245 */ 27246 ret = xmlTextReaderRead(vctxt->reader); 27247 } while (ret == 1); 27248 27249 exit: 27250 return (ret); 27251 internal_error: 27252 return (-1); 27253 } 27254 #endif 27255 27256 /************************************************************************ 27257 * * 27258 * SAX validation handlers * 27259 * * 27260 ************************************************************************/ 27261 27262 /* 27263 * Process text content. 27264 */ 27265 static void 27266 xmlSchemaSAXHandleText(void *ctx, 27267 const xmlChar * ch, 27268 int len) 27269 { 27270 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27271 27272 if (vctxt->depth < 0) 27273 return; 27274 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27275 return; 27276 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27277 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27278 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27279 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27280 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27281 "calling xmlSchemaVPushText()"); 27282 vctxt->err = -1; 27283 xmlStopParser(vctxt->parserCtxt); 27284 } 27285 } 27286 27287 /* 27288 * Process CDATA content. 27289 */ 27290 static void 27291 xmlSchemaSAXHandleCDataSection(void *ctx, 27292 const xmlChar * ch, 27293 int len) 27294 { 27295 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27296 27297 if (vctxt->depth < 0) 27298 return; 27299 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27300 return; 27301 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27302 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27303 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27304 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27305 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27306 "calling xmlSchemaVPushText()"); 27307 vctxt->err = -1; 27308 xmlStopParser(vctxt->parserCtxt); 27309 } 27310 } 27311 27312 static void 27313 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27314 const xmlChar * name ATTRIBUTE_UNUSED) 27315 { 27316 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27317 27318 if (vctxt->depth < 0) 27319 return; 27320 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27321 return; 27322 /* SAX VAL TODO: What to do here? */ 27323 TODO 27324 } 27325 27326 static void 27327 xmlSchemaSAXHandleStartElementNs(void *ctx, 27328 const xmlChar * localname, 27329 const xmlChar * prefix ATTRIBUTE_UNUSED, 27330 const xmlChar * URI, 27331 int nb_namespaces, 27332 const xmlChar ** namespaces, 27333 int nb_attributes, 27334 int nb_defaulted ATTRIBUTE_UNUSED, 27335 const xmlChar ** attributes) 27336 { 27337 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27338 int ret; 27339 xmlSchemaNodeInfoPtr ielem; 27340 int i, j; 27341 27342 /* 27343 * SAX VAL TODO: What to do with nb_defaulted? 27344 */ 27345 /* 27346 * Skip elements if inside a "skip" wildcard or invalid. 27347 */ 27348 vctxt->depth++; 27349 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27350 return; 27351 /* 27352 * Push the element. 27353 */ 27354 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27355 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27356 "calling xmlSchemaValidatorPushElem()"); 27357 goto internal_error; 27358 } 27359 ielem = vctxt->inode; 27360 /* 27361 * TODO: Is this OK? 27362 */ 27363 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27364 ielem->localName = localname; 27365 ielem->nsName = URI; 27366 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27367 /* 27368 * Register namespaces on the elem info. 27369 */ 27370 if (nb_namespaces != 0) { 27371 /* 27372 * Although the parser builds its own namespace list, 27373 * we have no access to it, so we'll use an own one. 27374 */ 27375 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27376 /* 27377 * Store prefix and namespace name. 27378 */ 27379 if (ielem->nsBindings == NULL) { 27380 ielem->nsBindings = 27381 (const xmlChar **) xmlMalloc(10 * 27382 sizeof(const xmlChar *)); 27383 if (ielem->nsBindings == NULL) { 27384 xmlSchemaVErrMemory(vctxt, 27385 "allocating namespace bindings for SAX validation", 27386 NULL); 27387 goto internal_error; 27388 } 27389 ielem->nbNsBindings = 0; 27390 ielem->sizeNsBindings = 5; 27391 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27392 ielem->sizeNsBindings *= 2; 27393 ielem->nsBindings = 27394 (const xmlChar **) xmlRealloc( 27395 (void *) ielem->nsBindings, 27396 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27397 if (ielem->nsBindings == NULL) { 27398 xmlSchemaVErrMemory(vctxt, 27399 "re-allocating namespace bindings for SAX validation", 27400 NULL); 27401 goto internal_error; 27402 } 27403 } 27404 27405 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27406 if (namespaces[j+1][0] == 0) { 27407 /* 27408 * Handle xmlns="". 27409 */ 27410 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27411 } else 27412 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27413 namespaces[j+1]; 27414 ielem->nbNsBindings++; 27415 } 27416 } 27417 /* 27418 * Register attributes. 27419 * SAX VAL TODO: We are not adding namespace declaration 27420 * attributes yet. 27421 */ 27422 if (nb_attributes != 0) { 27423 int valueLen, k, l; 27424 xmlChar *value; 27425 27426 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27427 /* 27428 * Duplicate the value, changing any & to a literal ampersand. 27429 * 27430 * libxml2 differs from normal SAX here in that it escapes all ampersands 27431 * as & instead of delivering the raw converted string. Changing the 27432 * behavior at this point would break applications that use this API, so 27433 * we are forced to work around it. 27434 */ 27435 valueLen = attributes[j+4] - attributes[j+3]; 27436 value = xmlMallocAtomic(valueLen + 1); 27437 if (value == NULL) { 27438 xmlSchemaVErrMemory(vctxt, 27439 "allocating string for decoded attribute", 27440 NULL); 27441 goto internal_error; 27442 } 27443 for (k = 0, l = 0; k < valueLen; l++) { 27444 if (k < valueLen - 4 && 27445 attributes[j+3][k+0] == '&' && 27446 attributes[j+3][k+1] == '#' && 27447 attributes[j+3][k+2] == '3' && 27448 attributes[j+3][k+3] == '8' && 27449 attributes[j+3][k+4] == ';') { 27450 value[l] = '&'; 27451 k += 5; 27452 } else { 27453 value[l] = attributes[j+3][k]; 27454 k++; 27455 } 27456 } 27457 value[l] = '\0'; 27458 /* 27459 * TODO: Set the node line. 27460 */ 27461 ret = xmlSchemaValidatorPushAttribute(vctxt, 27462 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27463 value, 1); 27464 if (ret == -1) { 27465 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27466 "calling xmlSchemaValidatorPushAttribute()"); 27467 goto internal_error; 27468 } 27469 } 27470 } 27471 /* 27472 * Validate the element. 27473 */ 27474 ret = xmlSchemaValidateElem(vctxt); 27475 if (ret != 0) { 27476 if (ret == -1) { 27477 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27478 "calling xmlSchemaValidateElem()"); 27479 goto internal_error; 27480 } 27481 goto exit; 27482 } 27483 27484 exit: 27485 return; 27486 internal_error: 27487 vctxt->err = -1; 27488 xmlStopParser(vctxt->parserCtxt); 27489 return; 27490 } 27491 27492 static void 27493 xmlSchemaSAXHandleEndElementNs(void *ctx, 27494 const xmlChar * localname ATTRIBUTE_UNUSED, 27495 const xmlChar * prefix ATTRIBUTE_UNUSED, 27496 const xmlChar * URI ATTRIBUTE_UNUSED) 27497 { 27498 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27499 int res; 27500 27501 /* 27502 * Skip elements if inside a "skip" wildcard or if invalid. 27503 */ 27504 if (vctxt->skipDepth != -1) { 27505 if (vctxt->depth > vctxt->skipDepth) { 27506 vctxt->depth--; 27507 return; 27508 } else 27509 vctxt->skipDepth = -1; 27510 } 27511 /* 27512 * SAX VAL TODO: Just a temporary check. 27513 */ 27514 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27515 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27516 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27517 "elem pop mismatch"); 27518 } 27519 res = xmlSchemaValidatorPopElem(vctxt); 27520 if (res != 0) { 27521 if (res < 0) { 27522 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27523 "calling xmlSchemaValidatorPopElem()"); 27524 goto internal_error; 27525 } 27526 goto exit; 27527 } 27528 exit: 27529 return; 27530 internal_error: 27531 vctxt->err = -1; 27532 xmlStopParser(vctxt->parserCtxt); 27533 return; 27534 } 27535 27536 /************************************************************************ 27537 * * 27538 * Validation interfaces * 27539 * * 27540 ************************************************************************/ 27541 27542 /** 27543 * xmlSchemaNewValidCtxt: 27544 * @schema: a precompiled XML Schemas 27545 * 27546 * Create an XML Schemas validation context based on the given schema. 27547 * 27548 * Returns the validation context or NULL in case of error 27549 */ 27550 xmlSchemaValidCtxtPtr 27551 xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27552 { 27553 xmlSchemaValidCtxtPtr ret; 27554 27555 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27556 if (ret == NULL) { 27557 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27558 return (NULL); 27559 } 27560 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27561 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27562 ret->dict = xmlDictCreate(); 27563 ret->nodeQNames = xmlSchemaItemListCreate(); 27564 ret->schema = schema; 27565 return (ret); 27566 } 27567 27568 /** 27569 * xmlSchemaValidateSetFilename: 27570 * @vctxt: the schema validation context 27571 * @filename: the file name 27572 * 27573 * Workaround to provide file error reporting information when this is 27574 * not provided by current APIs 27575 */ 27576 void 27577 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) { 27578 if (vctxt == NULL) 27579 return; 27580 if (vctxt->filename != NULL) 27581 xmlFree(vctxt->filename); 27582 if (filename != NULL) 27583 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename); 27584 else 27585 vctxt->filename = NULL; 27586 } 27587 27588 /** 27589 * xmlSchemaClearValidCtxt: 27590 * @vctxt: the schema validation context 27591 * 27592 * Free the resources associated to the schema validation context; 27593 * leaves some fields alive intended for reuse of the context. 27594 */ 27595 static void 27596 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27597 { 27598 if (vctxt == NULL) 27599 return; 27600 27601 /* 27602 * TODO: Should we clear the flags? 27603 * Might be problematic if one reuses the context 27604 * and assumes that the options remain the same. 27605 */ 27606 vctxt->flags = 0; 27607 vctxt->validationRoot = NULL; 27608 vctxt->doc = NULL; 27609 #ifdef LIBXML_READER_ENABLED 27610 vctxt->reader = NULL; 27611 #endif 27612 vctxt->hasKeyrefs = 0; 27613 27614 if (vctxt->value != NULL) { 27615 xmlSchemaFreeValue(vctxt->value); 27616 vctxt->value = NULL; 27617 } 27618 /* 27619 * Augmented IDC information. 27620 */ 27621 if (vctxt->aidcs != NULL) { 27622 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27623 do { 27624 next = cur->next; 27625 xmlFree(cur); 27626 cur = next; 27627 } while (cur != NULL); 27628 vctxt->aidcs = NULL; 27629 } 27630 if (vctxt->idcMatcherCache != NULL) { 27631 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27632 27633 while (matcher) { 27634 tmp = matcher; 27635 matcher = matcher->nextCached; 27636 xmlSchemaIDCFreeMatcherList(tmp); 27637 } 27638 vctxt->idcMatcherCache = NULL; 27639 } 27640 27641 27642 if (vctxt->idcNodes != NULL) { 27643 int i; 27644 xmlSchemaPSVIIDCNodePtr item; 27645 27646 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27647 item = vctxt->idcNodes[i]; 27648 xmlFree(item->keys); 27649 xmlFree(item); 27650 } 27651 xmlFree(vctxt->idcNodes); 27652 vctxt->idcNodes = NULL; 27653 vctxt->nbIdcNodes = 0; 27654 vctxt->sizeIdcNodes = 0; 27655 } 27656 /* 27657 * Note that we won't delete the XPath state pool here. 27658 */ 27659 if (vctxt->xpathStates != NULL) { 27660 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27661 vctxt->xpathStates = NULL; 27662 } 27663 /* 27664 * Attribute info. 27665 */ 27666 if (vctxt->nbAttrInfos != 0) { 27667 xmlSchemaClearAttrInfos(vctxt); 27668 } 27669 /* 27670 * Element info. 27671 */ 27672 if (vctxt->elemInfos != NULL) { 27673 int i; 27674 xmlSchemaNodeInfoPtr ei; 27675 27676 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27677 ei = vctxt->elemInfos[i]; 27678 if (ei == NULL) 27679 break; 27680 xmlSchemaClearElemInfo(vctxt, ei); 27681 } 27682 } 27683 xmlSchemaItemListClear(vctxt->nodeQNames); 27684 /* Recreate the dict. */ 27685 xmlDictFree(vctxt->dict); 27686 /* 27687 * TODO: Is is save to recreate it? Do we have a scenario 27688 * where the user provides the dict? 27689 */ 27690 vctxt->dict = xmlDictCreate(); 27691 27692 if (vctxt->filename != NULL) { 27693 xmlFree(vctxt->filename); 27694 vctxt->filename = NULL; 27695 } 27696 } 27697 27698 /** 27699 * xmlSchemaFreeValidCtxt: 27700 * @ctxt: the schema validation context 27701 * 27702 * Free the resources associated to the schema validation context 27703 */ 27704 void 27705 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27706 { 27707 if (ctxt == NULL) 27708 return; 27709 if (ctxt->value != NULL) 27710 xmlSchemaFreeValue(ctxt->value); 27711 if (ctxt->pctxt != NULL) 27712 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27713 if (ctxt->idcNodes != NULL) { 27714 int i; 27715 xmlSchemaPSVIIDCNodePtr item; 27716 27717 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27718 item = ctxt->idcNodes[i]; 27719 xmlFree(item->keys); 27720 xmlFree(item); 27721 } 27722 xmlFree(ctxt->idcNodes); 27723 } 27724 if (ctxt->idcKeys != NULL) { 27725 int i; 27726 for (i = 0; i < ctxt->nbIdcKeys; i++) 27727 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27728 xmlFree(ctxt->idcKeys); 27729 } 27730 27731 if (ctxt->xpathStates != NULL) { 27732 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27733 ctxt->xpathStates = NULL; 27734 } 27735 if (ctxt->xpathStatePool != NULL) { 27736 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27737 ctxt->xpathStatePool = NULL; 27738 } 27739 27740 /* 27741 * Augmented IDC information. 27742 */ 27743 if (ctxt->aidcs != NULL) { 27744 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27745 do { 27746 next = cur->next; 27747 xmlFree(cur); 27748 cur = next; 27749 } while (cur != NULL); 27750 } 27751 if (ctxt->attrInfos != NULL) { 27752 int i; 27753 xmlSchemaAttrInfoPtr attr; 27754 27755 /* Just a paranoid call to the cleanup. */ 27756 if (ctxt->nbAttrInfos != 0) 27757 xmlSchemaClearAttrInfos(ctxt); 27758 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27759 attr = ctxt->attrInfos[i]; 27760 xmlFree(attr); 27761 } 27762 xmlFree(ctxt->attrInfos); 27763 } 27764 if (ctxt->elemInfos != NULL) { 27765 int i; 27766 xmlSchemaNodeInfoPtr ei; 27767 27768 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27769 ei = ctxt->elemInfos[i]; 27770 if (ei == NULL) 27771 break; 27772 xmlSchemaClearElemInfo(ctxt, ei); 27773 xmlFree(ei); 27774 } 27775 xmlFree(ctxt->elemInfos); 27776 } 27777 if (ctxt->nodeQNames != NULL) 27778 xmlSchemaItemListFree(ctxt->nodeQNames); 27779 if (ctxt->dict != NULL) 27780 xmlDictFree(ctxt->dict); 27781 if (ctxt->filename != NULL) 27782 xmlFree(ctxt->filename); 27783 xmlFree(ctxt); 27784 } 27785 27786 /** 27787 * xmlSchemaIsValid: 27788 * @ctxt: the schema validation context 27789 * 27790 * Check if any error was detected during validation. 27791 * 27792 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27793 * of internal error. 27794 */ 27795 int 27796 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27797 { 27798 if (ctxt == NULL) 27799 return(-1); 27800 return(ctxt->err == 0); 27801 } 27802 27803 /** 27804 * xmlSchemaSetValidErrors: 27805 * @ctxt: a schema validation context 27806 * @err: the error function 27807 * @warn: the warning function 27808 * @ctx: the functions context 27809 * 27810 * Set the error and warning callback informations 27811 */ 27812 void 27813 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27814 xmlSchemaValidityErrorFunc err, 27815 xmlSchemaValidityWarningFunc warn, void *ctx) 27816 { 27817 if (ctxt == NULL) 27818 return; 27819 ctxt->error = err; 27820 ctxt->warning = warn; 27821 ctxt->errCtxt = ctx; 27822 if (ctxt->pctxt != NULL) 27823 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27824 } 27825 27826 /** 27827 * xmlSchemaSetValidStructuredErrors: 27828 * @ctxt: a schema validation context 27829 * @serror: the structured error function 27830 * @ctx: the functions context 27831 * 27832 * Set the structured error callback 27833 */ 27834 void 27835 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27836 xmlStructuredErrorFunc serror, void *ctx) 27837 { 27838 if (ctxt == NULL) 27839 return; 27840 ctxt->serror = serror; 27841 ctxt->error = NULL; 27842 ctxt->warning = NULL; 27843 ctxt->errCtxt = ctx; 27844 if (ctxt->pctxt != NULL) 27845 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27846 } 27847 27848 /** 27849 * xmlSchemaGetValidErrors: 27850 * @ctxt: a XML-Schema validation context 27851 * @err: the error function result 27852 * @warn: the warning function result 27853 * @ctx: the functions context result 27854 * 27855 * Get the error and warning callback informations 27856 * 27857 * Returns -1 in case of error and 0 otherwise 27858 */ 27859 int 27860 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27861 xmlSchemaValidityErrorFunc * err, 27862 xmlSchemaValidityWarningFunc * warn, void **ctx) 27863 { 27864 if (ctxt == NULL) 27865 return (-1); 27866 if (err != NULL) 27867 *err = ctxt->error; 27868 if (warn != NULL) 27869 *warn = ctxt->warning; 27870 if (ctx != NULL) 27871 *ctx = ctxt->errCtxt; 27872 return (0); 27873 } 27874 27875 27876 /** 27877 * xmlSchemaSetValidOptions: 27878 * @ctxt: a schema validation context 27879 * @options: a combination of xmlSchemaValidOption 27880 * 27881 * Sets the options to be used during the validation. 27882 * 27883 * Returns 0 in case of success, -1 in case of an 27884 * API error. 27885 */ 27886 int 27887 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27888 int options) 27889 27890 { 27891 int i; 27892 27893 if (ctxt == NULL) 27894 return (-1); 27895 /* 27896 * WARNING: Change the start value if adding to the 27897 * xmlSchemaValidOption. 27898 * TODO: Is there an other, more easy to maintain, 27899 * way? 27900 */ 27901 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27902 if (options & 1<<i) 27903 return (-1); 27904 } 27905 ctxt->options = options; 27906 return (0); 27907 } 27908 27909 /** 27910 * xmlSchemaValidCtxtGetOptions: 27911 * @ctxt: a schema validation context 27912 * 27913 * Get the validation context options. 27914 * 27915 * Returns the option combination or -1 on error. 27916 */ 27917 int 27918 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27919 27920 { 27921 if (ctxt == NULL) 27922 return (-1); 27923 else 27924 return (ctxt->options); 27925 } 27926 27927 static int 27928 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27929 { 27930 xmlAttrPtr attr; 27931 int ret = 0; 27932 xmlSchemaNodeInfoPtr ielem = NULL; 27933 xmlNodePtr node, valRoot; 27934 const xmlChar *nsName; 27935 27936 /* DOC VAL TODO: Move this to the start function. */ 27937 if (vctxt->validationRoot != NULL) 27938 valRoot = vctxt->validationRoot; 27939 else 27940 valRoot = xmlDocGetRootElement(vctxt->doc); 27941 if (valRoot == NULL) { 27942 /* VAL TODO: Error code? */ 27943 VERROR(1, NULL, "The document has no document element"); 27944 return (1); 27945 } 27946 vctxt->depth = -1; 27947 vctxt->validationRoot = valRoot; 27948 node = valRoot; 27949 while (node != NULL) { 27950 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27951 goto next_sibling; 27952 if (node->type == XML_ELEMENT_NODE) { 27953 27954 /* 27955 * Init the node-info. 27956 */ 27957 vctxt->depth++; 27958 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27959 goto internal_error; 27960 ielem = vctxt->inode; 27961 ielem->node = node; 27962 ielem->nodeLine = node->line; 27963 ielem->localName = node->name; 27964 if (node->ns != NULL) 27965 ielem->nsName = node->ns->href; 27966 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27967 /* 27968 * Register attributes. 27969 * DOC VAL TODO: We do not register namespace declaration 27970 * attributes yet. 27971 */ 27972 vctxt->nbAttrInfos = 0; 27973 if (node->properties != NULL) { 27974 attr = node->properties; 27975 do { 27976 if (attr->ns != NULL) 27977 nsName = attr->ns->href; 27978 else 27979 nsName = NULL; 27980 ret = xmlSchemaValidatorPushAttribute(vctxt, 27981 (xmlNodePtr) attr, 27982 /* 27983 * Note that we give it the line number of the 27984 * parent element. 27985 */ 27986 ielem->nodeLine, 27987 attr->name, nsName, 0, 27988 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27989 if (ret == -1) { 27990 VERROR_INT("xmlSchemaDocWalk", 27991 "calling xmlSchemaValidatorPushAttribute()"); 27992 goto internal_error; 27993 } 27994 attr = attr->next; 27995 } while (attr); 27996 } 27997 /* 27998 * Validate the element. 27999 */ 28000 ret = xmlSchemaValidateElem(vctxt); 28001 if (ret != 0) { 28002 if (ret == -1) { 28003 VERROR_INT("xmlSchemaDocWalk", 28004 "calling xmlSchemaValidateElem()"); 28005 goto internal_error; 28006 } 28007 /* 28008 * Don't stop validation; just skip the content 28009 * of this element. 28010 */ 28011 goto leave_node; 28012 } 28013 if ((vctxt->skipDepth != -1) && 28014 (vctxt->depth >= vctxt->skipDepth)) 28015 goto leave_node; 28016 } else if ((node->type == XML_TEXT_NODE) || 28017 (node->type == XML_CDATA_SECTION_NODE)) { 28018 /* 28019 * Process character content. 28020 */ 28021 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 28022 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 28023 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 28024 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 28025 if (ret < 0) { 28026 VERROR_INT("xmlSchemaVDocWalk", 28027 "calling xmlSchemaVPushText()"); 28028 goto internal_error; 28029 } 28030 /* 28031 * DOC VAL TODO: Should we skip further validation of the 28032 * element content here? 28033 */ 28034 } else if ((node->type == XML_ENTITY_NODE) || 28035 (node->type == XML_ENTITY_REF_NODE)) { 28036 /* 28037 * DOC VAL TODO: What to do with entities? 28038 */ 28039 VERROR_INT("xmlSchemaVDocWalk", 28040 "there is at least one entity reference in the node-tree " 28041 "currently being validated. Processing of entities with " 28042 "this XML Schema processor is not supported (yet). Please " 28043 "substitute entities before validation."); 28044 goto internal_error; 28045 } else { 28046 goto leave_node; 28047 /* 28048 * DOC VAL TODO: XInclude nodes, etc. 28049 */ 28050 } 28051 /* 28052 * Walk the doc. 28053 */ 28054 if (node->children != NULL) { 28055 node = node->children; 28056 continue; 28057 } 28058 leave_node: 28059 if (node->type == XML_ELEMENT_NODE) { 28060 /* 28061 * Leaving the scope of an element. 28062 */ 28063 if (node != vctxt->inode->node) { 28064 VERROR_INT("xmlSchemaVDocWalk", 28065 "element position mismatch"); 28066 goto internal_error; 28067 } 28068 ret = xmlSchemaValidatorPopElem(vctxt); 28069 if (ret != 0) { 28070 if (ret < 0) { 28071 VERROR_INT("xmlSchemaVDocWalk", 28072 "calling xmlSchemaValidatorPopElem()"); 28073 goto internal_error; 28074 } 28075 } 28076 if (node == valRoot) 28077 goto exit; 28078 } 28079 next_sibling: 28080 if (node->next != NULL) 28081 node = node->next; 28082 else { 28083 node = node->parent; 28084 goto leave_node; 28085 } 28086 } 28087 28088 exit: 28089 return (ret); 28090 internal_error: 28091 return (-1); 28092 } 28093 28094 static int 28095 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 28096 /* 28097 * Some initialization. 28098 */ 28099 vctxt->err = 0; 28100 vctxt->nberrors = 0; 28101 vctxt->depth = -1; 28102 vctxt->skipDepth = -1; 28103 vctxt->xsiAssemble = 0; 28104 vctxt->hasKeyrefs = 0; 28105 #ifdef ENABLE_IDC_NODE_TABLES_TEST 28106 vctxt->createIDCNodeTables = 1; 28107 #else 28108 vctxt->createIDCNodeTables = 0; 28109 #endif 28110 /* 28111 * Create a schema + parser if necessary. 28112 */ 28113 if (vctxt->schema == NULL) { 28114 xmlSchemaParserCtxtPtr pctxt; 28115 28116 vctxt->xsiAssemble = 1; 28117 /* 28118 * If not schema was given then we will create a schema 28119 * dynamically using XSI schema locations. 28120 * 28121 * Create the schema parser context. 28122 */ 28123 if ((vctxt->pctxt == NULL) && 28124 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 28125 return (-1); 28126 pctxt = vctxt->pctxt; 28127 pctxt->xsiAssemble = 1; 28128 /* 28129 * Create the schema. 28130 */ 28131 vctxt->schema = xmlSchemaNewSchema(pctxt); 28132 if (vctxt->schema == NULL) 28133 return (-1); 28134 /* 28135 * Create the schema construction context. 28136 */ 28137 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 28138 if (pctxt->constructor == NULL) 28139 return(-1); 28140 pctxt->constructor->mainSchema = vctxt->schema; 28141 /* 28142 * Take ownership of the constructor to be able to free it. 28143 */ 28144 pctxt->ownsConstructor = 1; 28145 } 28146 /* 28147 * Augment the IDC definitions for the main schema and all imported ones 28148 * NOTE: main schema if the first in the imported list 28149 */ 28150 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, 28151 vctxt); 28152 28153 return(0); 28154 } 28155 28156 static void 28157 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28158 if (vctxt->xsiAssemble) { 28159 if (vctxt->schema != NULL) { 28160 xmlSchemaFree(vctxt->schema); 28161 vctxt->schema = NULL; 28162 } 28163 } 28164 xmlSchemaClearValidCtxt(vctxt); 28165 } 28166 28167 static int 28168 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28169 { 28170 int ret = 0; 28171 28172 if (xmlSchemaPreRun(vctxt) < 0) 28173 return(-1); 28174 28175 if (vctxt->doc != NULL) { 28176 /* 28177 * Tree validation. 28178 */ 28179 ret = xmlSchemaVDocWalk(vctxt); 28180 #ifdef LIBXML_READER_ENABLED 28181 } else if (vctxt->reader != NULL) { 28182 /* 28183 * XML Reader validation. 28184 */ 28185 #ifdef XML_SCHEMA_READER_ENABLED 28186 ret = xmlSchemaVReaderWalk(vctxt); 28187 #endif 28188 #endif 28189 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28190 /* 28191 * SAX validation. 28192 */ 28193 ret = xmlParseDocument(vctxt->parserCtxt); 28194 } else { 28195 VERROR_INT("xmlSchemaVStart", 28196 "no instance to validate"); 28197 ret = -1; 28198 } 28199 28200 xmlSchemaPostRun(vctxt); 28201 if (ret == 0) 28202 ret = vctxt->err; 28203 return (ret); 28204 } 28205 28206 /** 28207 * xmlSchemaValidateOneElement: 28208 * @ctxt: a schema validation context 28209 * @elem: an element node 28210 * 28211 * Validate a branch of a tree, starting with the given @elem. 28212 * 28213 * Returns 0 if the element and its subtree is valid, a positive error 28214 * code number otherwise and -1 in case of an internal or API error. 28215 */ 28216 int 28217 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28218 { 28219 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28220 return (-1); 28221 28222 if (ctxt->schema == NULL) 28223 return (-1); 28224 28225 ctxt->doc = elem->doc; 28226 ctxt->node = elem; 28227 ctxt->validationRoot = elem; 28228 return(xmlSchemaVStart(ctxt)); 28229 } 28230 28231 /** 28232 * xmlSchemaValidateDoc: 28233 * @ctxt: a schema validation context 28234 * @doc: a parsed document tree 28235 * 28236 * Validate a document tree in memory. 28237 * 28238 * Returns 0 if the document is schemas valid, a positive error code 28239 * number otherwise and -1 in case of internal or API error. 28240 */ 28241 int 28242 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28243 { 28244 if ((ctxt == NULL) || (doc == NULL)) 28245 return (-1); 28246 28247 ctxt->doc = doc; 28248 ctxt->node = xmlDocGetRootElement(doc); 28249 if (ctxt->node == NULL) { 28250 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28251 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28252 (xmlNodePtr) doc, NULL, 28253 "The document has no document element", NULL, NULL); 28254 return (ctxt->err); 28255 } 28256 ctxt->validationRoot = ctxt->node; 28257 return (xmlSchemaVStart(ctxt)); 28258 } 28259 28260 28261 /************************************************************************ 28262 * * 28263 * Function and data for SAX streaming API * 28264 * * 28265 ************************************************************************/ 28266 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28267 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28268 28269 struct _xmlSchemaSplitSAXData { 28270 xmlSAXHandlerPtr user_sax; 28271 void *user_data; 28272 xmlSchemaValidCtxtPtr ctxt; 28273 xmlSAXHandlerPtr schemas_sax; 28274 }; 28275 28276 #define XML_SAX_PLUG_MAGIC 0xdc43ba21 28277 28278 struct _xmlSchemaSAXPlug { 28279 unsigned int magic; 28280 28281 /* the original callbacks informations */ 28282 xmlSAXHandlerPtr *user_sax_ptr; 28283 xmlSAXHandlerPtr user_sax; 28284 void **user_data_ptr; 28285 void *user_data; 28286 28287 /* the block plugged back and validation informations */ 28288 xmlSAXHandler schemas_sax; 28289 xmlSchemaValidCtxtPtr ctxt; 28290 }; 28291 28292 /* All those functions just bounces to the user provided SAX handlers */ 28293 static void 28294 internalSubsetSplit(void *ctx, const xmlChar *name, 28295 const xmlChar *ExternalID, const xmlChar *SystemID) 28296 { 28297 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28298 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28299 (ctxt->user_sax->internalSubset != NULL)) 28300 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28301 SystemID); 28302 } 28303 28304 static int 28305 isStandaloneSplit(void *ctx) 28306 { 28307 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28308 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28309 (ctxt->user_sax->isStandalone != NULL)) 28310 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28311 return(0); 28312 } 28313 28314 static int 28315 hasInternalSubsetSplit(void *ctx) 28316 { 28317 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28318 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28319 (ctxt->user_sax->hasInternalSubset != NULL)) 28320 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28321 return(0); 28322 } 28323 28324 static int 28325 hasExternalSubsetSplit(void *ctx) 28326 { 28327 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28328 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28329 (ctxt->user_sax->hasExternalSubset != NULL)) 28330 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28331 return(0); 28332 } 28333 28334 static void 28335 externalSubsetSplit(void *ctx, const xmlChar *name, 28336 const xmlChar *ExternalID, const xmlChar *SystemID) 28337 { 28338 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28339 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28340 (ctxt->user_sax->externalSubset != NULL)) 28341 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28342 SystemID); 28343 } 28344 28345 static xmlParserInputPtr 28346 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28347 { 28348 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28349 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28350 (ctxt->user_sax->resolveEntity != NULL)) 28351 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28352 systemId)); 28353 return(NULL); 28354 } 28355 28356 static xmlEntityPtr 28357 getEntitySplit(void *ctx, const xmlChar *name) 28358 { 28359 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28360 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28361 (ctxt->user_sax->getEntity != NULL)) 28362 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28363 return(NULL); 28364 } 28365 28366 static xmlEntityPtr 28367 getParameterEntitySplit(void *ctx, const xmlChar *name) 28368 { 28369 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28370 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28371 (ctxt->user_sax->getParameterEntity != NULL)) 28372 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28373 return(NULL); 28374 } 28375 28376 28377 static void 28378 entityDeclSplit(void *ctx, const xmlChar *name, int type, 28379 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28380 { 28381 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28382 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28383 (ctxt->user_sax->entityDecl != NULL)) 28384 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28385 systemId, content); 28386 } 28387 28388 static void 28389 attributeDeclSplit(void *ctx, const xmlChar * elem, 28390 const xmlChar * name, int type, int def, 28391 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28392 { 28393 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28394 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28395 (ctxt->user_sax->attributeDecl != NULL)) { 28396 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28397 def, defaultValue, tree); 28398 } else { 28399 xmlFreeEnumeration(tree); 28400 } 28401 } 28402 28403 static void 28404 elementDeclSplit(void *ctx, const xmlChar *name, int type, 28405 xmlElementContentPtr content) 28406 { 28407 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28408 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28409 (ctxt->user_sax->elementDecl != NULL)) 28410 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28411 } 28412 28413 static void 28414 notationDeclSplit(void *ctx, const xmlChar *name, 28415 const xmlChar *publicId, const xmlChar *systemId) 28416 { 28417 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28418 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28419 (ctxt->user_sax->notationDecl != NULL)) 28420 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28421 systemId); 28422 } 28423 28424 static void 28425 unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28426 const xmlChar *publicId, const xmlChar *systemId, 28427 const xmlChar *notationName) 28428 { 28429 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28430 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28431 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28432 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28433 systemId, notationName); 28434 } 28435 28436 static void 28437 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28438 { 28439 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28440 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28441 (ctxt->user_sax->setDocumentLocator != NULL)) 28442 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28443 } 28444 28445 static void 28446 startDocumentSplit(void *ctx) 28447 { 28448 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28449 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28450 (ctxt->user_sax->startDocument != NULL)) 28451 ctxt->user_sax->startDocument(ctxt->user_data); 28452 } 28453 28454 static void 28455 endDocumentSplit(void *ctx) 28456 { 28457 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28458 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28459 (ctxt->user_sax->endDocument != NULL)) 28460 ctxt->user_sax->endDocument(ctxt->user_data); 28461 } 28462 28463 static void 28464 processingInstructionSplit(void *ctx, const xmlChar *target, 28465 const xmlChar *data) 28466 { 28467 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28468 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28469 (ctxt->user_sax->processingInstruction != NULL)) 28470 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28471 } 28472 28473 static void 28474 commentSplit(void *ctx, const xmlChar *value) 28475 { 28476 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28477 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28478 (ctxt->user_sax->comment != NULL)) 28479 ctxt->user_sax->comment(ctxt->user_data, value); 28480 } 28481 28482 /* 28483 * Varargs error callbacks to the user application, harder ... 28484 */ 28485 28486 static void XMLCDECL 28487 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28488 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28489 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28490 (ctxt->user_sax->warning != NULL)) { 28491 TODO 28492 } 28493 } 28494 static void XMLCDECL 28495 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28496 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28497 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28498 (ctxt->user_sax->error != NULL)) { 28499 TODO 28500 } 28501 } 28502 static void XMLCDECL 28503 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28504 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28505 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28506 (ctxt->user_sax->fatalError != NULL)) { 28507 TODO 28508 } 28509 } 28510 28511 /* 28512 * Those are function where both the user handler and the schemas handler 28513 * need to be called. 28514 */ 28515 static void 28516 charactersSplit(void *ctx, const xmlChar *ch, int len) 28517 { 28518 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28519 if (ctxt == NULL) 28520 return; 28521 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28522 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28523 if (ctxt->ctxt != NULL) 28524 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28525 } 28526 28527 static void 28528 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28529 { 28530 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28531 if (ctxt == NULL) 28532 return; 28533 if ((ctxt->user_sax != NULL) && 28534 (ctxt->user_sax->ignorableWhitespace != NULL)) 28535 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28536 if (ctxt->ctxt != NULL) 28537 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28538 } 28539 28540 static void 28541 cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28542 { 28543 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28544 if (ctxt == NULL) 28545 return; 28546 if ((ctxt->user_sax != NULL) && 28547 (ctxt->user_sax->cdataBlock != NULL)) 28548 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28549 if (ctxt->ctxt != NULL) 28550 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28551 } 28552 28553 static void 28554 referenceSplit(void *ctx, const xmlChar *name) 28555 { 28556 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28557 if (ctxt == NULL) 28558 return; 28559 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28560 (ctxt->user_sax->reference != NULL)) 28561 ctxt->user_sax->reference(ctxt->user_data, name); 28562 if (ctxt->ctxt != NULL) 28563 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28564 } 28565 28566 static void 28567 startElementNsSplit(void *ctx, const xmlChar * localname, 28568 const xmlChar * prefix, const xmlChar * URI, 28569 int nb_namespaces, const xmlChar ** namespaces, 28570 int nb_attributes, int nb_defaulted, 28571 const xmlChar ** attributes) { 28572 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28573 if (ctxt == NULL) 28574 return; 28575 if ((ctxt->user_sax != NULL) && 28576 (ctxt->user_sax->startElementNs != NULL)) 28577 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28578 URI, nb_namespaces, namespaces, 28579 nb_attributes, nb_defaulted, 28580 attributes); 28581 if (ctxt->ctxt != NULL) 28582 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28583 URI, nb_namespaces, namespaces, 28584 nb_attributes, nb_defaulted, 28585 attributes); 28586 } 28587 28588 static void 28589 endElementNsSplit(void *ctx, const xmlChar * localname, 28590 const xmlChar * prefix, const xmlChar * URI) { 28591 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28592 if (ctxt == NULL) 28593 return; 28594 if ((ctxt->user_sax != NULL) && 28595 (ctxt->user_sax->endElementNs != NULL)) 28596 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28597 if (ctxt->ctxt != NULL) 28598 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28599 } 28600 28601 /** 28602 * xmlSchemaSAXPlug: 28603 * @ctxt: a schema validation context 28604 * @sax: a pointer to the original xmlSAXHandlerPtr 28605 * @user_data: a pointer to the original SAX user data pointer 28606 * 28607 * Plug a SAX based validation layer in a SAX parsing event flow. 28608 * The original @saxptr and @dataptr data are replaced by new pointers 28609 * but the calls to the original will be maintained. 28610 * 28611 * Returns a pointer to a data structure needed to unplug the validation layer 28612 * or NULL in case of errors. 28613 */ 28614 xmlSchemaSAXPlugPtr 28615 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28616 xmlSAXHandlerPtr *sax, void **user_data) 28617 { 28618 xmlSchemaSAXPlugPtr ret; 28619 xmlSAXHandlerPtr old_sax; 28620 28621 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28622 return(NULL); 28623 28624 /* 28625 * We only allow to plug into SAX2 event streams 28626 */ 28627 old_sax = *sax; 28628 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28629 return(NULL); 28630 if ((old_sax != NULL) && 28631 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28632 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28633 return(NULL); 28634 28635 /* 28636 * everything seems right allocate the local data needed for that layer 28637 */ 28638 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28639 if (ret == NULL) { 28640 return(NULL); 28641 } 28642 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28643 ret->magic = XML_SAX_PLUG_MAGIC; 28644 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28645 ret->ctxt = ctxt; 28646 ret->user_sax_ptr = sax; 28647 ret->user_sax = old_sax; 28648 if (old_sax == NULL) { 28649 /* 28650 * go direct, no need for the split block and functions. 28651 */ 28652 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28653 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28654 /* 28655 * Note that we use the same text-function for both, to prevent 28656 * the parser from testing for ignorable whitespace. 28657 */ 28658 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28659 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28660 28661 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28662 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28663 28664 ret->user_data = ctxt; 28665 *user_data = ctxt; 28666 } else { 28667 /* 28668 * for each callback unused by Schemas initialize it to the Split 28669 * routine only if non NULL in the user block, this can speed up 28670 * things at the SAX level. 28671 */ 28672 if (old_sax->internalSubset != NULL) 28673 ret->schemas_sax.internalSubset = internalSubsetSplit; 28674 if (old_sax->isStandalone != NULL) 28675 ret->schemas_sax.isStandalone = isStandaloneSplit; 28676 if (old_sax->hasInternalSubset != NULL) 28677 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28678 if (old_sax->hasExternalSubset != NULL) 28679 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28680 if (old_sax->resolveEntity != NULL) 28681 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28682 if (old_sax->getEntity != NULL) 28683 ret->schemas_sax.getEntity = getEntitySplit; 28684 if (old_sax->entityDecl != NULL) 28685 ret->schemas_sax.entityDecl = entityDeclSplit; 28686 if (old_sax->notationDecl != NULL) 28687 ret->schemas_sax.notationDecl = notationDeclSplit; 28688 if (old_sax->attributeDecl != NULL) 28689 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28690 if (old_sax->elementDecl != NULL) 28691 ret->schemas_sax.elementDecl = elementDeclSplit; 28692 if (old_sax->unparsedEntityDecl != NULL) 28693 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28694 if (old_sax->setDocumentLocator != NULL) 28695 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28696 if (old_sax->startDocument != NULL) 28697 ret->schemas_sax.startDocument = startDocumentSplit; 28698 if (old_sax->endDocument != NULL) 28699 ret->schemas_sax.endDocument = endDocumentSplit; 28700 if (old_sax->processingInstruction != NULL) 28701 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28702 if (old_sax->comment != NULL) 28703 ret->schemas_sax.comment = commentSplit; 28704 if (old_sax->warning != NULL) 28705 ret->schemas_sax.warning = warningSplit; 28706 if (old_sax->error != NULL) 28707 ret->schemas_sax.error = errorSplit; 28708 if (old_sax->fatalError != NULL) 28709 ret->schemas_sax.fatalError = fatalErrorSplit; 28710 if (old_sax->getParameterEntity != NULL) 28711 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28712 if (old_sax->externalSubset != NULL) 28713 ret->schemas_sax.externalSubset = externalSubsetSplit; 28714 28715 /* 28716 * the 6 schemas callback have to go to the splitter functions 28717 * Note that we use the same text-function for ignorableWhitespace 28718 * if possible, to prevent the parser from testing for ignorable 28719 * whitespace. 28720 */ 28721 ret->schemas_sax.characters = charactersSplit; 28722 if ((old_sax->ignorableWhitespace != NULL) && 28723 (old_sax->ignorableWhitespace != old_sax->characters)) 28724 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28725 else 28726 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28727 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28728 ret->schemas_sax.reference = referenceSplit; 28729 ret->schemas_sax.startElementNs = startElementNsSplit; 28730 ret->schemas_sax.endElementNs = endElementNsSplit; 28731 28732 ret->user_data_ptr = user_data; 28733 ret->user_data = *user_data; 28734 *user_data = ret; 28735 } 28736 28737 /* 28738 * plug the pointers back. 28739 */ 28740 *sax = &(ret->schemas_sax); 28741 ctxt->sax = *sax; 28742 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28743 xmlSchemaPreRun(ctxt); 28744 return(ret); 28745 } 28746 28747 /** 28748 * xmlSchemaSAXUnplug: 28749 * @plug: a data structure returned by xmlSchemaSAXPlug 28750 * 28751 * Unplug a SAX based validation layer in a SAX parsing event flow. 28752 * The original pointers used in the call are restored. 28753 * 28754 * Returns 0 in case of success and -1 in case of failure. 28755 */ 28756 int 28757 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28758 { 28759 xmlSAXHandlerPtr *sax; 28760 void **user_data; 28761 28762 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28763 return(-1); 28764 plug->magic = 0; 28765 28766 xmlSchemaPostRun(plug->ctxt); 28767 /* restore the data */ 28768 sax = plug->user_sax_ptr; 28769 *sax = plug->user_sax; 28770 if (plug->user_sax != NULL) { 28771 user_data = plug->user_data_ptr; 28772 *user_data = plug->user_data; 28773 } 28774 28775 /* free and return */ 28776 xmlFree(plug); 28777 return(0); 28778 } 28779 28780 /** 28781 * xmlSchemaValidateSetLocator: 28782 * @vctxt: a schema validation context 28783 * @f: the locator function pointer 28784 * @ctxt: the locator context 28785 * 28786 * Allows to set a locator function to the validation context, 28787 * which will be used to provide file and line information since 28788 * those are not provided as part of the SAX validation flow 28789 * Setting @f to NULL disable the locator. 28790 */ 28791 28792 void 28793 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt, 28794 xmlSchemaValidityLocatorFunc f, 28795 void *ctxt) 28796 { 28797 if (vctxt == NULL) return; 28798 vctxt->locFunc = f; 28799 vctxt->locCtxt = ctxt; 28800 } 28801 28802 /** 28803 * xmlSchemaValidateStreamLocator: 28804 * @ctx: the xmlTextReaderPtr used 28805 * @file: returned file information 28806 * @line: returned line information 28807 * 28808 * Internal locator function for the readers 28809 * 28810 * Returns 0 in case the Schema validation could be (des)activated and 28811 * -1 in case of error. 28812 */ 28813 static int 28814 xmlSchemaValidateStreamLocator(void *ctx, const char **file, 28815 unsigned long *line) { 28816 xmlParserCtxtPtr ctxt; 28817 28818 if ((ctx == NULL) || ((file == NULL) && (line == NULL))) 28819 return(-1); 28820 28821 if (file != NULL) 28822 *file = NULL; 28823 if (line != NULL) 28824 *line = 0; 28825 28826 ctxt = (xmlParserCtxtPtr) ctx; 28827 if (ctxt->input != NULL) { 28828 if (file != NULL) 28829 *file = ctxt->input->filename; 28830 if (line != NULL) 28831 *line = ctxt->input->line; 28832 return(0); 28833 } 28834 return(-1); 28835 } 28836 28837 /** 28838 * xmlSchemaValidateStream: 28839 * @ctxt: a schema validation context 28840 * @input: the input to use for reading the data 28841 * @enc: an optional encoding information 28842 * @sax: a SAX handler for the resulting events 28843 * @user_data: the context to provide to the SAX handler. 28844 * 28845 * Validate an input based on a flow of SAX event from the parser 28846 * and forward the events to the @sax handler with the provided @user_data 28847 * the user provided @sax handler must be a SAX2 one. 28848 * 28849 * Returns 0 if the document is schemas valid, a positive error code 28850 * number otherwise and -1 in case of internal or API error. 28851 */ 28852 int 28853 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28854 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28855 xmlSAXHandlerPtr sax, void *user_data) 28856 { 28857 xmlSchemaSAXPlugPtr plug = NULL; 28858 xmlSAXHandlerPtr old_sax = NULL; 28859 xmlParserCtxtPtr pctxt = NULL; 28860 xmlParserInputPtr inputStream = NULL; 28861 int ret; 28862 28863 if ((ctxt == NULL) || (input == NULL)) 28864 return (-1); 28865 28866 /* 28867 * prepare the parser 28868 */ 28869 pctxt = xmlNewParserCtxt(); 28870 if (pctxt == NULL) 28871 return (-1); 28872 old_sax = pctxt->sax; 28873 pctxt->sax = sax; 28874 pctxt->userData = user_data; 28875 #if 0 28876 if (options) 28877 xmlCtxtUseOptions(pctxt, options); 28878 #endif 28879 pctxt->linenumbers = 1; 28880 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt); 28881 28882 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28883 if (inputStream == NULL) { 28884 ret = -1; 28885 goto done; 28886 } 28887 inputPush(pctxt, inputStream); 28888 ctxt->parserCtxt = pctxt; 28889 ctxt->input = input; 28890 28891 /* 28892 * Plug the validation and launch the parsing 28893 */ 28894 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28895 if (plug == NULL) { 28896 ret = -1; 28897 goto done; 28898 } 28899 ctxt->input = input; 28900 ctxt->enc = enc; 28901 ctxt->sax = pctxt->sax; 28902 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28903 ret = xmlSchemaVStart(ctxt); 28904 28905 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28906 ret = ctxt->parserCtxt->errNo; 28907 if (ret == 0) 28908 ret = 1; 28909 } 28910 28911 done: 28912 ctxt->parserCtxt = NULL; 28913 ctxt->sax = NULL; 28914 ctxt->input = NULL; 28915 if (plug != NULL) { 28916 xmlSchemaSAXUnplug(plug); 28917 } 28918 /* cleanup */ 28919 if (pctxt != NULL) { 28920 pctxt->sax = old_sax; 28921 xmlFreeParserCtxt(pctxt); 28922 } 28923 return (ret); 28924 } 28925 28926 /** 28927 * xmlSchemaValidateFile: 28928 * @ctxt: a schema validation context 28929 * @filename: the URI of the instance 28930 * @options: a future set of options, currently unused 28931 * 28932 * Do a schemas validation of the given resource, it will use the 28933 * SAX streamable validation internally. 28934 * 28935 * Returns 0 if the document is valid, a positive error code 28936 * number otherwise and -1 in case of an internal or API error. 28937 */ 28938 int 28939 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28940 const char * filename, 28941 int options ATTRIBUTE_UNUSED) 28942 { 28943 int ret; 28944 xmlParserInputBufferPtr input; 28945 28946 if ((ctxt == NULL) || (filename == NULL)) 28947 return (-1); 28948 28949 input = xmlParserInputBufferCreateFilename(filename, 28950 XML_CHAR_ENCODING_NONE); 28951 if (input == NULL) 28952 return (-1); 28953 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28954 NULL, NULL); 28955 return (ret); 28956 } 28957 28958 /** 28959 * xmlSchemaValidCtxtGetParserCtxt: 28960 * @ctxt: a schema validation context 28961 * 28962 * allow access to the parser context of the schema validation context 28963 * 28964 * Returns the parser context of the schema validation context or NULL 28965 * in case of error. 28966 */ 28967 xmlParserCtxtPtr 28968 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28969 { 28970 if (ctxt == NULL) 28971 return(NULL); 28972 return (ctxt->parserCtxt); 28973 } 28974 28975 #define bottom_xmlschemas 28976 #include "elfgcchack.h" 28977 #endif /* LIBXML_SCHEMAS_ENABLED */ 28978