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@redhat.com> 8 */ 9 10/* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - if we don't intend to use the schema for schemas, we 16 * need to validate all schema attributes (ref, type, name) 17 * against their types. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47#define IN_LIBXML 48#include "libxml.h" 49 50#ifdef LIBXML_SCHEMAS_ENABLED 51 52#include <string.h> 53#include <libxml/xmlmemory.h> 54#include <libxml/parser.h> 55#include <libxml/parserInternals.h> 56#include <libxml/hash.h> 57#include <libxml/uri.h> 58#include <libxml/xmlschemas.h> 59#include <libxml/schemasInternals.h> 60#include <libxml/xmlschemastypes.h> 61#include <libxml/xmlautomata.h> 62#include <libxml/xmlregexp.h> 63#include <libxml/dict.h> 64#include <libxml/encoding.h> 65#include <libxml/xmlIO.h> 66#ifdef LIBXML_PATTERN_ENABLED 67#include <libxml/pattern.h> 68#endif 69#ifdef LIBXML_READER_ENABLED 70#include <libxml/xmlreader.h> 71#endif 72 73/* #define DEBUG 1 */ 74 75/* #define DEBUG_CONTENT 1 */ 76 77/* #define DEBUG_TYPE 1 */ 78 79/* #define DEBUG_CONTENT_REGEXP 1 */ 80 81/* #define DEBUG_AUTOMATA 1 */ 82 83/* #define DEBUG_IDC */ 84 85/* #define DEBUG_IDC_NODE_TABLE */ 86 87/* #define WXS_ELEM_DECL_CONS_ENABLED */ 88 89#ifdef DEBUG_IDC 90 #ifndef DEBUG_IDC_NODE_TABLE 91 #define DEBUG_IDC_NODE_TABLE 92 #endif 93#endif 94 95/* #define ENABLE_PARTICLE_RESTRICTION 1 */ 96 97#define ENABLE_REDEFINE 98 99/* #define ENABLE_NAMED_LOCALS */ 100 101/* #define ENABLE_IDC_NODE_TABLES_TEST */ 102 103#define DUMP_CONTENT_MODEL 104 105#ifdef LIBXML_READER_ENABLED 106/* #define XML_SCHEMA_READER_ENABLED */ 107#endif 108 109#define UNBOUNDED (1 << 30) 110#define TODO \ 111 xmlGenericError(xmlGenericErrorContext, \ 112 "Unimplemented block at %s:%d\n", \ 113 __FILE__, __LINE__); 114 115#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 116 117/* 118 * The XML Schemas namespaces 119 */ 120static const xmlChar *xmlSchemaNs = (const xmlChar *) 121 "http://www.w3.org/2001/XMLSchema"; 122 123static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 124 "http://www.w3.org/2001/XMLSchema-instance"; 125 126static const xmlChar *xmlNamespaceNs = (const xmlChar *) 127 "http://www.w3.org/2000/xmlns/"; 128 129/* 130* Come casting macros. 131*/ 132#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 133#define PCTXT_CAST (xmlSchemaParserCtxtPtr) 134#define VCTXT_CAST (xmlSchemaValidCtxtPtr) 135#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 136#define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 137#define WXS_PTC_CAST (xmlSchemaParticlePtr) 138#define WXS_TYPE_CAST (xmlSchemaTypePtr) 139#define WXS_ELEM_CAST (xmlSchemaElementPtr) 140#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 141#define WXS_ATTR_CAST (xmlSchemaAttributePtr) 142#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 143#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 144#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 145#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 146#define WXS_IDC_CAST (xmlSchemaIDCPtr) 147#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 148#define WXS_LIST_CAST (xmlSchemaItemListPtr) 149 150/* 151* Macros to query common properties of components. 152*/ 153#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 154 155#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 156/* 157* Macros for element declarations. 158*/ 159#define WXS_ELEM_TYPEDEF(e) (e)->subtypes 160 161#define WXS_SUBST_HEAD(item) (item)->refDecl 162/* 163* Macros for attribute declarations. 164*/ 165#define WXS_ATTR_TYPEDEF(a) (a)->subtypes 166/* 167* Macros for attribute uses. 168*/ 169#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 170 171#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 172 173#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 174 175#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 176/* 177* Macros for attribute groups. 178*/ 179#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 180#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 181/* 182* Macros for particles. 183*/ 184#define WXS_PARTICLE(p) WXS_PTC_CAST (p) 185 186#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 187 188#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 189 190#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 191/* 192* Macros for model groups definitions. 193*/ 194#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 195/* 196* Macros for model groups. 197*/ 198#define WXS_IS_MODEL_GROUP(i) \ 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 202 203#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 204/* 205* Macros for schema buckets. 206*/ 207#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 209 210#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 212 213#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 214 215#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 216/* 217* Macros for complex/simple types. 218*/ 219#define WXS_IS_ANYTYPE(i) \ 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 222 223#define WXS_IS_COMPLEX(i) \ 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 226 227#define WXS_IS_SIMPLE(item) \ 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 231 232#define WXS_IS_ANY_SIMPLE_TYPE(i) \ 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 235 236#define WXS_IS_RESTRICTION(t) \ 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 238 239#define WXS_IS_EXTENSION(t) \ 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 241 242#define WXS_IS_TYPE_NOT_FIXED(i) \ 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 245 246#define WXS_IS_TYPE_NOT_FIXED_1(item) \ 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 249 250#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 251 252#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 253/* 254* Macros for exclusively for complex types. 255*/ 256#define WXS_HAS_COMPLEX_CONTENT(item) \ 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 260 261#define WXS_HAS_SIMPLE_CONTENT(item) \ 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 264 265#define WXS_HAS_MIXED_CONTENT(item) \ 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 267 268#define WXS_EMPTIABLE(t) \ 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 270 271#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 272 273#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 274 275#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 276/* 277* Macros for exclusively for simple types. 278*/ 279#define WXS_LIST_ITEMTYPE(t) (t)->subtypes 280 281#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 282 283#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 284 285#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 286/* 287* Misc parser context macros. 288*/ 289#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 290 291#define WXS_HAS_BUCKETS(ctx) \ 292( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 293(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 294 295#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 296 297#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 298 299#define WXS_SCHEMA(ctx) (ctx)->schema 300 301#define WXS_ADD_LOCAL(ctx, item) \ 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 303 304#define WXS_ADD_GLOBAL(ctx, item) \ 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 306 307#define WXS_ADD_PENDING(ctx, item) \ 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 309/* 310* xmlSchemaItemList macros. 311*/ 312#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 313/* 314* Misc macros. 315*/ 316#define IS_SCHEMA(node, type) \ 317 ((node != NULL) && (node->ns != NULL) && \ 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 320 321#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 322 323/* 324* Since we put the default/fixed values into the dict, we can 325* use pointer comparison for those values. 326* REMOVED: (xmlStrEqual((v1), (v2))) 327*/ 328#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 329 330#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 331 332#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 333 334#define HFAILURE if (res == -1) goto exit_failure; 335 336#define HERROR if (res != 0) goto exit_error; 337 338#define HSTOP(ctx) if ((ctx)->stop) goto exit; 339/* 340* Some flags used for various schema constraints. 341*/ 342#define SUBSET_RESTRICTION 1<<0 343#define SUBSET_EXTENSION 1<<1 344#define SUBSET_SUBSTITUTION 1<<2 345#define SUBSET_LIST 1<<3 346#define SUBSET_UNION 1<<4 347 348typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 349typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 350 351typedef struct _xmlSchemaItemList xmlSchemaItemList; 352typedef xmlSchemaItemList *xmlSchemaItemListPtr; 353struct _xmlSchemaItemList { 354 void **items; /* used for dynamic addition of schemata */ 355 int nbItems; /* used for dynamic addition of schemata */ 356 int sizeItems; /* used for dynamic addition of schemata */ 357}; 358 359#define XML_SCHEMA_CTXT_PARSER 1 360#define XML_SCHEMA_CTXT_VALIDATOR 2 361 362typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 363typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 364struct _xmlSchemaAbstractCtxt { 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 366}; 367 368typedef struct _xmlSchemaBucket xmlSchemaBucket; 369typedef xmlSchemaBucket *xmlSchemaBucketPtr; 370 371#define XML_SCHEMA_SCHEMA_MAIN 0 372#define XML_SCHEMA_SCHEMA_IMPORT 1 373#define XML_SCHEMA_SCHEMA_INCLUDE 2 374#define XML_SCHEMA_SCHEMA_REDEFINE 3 375 376/** 377 * xmlSchemaSchemaRelation: 378 * 379 * Used to create a graph of schema relationships. 380 */ 381typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 382typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 383struct _xmlSchemaSchemaRelation { 384 xmlSchemaSchemaRelationPtr next; 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 386 const xmlChar *importNamespace; 387 xmlSchemaBucketPtr bucket; 388}; 389 390#define XML_SCHEMA_BUCKET_MARKED 1<<0 391#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 392 393struct _xmlSchemaBucket { 394 int type; 395 int flags; 396 const xmlChar *schemaLocation; 397 const xmlChar *origTargetNamespace; 398 const xmlChar *targetNamespace; 399 xmlDocPtr doc; 400 xmlSchemaSchemaRelationPtr relations; 401 int located; 402 int parsed; 403 int imported; 404 int preserveDoc; 405 xmlSchemaItemListPtr globals; /* Global components. */ 406 xmlSchemaItemListPtr locals; /* Local components. */ 407}; 408 409/** 410 * xmlSchemaImport: 411 * (extends xmlSchemaBucket) 412 * 413 * Reflects a schema. Holds some information 414 * about the schema and its toplevel components. Duplicate 415 * toplevel components are not checked at this level. 416 */ 417typedef struct _xmlSchemaImport xmlSchemaImport; 418typedef xmlSchemaImport *xmlSchemaImportPtr; 419struct _xmlSchemaImport { 420 int type; /* Main OR import OR include. */ 421 int flags; 422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 423 /* For chameleon includes, @origTargetNamespace will be NULL */ 424 const xmlChar *origTargetNamespace; 425 /* 426 * For chameleon includes, @targetNamespace will be the 427 * targetNamespace of the including schema. 428 */ 429 const xmlChar *targetNamespace; 430 xmlDocPtr doc; /* The schema node-tree. */ 431 /* @relations will hold any included/imported/redefined schemas. */ 432 xmlSchemaSchemaRelationPtr relations; 433 int located; 434 int parsed; 435 int imported; 436 int preserveDoc; 437 xmlSchemaItemListPtr globals; 438 xmlSchemaItemListPtr locals; 439 /* The imported schema. */ 440 xmlSchemaPtr schema; 441}; 442 443/* 444* (extends xmlSchemaBucket) 445*/ 446typedef struct _xmlSchemaInclude xmlSchemaInclude; 447typedef xmlSchemaInclude *xmlSchemaIncludePtr; 448struct _xmlSchemaInclude { 449 int type; 450 int flags; 451 const xmlChar *schemaLocation; 452 const xmlChar *origTargetNamespace; 453 const xmlChar *targetNamespace; 454 xmlDocPtr doc; 455 xmlSchemaSchemaRelationPtr relations; 456 int located; 457 int parsed; 458 int imported; 459 int preserveDoc; 460 xmlSchemaItemListPtr globals; /* Global components. */ 461 xmlSchemaItemListPtr locals; /* Local components. */ 462 463 /* The owning main or import schema bucket. */ 464 xmlSchemaImportPtr ownerImport; 465}; 466 467/** 468 * xmlSchemaBasicItem: 469 * 470 * The abstract base type for schema components. 471 */ 472typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 473typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 474struct _xmlSchemaBasicItem { 475 xmlSchemaTypeType type; 476}; 477 478/** 479 * xmlSchemaAnnotItem: 480 * 481 * The abstract base type for annotated schema components. 482 * (Extends xmlSchemaBasicItem) 483 */ 484typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 485typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 486struct _xmlSchemaAnnotItem { 487 xmlSchemaTypeType type; 488 xmlSchemaAnnotPtr annot; 489}; 490 491/** 492 * xmlSchemaTreeItem: 493 * 494 * The abstract base type for tree-like structured schema components. 495 * (Extends xmlSchemaAnnotItem) 496 */ 497typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 498typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 499struct _xmlSchemaTreeItem { 500 xmlSchemaTypeType type; 501 xmlSchemaAnnotPtr annot; 502 xmlSchemaTreeItemPtr next; 503 xmlSchemaTreeItemPtr children; 504}; 505 506 507#define XML_SCHEMA_ATTR_USE_FIXED 1<<0 508/** 509 * xmlSchemaAttributeUsePtr: 510 * 511 * The abstract base type for tree-like structured schema components. 512 * (Extends xmlSchemaTreeItem) 513 */ 514typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 515typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 516struct _xmlSchemaAttributeUse { 517 xmlSchemaTypeType type; 518 xmlSchemaAnnotPtr annot; 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 520 /* 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 522 * a QName-ref. to an attribute group definition. 523 */ 524 xmlSchemaAttributePtr attrDecl; 525 526 int flags; 527 xmlNodePtr node; 528 int occurs; /* required, optional */ 529 const xmlChar * defValue; 530 xmlSchemaValPtr defVal; 531}; 532 533/** 534 * xmlSchemaAttributeUseProhibPtr: 535 * 536 * A helper component to reflect attribute prohibitions. 537 * (Extends xmlSchemaBasicItem) 538 */ 539typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 540typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 541struct _xmlSchemaAttributeUseProhib { 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 543 xmlNodePtr node; 544 const xmlChar *name; 545 const xmlChar *targetNamespace; 546 int isRef; 547}; 548 549/** 550 * xmlSchemaRedef: 551 */ 552typedef struct _xmlSchemaRedef xmlSchemaRedef; 553typedef xmlSchemaRedef *xmlSchemaRedefPtr; 554struct _xmlSchemaRedef { 555 xmlSchemaRedefPtr next; 556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 560 const xmlChar *refTargetNs; /* The target namespace of the 561 to-be-redefined comp. */ 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 563}; 564 565/** 566 * xmlSchemaConstructionCtxt: 567 */ 568typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 569typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 570struct _xmlSchemaConstructionCtxt { 571 xmlSchemaPtr mainSchema; /* The main schema. */ 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 573 xmlDictPtr dict; 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 578 need to be fixed. */ 579 xmlHashTablePtr substGroups; 580 xmlSchemaRedefPtr redefs; 581 xmlSchemaRedefPtr lastRedef; 582}; 583 584#define XML_SCHEMAS_PARSE_ERROR 1 585#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 586 587struct _xmlSchemaParserCtxt { 588 int type; 589 void *errCtxt; /* user specific error context */ 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 592 int err; 593 int nberrors; 594 xmlStructuredErrorFunc serror; 595 596 xmlSchemaConstructionCtxtPtr constructor; 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 598 599 /* xmlSchemaPtr topschema; */ 600 /* xmlHashTablePtr namespaces; */ 601 602 xmlSchemaPtr schema; /* The main schema in use */ 603 int counter; 604 605 const xmlChar *URL; 606 xmlDocPtr doc; 607 int preserve; /* Whether the doc should be freed */ 608 609 const char *buffer; 610 int size; 611 612 /* 613 * Used to build complex element content models 614 */ 615 xmlAutomataPtr am; 616 xmlAutomataStatePtr start; 617 xmlAutomataStatePtr end; 618 xmlAutomataStatePtr state; 619 620 xmlDictPtr dict; /* dictionnary for interned string names */ 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 622 int options; 623 xmlSchemaValidCtxtPtr vctxt; 624 int isS4S; 625 int isRedefine; 626 int xsiAssemble; 627 int stop; /* If the parser should stop; i.e. a critical error. */ 628 const xmlChar *targetNamespace; 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 630 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 632 int redefCounter; /* Used for redefinitions. */ 633 xmlSchemaItemListPtr attrProhibs; 634}; 635 636/** 637 * xmlSchemaQNameRef: 638 * 639 * A component reference item (not a schema component) 640 * (Extends xmlSchemaBasicItem) 641 */ 642typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 643typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 644struct _xmlSchemaQNameRef { 645 xmlSchemaTypeType type; 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 647 xmlSchemaTypeType itemType; 648 const xmlChar *name; 649 const xmlChar *targetNamespace; 650 xmlNodePtr node; 651}; 652 653/** 654 * xmlSchemaParticle: 655 * 656 * A particle component. 657 * (Extends xmlSchemaTreeItem) 658 */ 659typedef struct _xmlSchemaParticle xmlSchemaParticle; 660typedef xmlSchemaParticle *xmlSchemaParticlePtr; 661struct _xmlSchemaParticle { 662 xmlSchemaTypeType type; 663 xmlSchemaAnnotPtr annot; 664 xmlSchemaTreeItemPtr next; /* next particle */ 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 667 etc.) */ 668 int minOccurs; 669 int maxOccurs; 670 xmlNodePtr node; 671}; 672 673/** 674 * xmlSchemaModelGroup: 675 * 676 * A model group component. 677 * (Extends xmlSchemaTreeItem) 678 */ 679typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 680typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 681struct _xmlSchemaModelGroup { 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 683 xmlSchemaAnnotPtr annot; 684 xmlSchemaTreeItemPtr next; /* not used */ 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 686 xmlNodePtr node; 687}; 688 689#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 690#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 691/** 692 * xmlSchemaModelGroupDef: 693 * 694 * A model group definition component. 695 * (Extends xmlSchemaTreeItem) 696 */ 697typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 698typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 699struct _xmlSchemaModelGroupDef { 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 701 xmlSchemaAnnotPtr annot; 702 xmlSchemaTreeItemPtr next; /* not used */ 703 xmlSchemaTreeItemPtr children; /* the "model group" */ 704 const xmlChar *name; 705 const xmlChar *targetNamespace; 706 xmlNodePtr node; 707 int flags; 708}; 709 710typedef struct _xmlSchemaIDC xmlSchemaIDC; 711typedef xmlSchemaIDC *xmlSchemaIDCPtr; 712 713/** 714 * xmlSchemaIDCSelect: 715 * 716 * The identity-constraint "field" and "selector" item, holding the 717 * XPath expression. 718 */ 719typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 720typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 721struct _xmlSchemaIDCSelect { 722 xmlSchemaIDCSelectPtr next; 723 xmlSchemaIDCPtr idc; 724 int index; /* an index position if significant for IDC key-sequences */ 725 const xmlChar *xpath; /* the XPath expression */ 726 void *xpathComp; /* the compiled XPath expression */ 727}; 728 729/** 730 * xmlSchemaIDC: 731 * 732 * The identity-constraint definition component. 733 * (Extends xmlSchemaAnnotItem) 734 */ 735 736struct _xmlSchemaIDC { 737 xmlSchemaTypeType type; 738 xmlSchemaAnnotPtr annot; 739 xmlSchemaIDCPtr next; 740 xmlNodePtr node; 741 const xmlChar *name; 742 const xmlChar *targetNamespace; 743 xmlSchemaIDCSelectPtr selector; 744 xmlSchemaIDCSelectPtr fields; 745 int nbFields; 746 xmlSchemaQNameRefPtr ref; 747}; 748 749/** 750 * xmlSchemaIDCAug: 751 * 752 * The augmented IDC information used for validation. 753 */ 754typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 755typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 756struct _xmlSchemaIDCAug { 757 xmlSchemaIDCAugPtr next; /* next in a list */ 758 xmlSchemaIDCPtr def; /* the IDC definition */ 759 int keyrefDepth; /* the lowest tree level to which IDC 760 tables need to be bubbled upwards */ 761}; 762 763/** 764 * xmlSchemaPSVIIDCKeySequence: 765 * 766 * The key sequence of a node table item. 767 */ 768typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 769typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 770struct _xmlSchemaPSVIIDCKey { 771 xmlSchemaTypePtr type; 772 xmlSchemaValPtr val; 773}; 774 775/** 776 * xmlSchemaPSVIIDCNode: 777 * 778 * The node table item of a node table. 779 */ 780typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 781typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 782struct _xmlSchemaPSVIIDCNode { 783 xmlNodePtr node; 784 xmlSchemaPSVIIDCKeyPtr *keys; 785 int nodeLine; 786 int nodeQNameID; 787 788}; 789 790/** 791 * xmlSchemaPSVIIDCBinding: 792 * 793 * The identity-constraint binding item of the [identity-constraint table]. 794 */ 795typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 796typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 797struct _xmlSchemaPSVIIDCBinding { 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 799 xmlSchemaIDCPtr definition; /* the IDC definition */ 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 801 int nbNodes; /* number of entries in the node table */ 802 int sizeNodes; /* size of the node table */ 803 xmlSchemaItemListPtr dupls; 804}; 805 806 807#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 808#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 809 810#define XPATH_STATE_OBJ_MATCHES -2 811#define XPATH_STATE_OBJ_BLOCKED -3 812 813typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 814typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 815 816/** 817 * xmlSchemaIDCStateObj: 818 * 819 * The state object used to evaluate XPath expressions. 820 */ 821typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 822typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 823struct _xmlSchemaIDCStateObj { 824 int type; 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 826 int depth; /* depth of creation */ 827 int *history; /* list of (depth, state-id) tuples */ 828 int nbHistory; 829 int sizeHistory; 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 831 matcher */ 832 xmlSchemaIDCSelectPtr sel; 833 void *xpathCtxt; 834}; 835 836#define IDC_MATCHER 0 837 838/** 839 * xmlSchemaIDCMatcher: 840 * 841 * Used to evaluate IDC selectors (and fields). 842 */ 843struct _xmlSchemaIDCMatcher { 844 int type; 845 int depth; /* the tree depth at creation time */ 846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 849 int idcType; 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 851 elements */ 852 int sizeKeySeqs; 853 xmlSchemaItemListPtr targets; /* list of target-node 854 (xmlSchemaPSVIIDCNodePtr) entries */ 855}; 856 857/* 858* Element info flags. 859*/ 860#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 861#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 862#define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 863#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 864 865#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 866#define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 867#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 868 869#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 870#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 871#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 872#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 873 874/** 875 * xmlSchemaNodeInfo: 876 * 877 * Holds information of an element node. 878 */ 879struct _xmlSchemaNodeInfo { 880 int nodeType; 881 xmlNodePtr node; 882 int nodeLine; 883 const xmlChar *localName; 884 const xmlChar *nsName; 885 const xmlChar *value; 886 xmlSchemaValPtr val; /* the pre-computed value if any */ 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 888 889 int flags; /* combination of node info flags */ 890 891 int valNeeded; 892 int normVal; 893 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 895 int depth; 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 897 for the scope element*/ 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 899 element */ 900 xmlRegExecCtxtPtr regexCtxt; 901 902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 903 int nbNsBindings; 904 int sizeNsBindings; 905 906 int hasKeyrefs; 907 int appliedXPath; /* Indicates that an XPath has been applied. */ 908}; 909 910#define XML_SCHEMAS_ATTR_UNKNOWN 1 911#define XML_SCHEMAS_ATTR_ASSESSED 2 912#define XML_SCHEMAS_ATTR_PROHIBITED 3 913#define XML_SCHEMAS_ATTR_ERR_MISSING 4 914#define XML_SCHEMAS_ATTR_INVALID_VALUE 5 915#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 916#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 917#define XML_SCHEMAS_ATTR_DEFAULT 8 918#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 919#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 920#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 921#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 922#define XML_SCHEMAS_ATTR_WILD_SKIP 13 923#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 924#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 925#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 926#define XML_SCHEMAS_ATTR_META 17 927/* 928* @metaType values of xmlSchemaAttrInfo. 929*/ 930#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 931#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 932#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 933#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 934#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 935 936typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 937typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 938struct _xmlSchemaAttrInfo { 939 int nodeType; 940 xmlNodePtr node; 941 int nodeLine; 942 const xmlChar *localName; 943 const xmlChar *nsName; 944 const xmlChar *value; 945 xmlSchemaValPtr val; /* the pre-computed value if any */ 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 947 int flags; /* combination of node info flags */ 948 949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 951 int state; 952 int metaType; 953 const xmlChar *vcValue; /* the value constraint value */ 954 xmlSchemaNodeInfoPtr parent; 955}; 956 957 958#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 959/** 960 * xmlSchemaValidCtxt: 961 * 962 * A Schemas validation context 963 */ 964struct _xmlSchemaValidCtxt { 965 int type; 966 void *errCtxt; /* user specific data block */ 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 969 xmlStructuredErrorFunc serror; 970 971 xmlSchemaPtr schema; /* The schema in use */ 972 xmlDocPtr doc; 973 xmlParserInputBufferPtr input; 974 xmlCharEncoding enc; 975 xmlSAXHandlerPtr sax; 976 xmlParserCtxtPtr parserCtxt; 977 void *user_data; /* TODO: What is this for? */ 978 979 int err; 980 int nberrors; 981 982 xmlNodePtr node; 983 xmlNodePtr cur; 984 /* xmlSchemaTypePtr type; */ 985 986 xmlRegExecCtxtPtr regexp; 987 xmlSchemaValPtr value; 988 989 int valueWS; 990 int options; 991 xmlNodePtr validationRoot; 992 xmlSchemaParserCtxtPtr pctxt; 993 int xsiAssemble; 994 995 int depth; 996 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 997 int sizeElemInfos; 998 xmlSchemaNodeInfoPtr inode; /* the current element information */ 999 1000 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1001 1002 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1003 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1004 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1005 1006 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1007 int nbIdcNodes; 1008 int sizeIdcNodes; 1009 1010 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1011 int nbIdcKeys; 1012 int sizeIdcKeys; 1013 1014 int flags; 1015 1016 xmlDictPtr dict; 1017 1018#ifdef LIBXML_READER_ENABLED 1019 xmlTextReaderPtr reader; 1020#endif 1021 1022 xmlSchemaAttrInfoPtr *attrInfos; 1023 int nbAttrInfos; 1024 int sizeAttrInfos; 1025 1026 int skipDepth; 1027 xmlSchemaItemListPtr nodeQNames; 1028 int hasKeyrefs; 1029 int createIDCNodeTables; 1030 int psviExposeIDCNodeTables; 1031}; 1032 1033/** 1034 * xmlSchemaSubstGroup: 1035 * 1036 * 1037 */ 1038typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1039typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1040struct _xmlSchemaSubstGroup { 1041 xmlSchemaElementPtr head; 1042 xmlSchemaItemListPtr members; 1043}; 1044 1045/************************************************************************ 1046 * * 1047 * Some predeclarations * 1048 * * 1049 ************************************************************************/ 1050 1051static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1052 xmlSchemaPtr schema, 1053 xmlNodePtr node); 1054static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1055 xmlSchemaPtr schema, 1056 xmlNodePtr node); 1057static int 1058xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1059 xmlSchemaAbstractCtxtPtr ctxt); 1060static const xmlChar * 1061xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1062static int 1063xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1064 xmlNodePtr node); 1065static int 1066xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1067 xmlSchemaParserCtxtPtr ctxt); 1068static void 1069xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1070static xmlSchemaWhitespaceValueType 1071xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1072static xmlSchemaTreeItemPtr 1073xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1074 xmlNodePtr node, xmlSchemaTypeType type, 1075 int withParticle); 1076static const xmlChar * 1077xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1078static xmlSchemaTypeLinkPtr 1079xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1080static void 1081xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1082 const char *funcName, 1083 const char *message); 1084static int 1085xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1086 xmlSchemaTypePtr type, 1087 xmlSchemaTypePtr baseType, 1088 int subset); 1089static void 1090xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1091 xmlSchemaParserCtxtPtr ctxt); 1092static void 1093xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1094static xmlSchemaQNameRefPtr 1095xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1096 xmlSchemaPtr schema, 1097 xmlNodePtr node); 1098 1099/************************************************************************ 1100 * * 1101 * Helper functions * 1102 * * 1103 ************************************************************************/ 1104 1105/** 1106 * xmlSchemaItemTypeToStr: 1107 * @type: the type of the schema item 1108 * 1109 * Returns the component name of a schema item. 1110 */ 1111static const xmlChar * 1112xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1113{ 1114 switch (type) { 1115 case XML_SCHEMA_TYPE_BASIC: 1116 return(BAD_CAST "simple type definition"); 1117 case XML_SCHEMA_TYPE_SIMPLE: 1118 return(BAD_CAST "simple type definition"); 1119 case XML_SCHEMA_TYPE_COMPLEX: 1120 return(BAD_CAST "complex type definition"); 1121 case XML_SCHEMA_TYPE_ELEMENT: 1122 return(BAD_CAST "element declaration"); 1123 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1124 return(BAD_CAST "attribute use"); 1125 case XML_SCHEMA_TYPE_ATTRIBUTE: 1126 return(BAD_CAST "attribute declaration"); 1127 case XML_SCHEMA_TYPE_GROUP: 1128 return(BAD_CAST "model group definition"); 1129 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1130 return(BAD_CAST "attribute group definition"); 1131 case XML_SCHEMA_TYPE_NOTATION: 1132 return(BAD_CAST "notation declaration"); 1133 case XML_SCHEMA_TYPE_SEQUENCE: 1134 return(BAD_CAST "model group (sequence)"); 1135 case XML_SCHEMA_TYPE_CHOICE: 1136 return(BAD_CAST "model group (choice)"); 1137 case XML_SCHEMA_TYPE_ALL: 1138 return(BAD_CAST "model group (all)"); 1139 case XML_SCHEMA_TYPE_PARTICLE: 1140 return(BAD_CAST "particle"); 1141 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1142 return(BAD_CAST "unique identity-constraint"); 1143 /* return(BAD_CAST "IDC (unique)"); */ 1144 case XML_SCHEMA_TYPE_IDC_KEY: 1145 return(BAD_CAST "key identity-constraint"); 1146 /* return(BAD_CAST "IDC (key)"); */ 1147 case XML_SCHEMA_TYPE_IDC_KEYREF: 1148 return(BAD_CAST "keyref identity-constraint"); 1149 /* return(BAD_CAST "IDC (keyref)"); */ 1150 case XML_SCHEMA_TYPE_ANY: 1151 return(BAD_CAST "wildcard (any)"); 1152 case XML_SCHEMA_EXTRA_QNAMEREF: 1153 return(BAD_CAST "[helper component] QName reference"); 1154 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1155 return(BAD_CAST "[helper component] attribute use prohibition"); 1156 default: 1157 return(BAD_CAST "Not a schema component"); 1158 } 1159} 1160 1161/** 1162 * xmlSchemaGetComponentTypeStr: 1163 * @type: the type of the schema item 1164 * 1165 * Returns the component name of a schema item. 1166 */ 1167static const xmlChar * 1168xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1169{ 1170 switch (item->type) { 1171 case XML_SCHEMA_TYPE_BASIC: 1172 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1173 return(BAD_CAST "complex type definition"); 1174 else 1175 return(BAD_CAST "simple type definition"); 1176 default: 1177 return(xmlSchemaItemTypeToStr(item->type)); 1178 } 1179} 1180 1181/** 1182 * xmlSchemaGetComponentNode: 1183 * @item: a schema component 1184 * 1185 * Returns node associated with the schema component. 1186 * NOTE that such a node need not be available; plus, a component's 1187 * node need not to reflect the component directly, since there is no 1188 * one-to-one relationship between the XML Schema representation and 1189 * the component representation. 1190 */ 1191static xmlNodePtr 1192xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1193{ 1194 switch (item->type) { 1195 case XML_SCHEMA_TYPE_ELEMENT: 1196 return (((xmlSchemaElementPtr) item)->node); 1197 case XML_SCHEMA_TYPE_ATTRIBUTE: 1198 return (((xmlSchemaAttributePtr) item)->node); 1199 case XML_SCHEMA_TYPE_COMPLEX: 1200 case XML_SCHEMA_TYPE_SIMPLE: 1201 return (((xmlSchemaTypePtr) item)->node); 1202 case XML_SCHEMA_TYPE_ANY: 1203 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1204 return (((xmlSchemaWildcardPtr) item)->node); 1205 case XML_SCHEMA_TYPE_PARTICLE: 1206 return (((xmlSchemaParticlePtr) item)->node); 1207 case XML_SCHEMA_TYPE_SEQUENCE: 1208 case XML_SCHEMA_TYPE_CHOICE: 1209 case XML_SCHEMA_TYPE_ALL: 1210 return (((xmlSchemaModelGroupPtr) item)->node); 1211 case XML_SCHEMA_TYPE_GROUP: 1212 return (((xmlSchemaModelGroupDefPtr) item)->node); 1213 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1214 return (((xmlSchemaAttributeGroupPtr) item)->node); 1215 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1216 case XML_SCHEMA_TYPE_IDC_KEY: 1217 case XML_SCHEMA_TYPE_IDC_KEYREF: 1218 return (((xmlSchemaIDCPtr) item)->node); 1219 case XML_SCHEMA_EXTRA_QNAMEREF: 1220 return(((xmlSchemaQNameRefPtr) item)->node); 1221 /* TODO: What to do with NOTATIONs? 1222 case XML_SCHEMA_TYPE_NOTATION: 1223 return (((xmlSchemaNotationPtr) item)->node); 1224 */ 1225 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1226 return (((xmlSchemaAttributeUsePtr) item)->node); 1227 default: 1228 return (NULL); 1229 } 1230} 1231 1232#if 0 1233/** 1234 * xmlSchemaGetNextComponent: 1235 * @item: a schema component 1236 * 1237 * Returns the next sibling of the schema component. 1238 */ 1239static xmlSchemaBasicItemPtr 1240xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1241{ 1242 switch (item->type) { 1243 case XML_SCHEMA_TYPE_ELEMENT: 1244 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1245 case XML_SCHEMA_TYPE_ATTRIBUTE: 1246 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1247 case XML_SCHEMA_TYPE_COMPLEX: 1248 case XML_SCHEMA_TYPE_SIMPLE: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1250 case XML_SCHEMA_TYPE_ANY: 1251 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1252 return (NULL); 1253 case XML_SCHEMA_TYPE_PARTICLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1255 case XML_SCHEMA_TYPE_SEQUENCE: 1256 case XML_SCHEMA_TYPE_CHOICE: 1257 case XML_SCHEMA_TYPE_ALL: 1258 return (NULL); 1259 case XML_SCHEMA_TYPE_GROUP: 1260 return (NULL); 1261 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1263 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1264 case XML_SCHEMA_TYPE_IDC_KEY: 1265 case XML_SCHEMA_TYPE_IDC_KEYREF: 1266 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1267 default: 1268 return (NULL); 1269 } 1270} 1271#endif 1272 1273 1274/** 1275 * xmlSchemaFormatQName: 1276 * @buf: the string buffer 1277 * @namespaceName: the namespace name 1278 * @localName: the local name 1279 * 1280 * Returns the given QName in the format "{namespaceName}localName" or 1281 * just "localName" if @namespaceName is NULL. 1282 * 1283 * Returns the localName if @namespaceName is NULL, a formatted 1284 * string otherwise. 1285 */ 1286static const xmlChar* 1287xmlSchemaFormatQName(xmlChar **buf, 1288 const xmlChar *namespaceName, 1289 const xmlChar *localName) 1290{ 1291 FREE_AND_NULL(*buf) 1292 if (namespaceName != NULL) { 1293 *buf = xmlStrdup(BAD_CAST "{"); 1294 *buf = xmlStrcat(*buf, namespaceName); 1295 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1296 } 1297 if (localName != NULL) { 1298 if (namespaceName == NULL) 1299 return(localName); 1300 *buf = xmlStrcat(*buf, localName); 1301 } else { 1302 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1303 } 1304 return ((const xmlChar *) *buf); 1305} 1306 1307static const xmlChar* 1308xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1309{ 1310 if (ns != NULL) 1311 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1312 else 1313 return (xmlSchemaFormatQName(buf, NULL, localName)); 1314} 1315 1316static const xmlChar * 1317xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1318{ 1319 switch (item->type) { 1320 case XML_SCHEMA_TYPE_ELEMENT: 1321 return (((xmlSchemaElementPtr) item)->name); 1322 case XML_SCHEMA_TYPE_ATTRIBUTE: 1323 return (((xmlSchemaAttributePtr) item)->name); 1324 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1325 return (((xmlSchemaAttributeGroupPtr) item)->name); 1326 case XML_SCHEMA_TYPE_BASIC: 1327 case XML_SCHEMA_TYPE_SIMPLE: 1328 case XML_SCHEMA_TYPE_COMPLEX: 1329 return (((xmlSchemaTypePtr) item)->name); 1330 case XML_SCHEMA_TYPE_GROUP: 1331 return (((xmlSchemaModelGroupDefPtr) item)->name); 1332 case XML_SCHEMA_TYPE_IDC_KEY: 1333 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1334 case XML_SCHEMA_TYPE_IDC_KEYREF: 1335 return (((xmlSchemaIDCPtr) item)->name); 1336 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1337 if (WXS_ATTRUSE_DECL(item) != NULL) { 1338 return(xmlSchemaGetComponentName( 1339 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1340 } else 1341 return(NULL); 1342 case XML_SCHEMA_EXTRA_QNAMEREF: 1343 return (((xmlSchemaQNameRefPtr) item)->name); 1344 case XML_SCHEMA_TYPE_NOTATION: 1345 return (((xmlSchemaNotationPtr) item)->name); 1346 default: 1347 /* 1348 * Other components cannot have names. 1349 */ 1350 break; 1351 } 1352 return (NULL); 1353} 1354 1355#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1356#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1357/* 1358static const xmlChar * 1359xmlSchemaGetQNameRefName(void *ref) 1360{ 1361 return(((xmlSchemaQNameRefPtr) ref)->name); 1362} 1363 1364static const xmlChar * 1365xmlSchemaGetQNameRefTargetNs(void *ref) 1366{ 1367 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1368} 1369*/ 1370 1371static const xmlChar * 1372xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1373{ 1374 switch (item->type) { 1375 case XML_SCHEMA_TYPE_ELEMENT: 1376 return (((xmlSchemaElementPtr) item)->targetNamespace); 1377 case XML_SCHEMA_TYPE_ATTRIBUTE: 1378 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1379 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1380 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1381 case XML_SCHEMA_TYPE_BASIC: 1382 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1383 case XML_SCHEMA_TYPE_SIMPLE: 1384 case XML_SCHEMA_TYPE_COMPLEX: 1385 return (((xmlSchemaTypePtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_GROUP: 1387 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1388 case XML_SCHEMA_TYPE_IDC_KEY: 1389 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1390 case XML_SCHEMA_TYPE_IDC_KEYREF: 1391 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1393 if (WXS_ATTRUSE_DECL(item) != NULL) { 1394 return(xmlSchemaGetComponentTargetNs( 1395 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1396 } 1397 /* TODO: Will returning NULL break something? */ 1398 break; 1399 case XML_SCHEMA_EXTRA_QNAMEREF: 1400 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_NOTATION: 1402 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1403 default: 1404 /* 1405 * Other components cannot have names. 1406 */ 1407 break; 1408 } 1409 return (NULL); 1410} 1411 1412static const xmlChar* 1413xmlSchemaGetComponentQName(xmlChar **buf, 1414 void *item) 1415{ 1416 return (xmlSchemaFormatQName(buf, 1417 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1418 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1419} 1420 1421static const xmlChar* 1422xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1423{ 1424 xmlChar *str = NULL; 1425 1426 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1427 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1428 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1429 (xmlSchemaBasicItemPtr) item)); 1430 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1431 FREE_AND_NULL(str); 1432 return(*buf); 1433} 1434 1435static const xmlChar* 1436xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1437{ 1438 return(xmlSchemaGetComponentDesignation(buf, idc)); 1439} 1440 1441/** 1442 * xmlSchemaWildcardPCToString: 1443 * @pc: the type of processContents 1444 * 1445 * Returns a string representation of the type of 1446 * processContents. 1447 */ 1448static const xmlChar * 1449xmlSchemaWildcardPCToString(int pc) 1450{ 1451 switch (pc) { 1452 case XML_SCHEMAS_ANY_SKIP: 1453 return (BAD_CAST "skip"); 1454 case XML_SCHEMAS_ANY_LAX: 1455 return (BAD_CAST "lax"); 1456 case XML_SCHEMAS_ANY_STRICT: 1457 return (BAD_CAST "strict"); 1458 default: 1459 return (BAD_CAST "invalid process contents"); 1460 } 1461} 1462 1463/** 1464 * xmlSchemaGetCanonValueWhtspExt: 1465 * @val: the precomputed value 1466 * @retValue: the returned value 1467 * @ws: the whitespace type of the value 1468 * 1469 * Get a the cononical representation of the value. 1470 * The caller has to free the returned retValue. 1471 * 1472 * Returns 0 if the value could be built and -1 in case of 1473 * API errors or if the value type is not supported yet. 1474 */ 1475static int 1476xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1477 xmlSchemaWhitespaceValueType ws, 1478 xmlChar **retValue) 1479{ 1480 int list; 1481 xmlSchemaValType valType; 1482 const xmlChar *value, *value2 = NULL; 1483 1484 1485 if ((retValue == NULL) || (val == NULL)) 1486 return (-1); 1487 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1488 *retValue = NULL; 1489 do { 1490 value = NULL; 1491 valType = xmlSchemaGetValType(val); 1492 switch (valType) { 1493 case XML_SCHEMAS_STRING: 1494 case XML_SCHEMAS_NORMSTRING: 1495 case XML_SCHEMAS_ANYSIMPLETYPE: 1496 value = xmlSchemaValueGetAsString(val); 1497 if (value != NULL) { 1498 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1499 value2 = xmlSchemaCollapseString(value); 1500 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1501 value2 = xmlSchemaWhiteSpaceReplace(value); 1502 if (value2 != NULL) 1503 value = value2; 1504 } 1505 break; 1506 default: 1507 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1508 if (value2 != NULL) 1509 xmlFree((xmlChar *) value2); 1510 goto internal_error; 1511 } 1512 value = value2; 1513 } 1514 if (*retValue == NULL) 1515 if (value == NULL) { 1516 if (! list) 1517 *retValue = xmlStrdup(BAD_CAST ""); 1518 } else 1519 *retValue = xmlStrdup(value); 1520 else if (value != NULL) { 1521 /* List. */ 1522 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1523 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1524 } 1525 FREE_AND_NULL(value2) 1526 val = xmlSchemaValueGetNext(val); 1527 } while (val != NULL); 1528 1529 return (0); 1530internal_error: 1531 if (*retValue != NULL) 1532 xmlFree((xmlChar *) (*retValue)); 1533 if (value2 != NULL) 1534 xmlFree((xmlChar *) value2); 1535 return (-1); 1536} 1537 1538/** 1539 * xmlSchemaFormatItemForReport: 1540 * @buf: the string buffer 1541 * @itemDes: the designation of the item 1542 * @itemName: the name of the item 1543 * @item: the item as an object 1544 * @itemNode: the node of the item 1545 * @local: the local name 1546 * @parsing: if the function is used during the parse 1547 * 1548 * Returns a representation of the given item used 1549 * for error reports. 1550 * 1551 * The following order is used to build the resulting 1552 * designation if the arguments are not NULL: 1553 * 1a. If itemDes not NULL -> itemDes 1554 * 1b. If (itemDes not NULL) and (itemName not NULL) 1555 * -> itemDes + itemName 1556 * 2. If the preceding was NULL and (item not NULL) -> item 1557 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1558 * 1559 * If the itemNode is an attribute node, the name of the attribute 1560 * will be appended to the result. 1561 * 1562 * Returns the formatted string and sets @buf to the resulting value. 1563 */ 1564static xmlChar* 1565xmlSchemaFormatItemForReport(xmlChar **buf, 1566 const xmlChar *itemDes, 1567 xmlSchemaBasicItemPtr item, 1568 xmlNodePtr itemNode) 1569{ 1570 xmlChar *str = NULL; 1571 int named = 1; 1572 1573 if (*buf != NULL) { 1574 xmlFree(*buf); 1575 *buf = NULL; 1576 } 1577 1578 if (itemDes != NULL) { 1579 *buf = xmlStrdup(itemDes); 1580 } else if (item != NULL) { 1581 switch (item->type) { 1582 case XML_SCHEMA_TYPE_BASIC: { 1583 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1584 1585 if (WXS_IS_ATOMIC(type)) 1586 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1587 else if (WXS_IS_LIST(type)) 1588 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1589 else if (WXS_IS_UNION(type)) 1590 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1591 else 1592 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1593 *buf = xmlStrcat(*buf, type->name); 1594 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1595 } 1596 break; 1597 case XML_SCHEMA_TYPE_SIMPLE: { 1598 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1599 1600 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1601 *buf = xmlStrdup(BAD_CAST""); 1602 } else { 1603 *buf = xmlStrdup(BAD_CAST "local "); 1604 } 1605 if (WXS_IS_ATOMIC(type)) 1606 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1607 else if (WXS_IS_LIST(type)) 1608 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1609 else if (WXS_IS_UNION(type)) 1610 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1611 else 1612 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1615 *buf = xmlStrcat(*buf, type->name); 1616 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1617 } 1618 } 1619 break; 1620 case XML_SCHEMA_TYPE_COMPLEX: { 1621 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1622 1623 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1624 *buf = xmlStrdup(BAD_CAST ""); 1625 else 1626 *buf = xmlStrdup(BAD_CAST "local "); 1627 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1629 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1630 *buf = xmlStrcat(*buf, type->name); 1631 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1632 } 1633 } 1634 break; 1635 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1636 xmlSchemaAttributeUsePtr ause; 1637 1638 ause = WXS_ATTR_USE_CAST item; 1639 *buf = xmlStrdup(BAD_CAST "attribute use "); 1640 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1641 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1642 *buf = xmlStrcat(*buf, 1643 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1644 FREE_AND_NULL(str) 1645 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1646 } else { 1647 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1648 } 1649 } 1650 break; 1651 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1652 xmlSchemaAttributePtr attr; 1653 1654 attr = (xmlSchemaAttributePtr) item; 1655 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1656 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1657 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1658 attr->targetNamespace, attr->name)); 1659 FREE_AND_NULL(str) 1660 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1661 } 1662 break; 1663 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1664 xmlSchemaGetComponentDesignation(buf, item); 1665 break; 1666 case XML_SCHEMA_TYPE_ELEMENT: { 1667 xmlSchemaElementPtr elem; 1668 1669 elem = (xmlSchemaElementPtr) item; 1670 *buf = xmlStrdup(BAD_CAST "element decl."); 1671 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1672 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1673 elem->targetNamespace, elem->name)); 1674 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1675 } 1676 break; 1677 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1678 case XML_SCHEMA_TYPE_IDC_KEY: 1679 case XML_SCHEMA_TYPE_IDC_KEYREF: 1680 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1681 *buf = xmlStrdup(BAD_CAST "unique '"); 1682 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1683 *buf = xmlStrdup(BAD_CAST "key '"); 1684 else 1685 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1686 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 break; 1689 case XML_SCHEMA_TYPE_ANY: 1690 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1691 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1692 ((xmlSchemaWildcardPtr) item)->processContents)); 1693 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1694 break; 1695 case XML_SCHEMA_FACET_MININCLUSIVE: 1696 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1697 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1698 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1699 case XML_SCHEMA_FACET_TOTALDIGITS: 1700 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1701 case XML_SCHEMA_FACET_PATTERN: 1702 case XML_SCHEMA_FACET_ENUMERATION: 1703 case XML_SCHEMA_FACET_WHITESPACE: 1704 case XML_SCHEMA_FACET_LENGTH: 1705 case XML_SCHEMA_FACET_MAXLENGTH: 1706 case XML_SCHEMA_FACET_MINLENGTH: 1707 *buf = xmlStrdup(BAD_CAST "facet '"); 1708 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1709 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1710 break; 1711 case XML_SCHEMA_TYPE_GROUP: { 1712 *buf = xmlStrdup(BAD_CAST "model group def."); 1713 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1714 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1715 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1716 FREE_AND_NULL(str) 1717 } 1718 break; 1719 case XML_SCHEMA_TYPE_SEQUENCE: 1720 case XML_SCHEMA_TYPE_CHOICE: 1721 case XML_SCHEMA_TYPE_ALL: 1722 case XML_SCHEMA_TYPE_PARTICLE: 1723 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1724 break; 1725 case XML_SCHEMA_TYPE_NOTATION: { 1726 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1727 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1728 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1729 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1730 FREE_AND_NULL(str); 1731 } 1732 default: 1733 named = 0; 1734 } 1735 } else 1736 named = 0; 1737 1738 if ((named == 0) && (itemNode != NULL)) { 1739 xmlNodePtr elem; 1740 1741 if (itemNode->type == XML_ATTRIBUTE_NODE) 1742 elem = itemNode->parent; 1743 else 1744 elem = itemNode; 1745 *buf = xmlStrdup(BAD_CAST "Element '"); 1746 if (elem->ns != NULL) { 1747 *buf = xmlStrcat(*buf, 1748 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1749 FREE_AND_NULL(str) 1750 } else 1751 *buf = xmlStrcat(*buf, elem->name); 1752 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1753 1754 } 1755 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1756 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1757 if (itemNode->ns != NULL) { 1758 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1759 itemNode->ns->href, itemNode->name)); 1760 FREE_AND_NULL(str) 1761 } else 1762 *buf = xmlStrcat(*buf, itemNode->name); 1763 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1764 } 1765 FREE_AND_NULL(str) 1766 1767 return (*buf); 1768} 1769 1770/** 1771 * xmlSchemaFormatFacetEnumSet: 1772 * @buf: the string buffer 1773 * @type: the type holding the enumeration facets 1774 * 1775 * Builds a string consisting of all enumeration elements. 1776 * 1777 * Returns a string of all enumeration elements. 1778 */ 1779static const xmlChar * 1780xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1781 xmlChar **buf, xmlSchemaTypePtr type) 1782{ 1783 xmlSchemaFacetPtr facet; 1784 xmlSchemaWhitespaceValueType ws; 1785 xmlChar *value = NULL; 1786 int res, found = 0; 1787 1788 if (*buf != NULL) 1789 xmlFree(*buf); 1790 *buf = NULL; 1791 1792 do { 1793 /* 1794 * Use the whitespace type of the base type. 1795 */ 1796 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1797 for (facet = type->facets; facet != NULL; facet = facet->next) { 1798 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1799 continue; 1800 found = 1; 1801 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1802 ws, &value); 1803 if (res == -1) { 1804 xmlSchemaInternalErr(actxt, 1805 "xmlSchemaFormatFacetEnumSet", 1806 "compute the canonical lexical representation"); 1807 if (*buf != NULL) 1808 xmlFree(*buf); 1809 *buf = NULL; 1810 return (NULL); 1811 } 1812 if (*buf == NULL) 1813 *buf = xmlStrdup(BAD_CAST "'"); 1814 else 1815 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1816 *buf = xmlStrcat(*buf, BAD_CAST value); 1817 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1818 if (value != NULL) { 1819 xmlFree((xmlChar *)value); 1820 value = NULL; 1821 } 1822 } 1823 /* 1824 * The enumeration facet of a type restricts the enumeration 1825 * facet of the ancestor type; i.e., such restricted enumerations 1826 * do not belong to the set of the given type. Thus we break 1827 * on the first found enumeration. 1828 */ 1829 if (found) 1830 break; 1831 type = type->baseType; 1832 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1833 1834 return ((const xmlChar *) *buf); 1835} 1836 1837/************************************************************************ 1838 * * 1839 * Error functions * 1840 * * 1841 ************************************************************************/ 1842 1843#if 0 1844static void 1845xmlSchemaErrMemory(const char *msg) 1846{ 1847 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1848 msg); 1849} 1850#endif 1851 1852static void 1853xmlSchemaPSimpleErr(const char *msg) 1854{ 1855 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1856 msg); 1857} 1858 1859/** 1860 * xmlSchemaPErrMemory: 1861 * @node: a context node 1862 * @extra: extra informations 1863 * 1864 * Handle an out of memory condition 1865 */ 1866static void 1867xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1868 const char *extra, xmlNodePtr node) 1869{ 1870 if (ctxt != NULL) 1871 ctxt->nberrors++; 1872 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1873 extra); 1874} 1875 1876/** 1877 * xmlSchemaPErr: 1878 * @ctxt: the parsing context 1879 * @node: the context node 1880 * @error: the error code 1881 * @msg: the error message 1882 * @str1: extra data 1883 * @str2: extra data 1884 * 1885 * Handle a parser error 1886 */ 1887static void 1888xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1889 const char *msg, const xmlChar * str1, const xmlChar * str2) 1890{ 1891 xmlGenericErrorFunc channel = NULL; 1892 xmlStructuredErrorFunc schannel = NULL; 1893 void *data = NULL; 1894 1895 if (ctxt != NULL) { 1896 ctxt->nberrors++; 1897 ctxt->err = error; 1898 channel = ctxt->error; 1899 data = ctxt->errCtxt; 1900 schannel = ctxt->serror; 1901 } 1902 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1903 error, XML_ERR_ERROR, NULL, 0, 1904 (const char *) str1, (const char *) str2, NULL, 0, 0, 1905 msg, str1, str2); 1906} 1907 1908/** 1909 * xmlSchemaPErr2: 1910 * @ctxt: the parsing context 1911 * @node: the context node 1912 * @node: the current child 1913 * @error: the error code 1914 * @msg: the error message 1915 * @str1: extra data 1916 * @str2: extra data 1917 * 1918 * Handle a parser error 1919 */ 1920static void 1921xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1922 xmlNodePtr child, int error, 1923 const char *msg, const xmlChar * str1, const xmlChar * str2) 1924{ 1925 if (child != NULL) 1926 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1927 else 1928 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1929} 1930 1931 1932/** 1933 * xmlSchemaPErrExt: 1934 * @ctxt: the parsing context 1935 * @node: the context node 1936 * @error: the error code 1937 * @strData1: extra data 1938 * @strData2: extra data 1939 * @strData3: extra data 1940 * @msg: the message 1941 * @str1: extra parameter for the message display 1942 * @str2: extra parameter for the message display 1943 * @str3: extra parameter for the message display 1944 * @str4: extra parameter for the message display 1945 * @str5: extra parameter for the message display 1946 * 1947 * Handle a parser error 1948 */ 1949static void 1950xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1951 const xmlChar * strData1, const xmlChar * strData2, 1952 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1953 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1954 const xmlChar * str5) 1955{ 1956 1957 xmlGenericErrorFunc channel = NULL; 1958 xmlStructuredErrorFunc schannel = NULL; 1959 void *data = NULL; 1960 1961 if (ctxt != NULL) { 1962 ctxt->nberrors++; 1963 ctxt->err = error; 1964 channel = ctxt->error; 1965 data = ctxt->errCtxt; 1966 schannel = ctxt->serror; 1967 } 1968 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1969 error, XML_ERR_ERROR, NULL, 0, 1970 (const char *) strData1, (const char *) strData2, 1971 (const char *) strData3, 0, 0, msg, str1, str2, 1972 str3, str4, str5); 1973} 1974 1975/************************************************************************ 1976 * * 1977 * Allround error functions * 1978 * * 1979 ************************************************************************/ 1980 1981/** 1982 * xmlSchemaVTypeErrMemory: 1983 * @node: a context node 1984 * @extra: extra informations 1985 * 1986 * Handle an out of memory condition 1987 */ 1988static void 1989xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1990 const char *extra, xmlNodePtr node) 1991{ 1992 if (ctxt != NULL) { 1993 ctxt->nberrors++; 1994 ctxt->err = XML_SCHEMAV_INTERNAL; 1995 } 1996 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 1997 extra); 1998} 1999 2000static void 2001xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2002 const char *msg, const xmlChar *str) 2003{ 2004 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2005 msg, (const char *) str); 2006} 2007 2008#define WXS_ERROR_TYPE_ERROR 1 2009#define WXS_ERROR_TYPE_WARNING 2 2010/** 2011 * xmlSchemaErr3: 2012 * @ctxt: the validation context 2013 * @node: the context node 2014 * @error: the error code 2015 * @msg: the error message 2016 * @str1: extra data 2017 * @str2: extra data 2018 * @str3: extra data 2019 * 2020 * Handle a validation error 2021 */ 2022static void 2023xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2024 xmlErrorLevel errorLevel, 2025 int error, xmlNodePtr node, int line, const char *msg, 2026 const xmlChar *str1, const xmlChar *str2, 2027 const xmlChar *str3, const xmlChar *str4) 2028{ 2029 xmlStructuredErrorFunc schannel = NULL; 2030 xmlGenericErrorFunc channel = NULL; 2031 void *data = NULL; 2032 2033 if (ctxt != NULL) { 2034 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2035 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2036 const char *file = NULL; 2037 if (errorLevel != XML_ERR_WARNING) { 2038 vctxt->nberrors++; 2039 vctxt->err = error; 2040 channel = vctxt->error; 2041 } else { 2042 channel = vctxt->warning; 2043 } 2044 schannel = vctxt->serror; 2045 data = vctxt->errCtxt; 2046 2047 /* 2048 * Error node. If we specify a line number, then 2049 * do not channel any node to the error function. 2050 */ 2051 if (line == 0) { 2052 if ((node == NULL) && 2053 (vctxt->depth >= 0) && 2054 (vctxt->inode != NULL)) { 2055 node = vctxt->inode->node; 2056 } 2057 /* 2058 * Get filename and line if no node-tree. 2059 */ 2060 if ((node == NULL) && 2061 (vctxt->parserCtxt != NULL) && 2062 (vctxt->parserCtxt->input != NULL)) { 2063 file = vctxt->parserCtxt->input->filename; 2064 line = vctxt->parserCtxt->input->line; 2065 } 2066 } else { 2067 /* 2068 * Override the given node's (if any) position 2069 * and channel only the given line number. 2070 */ 2071 node = NULL; 2072 /* 2073 * Get filename. 2074 */ 2075 if (vctxt->doc != NULL) 2076 file = (const char *) vctxt->doc->URL; 2077 else if ((vctxt->parserCtxt != NULL) && 2078 (vctxt->parserCtxt->input != NULL)) 2079 file = vctxt->parserCtxt->input->filename; 2080 } 2081 __xmlRaiseError(schannel, channel, data, ctxt, 2082 node, XML_FROM_SCHEMASV, 2083 error, errorLevel, file, line, 2084 (const char *) str1, (const char *) str2, 2085 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2086 2087 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2088 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2089 if (errorLevel != XML_ERR_WARNING) { 2090 pctxt->nberrors++; 2091 pctxt->err = error; 2092 channel = pctxt->error; 2093 } else { 2094 channel = pctxt->warning; 2095 } 2096 schannel = pctxt->serror; 2097 data = pctxt->errCtxt; 2098 __xmlRaiseError(schannel, channel, data, ctxt, 2099 node, XML_FROM_SCHEMASP, error, 2100 errorLevel, NULL, 0, 2101 (const char *) str1, (const char *) str2, 2102 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2103 } else { 2104 TODO 2105 } 2106 } 2107} 2108 2109/** 2110 * xmlSchemaErr3: 2111 * @ctxt: the validation context 2112 * @node: the context node 2113 * @error: the error code 2114 * @msg: the error message 2115 * @str1: extra data 2116 * @str2: extra data 2117 * @str3: extra data 2118 * 2119 * Handle a validation error 2120 */ 2121static void 2122xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2123 int error, xmlNodePtr node, const char *msg, 2124 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2125{ 2126 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2127 msg, str1, str2, str3, NULL); 2128} 2129 2130static void 2131xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2132 int error, xmlNodePtr node, const char *msg, 2133 const xmlChar *str1, const xmlChar *str2, 2134 const xmlChar *str3, const xmlChar *str4) 2135{ 2136 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2137 msg, str1, str2, str3, str4); 2138} 2139 2140static void 2141xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2142 int error, xmlNodePtr node, const char *msg, 2143 const xmlChar *str1, const xmlChar *str2) 2144{ 2145 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2146} 2147 2148static xmlChar * 2149xmlSchemaFormatNodeForError(xmlChar ** msg, 2150 xmlSchemaAbstractCtxtPtr actxt, 2151 xmlNodePtr node) 2152{ 2153 xmlChar *str = NULL; 2154 2155 *msg = NULL; 2156 if ((node != NULL) && 2157 (node->type != XML_ELEMENT_NODE) && 2158 (node->type != XML_ATTRIBUTE_NODE)) 2159 { 2160 /* 2161 * Don't try to format other nodes than element and 2162 * attribute nodes. 2163 * Play save and return an empty string. 2164 */ 2165 *msg = xmlStrdup(BAD_CAST ""); 2166 return(*msg); 2167 } 2168 if (node != NULL) { 2169 /* 2170 * Work on tree nodes. 2171 */ 2172 if (node->type == XML_ATTRIBUTE_NODE) { 2173 xmlNodePtr elem = node->parent; 2174 2175 *msg = xmlStrdup(BAD_CAST "Element '"); 2176 if (elem->ns != NULL) 2177 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2178 elem->ns->href, elem->name)); 2179 else 2180 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2181 NULL, elem->name)); 2182 FREE_AND_NULL(str); 2183 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2184 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2185 } else { 2186 *msg = xmlStrdup(BAD_CAST "Element '"); 2187 } 2188 if (node->ns != NULL) 2189 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2190 node->ns->href, node->name)); 2191 else 2192 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2193 NULL, node->name)); 2194 FREE_AND_NULL(str); 2195 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2196 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2197 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2198 /* 2199 * Work on node infos. 2200 */ 2201 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2202 xmlSchemaNodeInfoPtr ielem = 2203 vctxt->elemInfos[vctxt->depth]; 2204 2205 *msg = xmlStrdup(BAD_CAST "Element '"); 2206 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2207 ielem->nsName, ielem->localName)); 2208 FREE_AND_NULL(str); 2209 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2210 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2211 } else { 2212 *msg = xmlStrdup(BAD_CAST "Element '"); 2213 } 2214 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2215 vctxt->inode->nsName, vctxt->inode->localName)); 2216 FREE_AND_NULL(str); 2217 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2218 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2219 /* 2220 * Hmm, no node while parsing? 2221 * Return an empty string, in case NULL will break something. 2222 */ 2223 *msg = xmlStrdup(BAD_CAST ""); 2224 } else { 2225 TODO 2226 return (NULL); 2227 } 2228 /* 2229 * VAL TODO: The output of the given schema component is currently 2230 * disabled. 2231 */ 2232#if 0 2233 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2234 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2235 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2236 NULL, type, NULL, 0)); 2237 FREE_AND_NULL(str) 2238 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2239 } 2240#endif 2241 return (*msg); 2242} 2243 2244static void 2245xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2246 const char *funcName, 2247 const char *message, 2248 const xmlChar *str1, 2249 const xmlChar *str2) 2250{ 2251 xmlChar *msg = NULL; 2252 2253 if (actxt == NULL) 2254 return; 2255 msg = xmlStrdup(BAD_CAST "Internal error: "); 2256 msg = xmlStrcat(msg, BAD_CAST funcName); 2257 msg = xmlStrcat(msg, BAD_CAST ", "); 2258 msg = xmlStrcat(msg, BAD_CAST message); 2259 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2260 2261 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2262 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, 2263 (const char *) msg, str1, str2); 2264 2265 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2266 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, 2267 (const char *) msg, str1, str2); 2268 2269 FREE_AND_NULL(msg) 2270} 2271 2272static void 2273xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2274 const char *funcName, 2275 const char *message) 2276{ 2277 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2278} 2279 2280#if 0 2281static void 2282xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2283 const char *funcName, 2284 const char *message, 2285 const xmlChar *str1, 2286 const xmlChar *str2) 2287{ 2288 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2289 str1, str2); 2290} 2291#endif 2292 2293static void 2294xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2295 xmlParserErrors error, 2296 xmlNodePtr node, 2297 xmlSchemaBasicItemPtr item, 2298 const char *message, 2299 const xmlChar *str1, const xmlChar *str2, 2300 const xmlChar *str3, const xmlChar *str4) 2301{ 2302 xmlChar *msg = NULL; 2303 2304 if ((node == NULL) && (item != NULL) && 2305 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2306 node = WXS_ITEM_NODE(item); 2307 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2308 msg = xmlStrcat(msg, BAD_CAST ": "); 2309 } else 2310 xmlSchemaFormatNodeForError(&msg, actxt, node); 2311 msg = xmlStrcat(msg, (const xmlChar *) message); 2312 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2313 xmlSchemaErr4(actxt, error, node, 2314 (const char *) msg, str1, str2, str3, str4); 2315 FREE_AND_NULL(msg) 2316} 2317 2318static void 2319xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2320 xmlParserErrors error, 2321 xmlNodePtr node, 2322 xmlSchemaBasicItemPtr item, 2323 const char *message, 2324 const xmlChar *str1, 2325 const xmlChar *str2) 2326{ 2327 xmlSchemaCustomErr4(actxt, error, node, item, 2328 message, str1, str2, NULL, NULL); 2329} 2330 2331 2332 2333static void 2334xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2335 xmlParserErrors error, 2336 xmlNodePtr node, 2337 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2338 const char *message, 2339 const xmlChar *str1, 2340 const xmlChar *str2, 2341 const xmlChar *str3) 2342{ 2343 xmlChar *msg = NULL; 2344 2345 xmlSchemaFormatNodeForError(&msg, actxt, node); 2346 msg = xmlStrcat(msg, (const xmlChar *) message); 2347 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2348 2349 /* URGENT TODO: Set the error code to something sane. */ 2350 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2351 (const char *) msg, str1, str2, str3, NULL); 2352 2353 FREE_AND_NULL(msg) 2354} 2355 2356 2357 2358static void 2359xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2360 xmlParserErrors error, 2361 xmlSchemaPSVIIDCNodePtr idcNode, 2362 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2363 const char *message, 2364 const xmlChar *str1, 2365 const xmlChar *str2) 2366{ 2367 xmlChar *msg = NULL, *qname = NULL; 2368 2369 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2370 msg = xmlStrcat(msg, (const xmlChar *) message); 2371 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2372 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2373 error, NULL, idcNode->nodeLine, (const char *) msg, 2374 xmlSchemaFormatQName(&qname, 2375 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2376 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2377 str1, str2, NULL); 2378 FREE_AND_NULL(qname); 2379 FREE_AND_NULL(msg); 2380} 2381 2382static int 2383xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2384 xmlNodePtr node) 2385{ 2386 if (node != NULL) 2387 return (node->type); 2388 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2389 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2390 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2391 return (-1); 2392} 2393 2394static int 2395xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2396{ 2397 switch (item->type) { 2398 case XML_SCHEMA_TYPE_COMPLEX: 2399 case XML_SCHEMA_TYPE_SIMPLE: 2400 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2401 return(1); 2402 break; 2403 case XML_SCHEMA_TYPE_GROUP: 2404 return (1); 2405 case XML_SCHEMA_TYPE_ELEMENT: 2406 if ( ((xmlSchemaElementPtr) item)->flags & 2407 XML_SCHEMAS_ELEM_GLOBAL) 2408 return(1); 2409 break; 2410 case XML_SCHEMA_TYPE_ATTRIBUTE: 2411 if ( ((xmlSchemaAttributePtr) item)->flags & 2412 XML_SCHEMAS_ATTR_GLOBAL) 2413 return(1); 2414 break; 2415 /* Note that attribute groups are always global. */ 2416 default: 2417 return(1); 2418 } 2419 return (0); 2420} 2421 2422static void 2423xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2424 xmlParserErrors error, 2425 xmlNodePtr node, 2426 const xmlChar *value, 2427 xmlSchemaTypePtr type, 2428 int displayValue) 2429{ 2430 xmlChar *msg = NULL; 2431 2432 xmlSchemaFormatNodeForError(&msg, actxt, node); 2433 2434 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2435 XML_ATTRIBUTE_NODE)) 2436 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2437 else 2438 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2439 "value of "); 2440 2441 if (! xmlSchemaIsGlobalItem(type)) 2442 msg = xmlStrcat(msg, BAD_CAST "the local "); 2443 else 2444 msg = xmlStrcat(msg, BAD_CAST "the "); 2445 2446 if (WXS_IS_ATOMIC(type)) 2447 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2448 else if (WXS_IS_LIST(type)) 2449 msg = xmlStrcat(msg, BAD_CAST "list type"); 2450 else if (WXS_IS_UNION(type)) 2451 msg = xmlStrcat(msg, BAD_CAST "union type"); 2452 2453 if (xmlSchemaIsGlobalItem(type)) { 2454 xmlChar *str = NULL; 2455 msg = xmlStrcat(msg, BAD_CAST " '"); 2456 if (type->builtInType != 0) { 2457 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2458 msg = xmlStrcat(msg, type->name); 2459 } else 2460 msg = xmlStrcat(msg, 2461 xmlSchemaFormatQName(&str, 2462 type->targetNamespace, type->name)); 2463 msg = xmlStrcat(msg, BAD_CAST "'"); 2464 FREE_AND_NULL(str); 2465 } 2466 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2467 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2468 XML_ATTRIBUTE_NODE)) 2469 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2470 else 2471 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2472 FREE_AND_NULL(msg) 2473} 2474 2475static const xmlChar * 2476xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2477 xmlSchemaNodeInfoPtr ni, 2478 xmlNodePtr node) 2479{ 2480 if (node != NULL) { 2481 if (node->ns != NULL) 2482 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2483 else 2484 return (xmlSchemaFormatQName(str, NULL, node->name)); 2485 } else if (ni != NULL) 2486 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2487 return (NULL); 2488} 2489 2490static void 2491xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2492 xmlParserErrors error, 2493 xmlSchemaAttrInfoPtr ni, 2494 xmlNodePtr node) 2495{ 2496 xmlChar *msg = NULL, *str = NULL; 2497 2498 xmlSchemaFormatNodeForError(&msg, actxt, node); 2499 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2500 xmlSchemaErr(actxt, error, node, (const char *) msg, 2501 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2502 NULL); 2503 FREE_AND_NULL(str) 2504 FREE_AND_NULL(msg) 2505} 2506 2507static void 2508xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2509 xmlParserErrors error, 2510 xmlNodePtr node, 2511 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2512 const char *message, 2513 int nbval, 2514 int nbneg, 2515 xmlChar **values) 2516{ 2517 xmlChar *str = NULL, *msg = NULL; 2518 xmlChar *localName, *nsName; 2519 const xmlChar *cur, *end; 2520 int i; 2521 2522 xmlSchemaFormatNodeForError(&msg, actxt, node); 2523 msg = xmlStrcat(msg, (const xmlChar *) message); 2524 msg = xmlStrcat(msg, BAD_CAST "."); 2525 /* 2526 * Note that is does not make sense to report that we have a 2527 * wildcard here, since the wildcard might be unfolded into 2528 * multiple transitions. 2529 */ 2530 if (nbval + nbneg > 0) { 2531 if (nbval + nbneg > 1) { 2532 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2533 } else 2534 str = xmlStrdup(BAD_CAST " Expected is ( "); 2535 nsName = NULL; 2536 2537 for (i = 0; i < nbval + nbneg; i++) { 2538 cur = values[i]; 2539 if (cur == NULL) 2540 continue; 2541 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2542 (cur[3] == ' ')) { 2543 cur += 4; 2544 str = xmlStrcat(str, BAD_CAST "##other"); 2545 } 2546 /* 2547 * Get the local name. 2548 */ 2549 localName = NULL; 2550 2551 end = cur; 2552 if (*end == '*') { 2553 localName = xmlStrdup(BAD_CAST "*"); 2554 end++; 2555 } else { 2556 while ((*end != 0) && (*end != '|')) 2557 end++; 2558 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2559 } 2560 if (*end != 0) { 2561 end++; 2562 /* 2563 * Skip "*|*" if they come with negated expressions, since 2564 * they represent the same negated wildcard. 2565 */ 2566 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2567 /* 2568 * Get the namespace name. 2569 */ 2570 cur = end; 2571 if (*end == '*') { 2572 nsName = xmlStrdup(BAD_CAST "{*}"); 2573 } else { 2574 while (*end != 0) 2575 end++; 2576 2577 if (i >= nbval) 2578 nsName = xmlStrdup(BAD_CAST "{##other:"); 2579 else 2580 nsName = xmlStrdup(BAD_CAST "{"); 2581 2582 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2583 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2584 } 2585 str = xmlStrcat(str, BAD_CAST nsName); 2586 FREE_AND_NULL(nsName) 2587 } else { 2588 FREE_AND_NULL(localName); 2589 continue; 2590 } 2591 } 2592 str = xmlStrcat(str, BAD_CAST localName); 2593 FREE_AND_NULL(localName); 2594 2595 if (i < nbval + nbneg -1) 2596 str = xmlStrcat(str, BAD_CAST ", "); 2597 } 2598 str = xmlStrcat(str, BAD_CAST " ).\n"); 2599 msg = xmlStrcat(msg, BAD_CAST str); 2600 FREE_AND_NULL(str) 2601 } else 2602 msg = xmlStrcat(msg, BAD_CAST "\n"); 2603 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2604 xmlFree(msg); 2605} 2606 2607static void 2608xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2609 xmlParserErrors error, 2610 xmlNodePtr node, 2611 const xmlChar *value, 2612 unsigned long length, 2613 xmlSchemaTypePtr type, 2614 xmlSchemaFacetPtr facet, 2615 const char *message, 2616 const xmlChar *str1, 2617 const xmlChar *str2) 2618{ 2619 xmlChar *str = NULL, *msg = NULL; 2620 xmlSchemaTypeType facetType; 2621 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2622 2623 xmlSchemaFormatNodeForError(&msg, actxt, node); 2624 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2625 facetType = XML_SCHEMA_FACET_ENUMERATION; 2626 /* 2627 * If enumerations are validated, one must not expect the 2628 * facet to be given. 2629 */ 2630 } else 2631 facetType = facet->type; 2632 msg = xmlStrcat(msg, BAD_CAST "["); 2633 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2634 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2635 msg = xmlStrcat(msg, BAD_CAST "'] "); 2636 if (message == NULL) { 2637 /* 2638 * Use a default message. 2639 */ 2640 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2641 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2642 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2643 2644 char len[25], actLen[25]; 2645 2646 /* FIXME, TODO: What is the max expected string length of the 2647 * this value? 2648 */ 2649 if (nodeType == XML_ATTRIBUTE_NODE) 2650 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2651 else 2652 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2653 2654 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2655 snprintf(actLen, 24, "%lu", length); 2656 2657 if (facetType == XML_SCHEMA_FACET_LENGTH) 2658 msg = xmlStrcat(msg, 2659 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2660 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2661 msg = xmlStrcat(msg, 2662 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2663 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2664 msg = xmlStrcat(msg, 2665 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2666 2667 if (nodeType == XML_ATTRIBUTE_NODE) 2668 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2669 value, (const xmlChar *) actLen, (const xmlChar *) len); 2670 else 2671 xmlSchemaErr(actxt, error, node, (const char *) msg, 2672 (const xmlChar *) actLen, (const xmlChar *) len); 2673 2674 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2675 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2676 "of the set {%s}.\n"); 2677 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2678 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2679 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2681 "by the pattern '%s'.\n"); 2682 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2683 facet->value); 2684 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2685 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2686 "minimum value allowed ('%s').\n"); 2687 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2688 facet->value); 2689 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2690 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2691 "maximum value allowed ('%s').\n"); 2692 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2693 facet->value); 2694 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2695 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2696 "'%s'.\n"); 2697 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2698 facet->value); 2699 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2700 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2701 "'%s'.\n"); 2702 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2703 facet->value); 2704 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2706 "digits than are allowed ('%s').\n"); 2707 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2708 facet->value); 2709 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2711 "digits than are allowed ('%s').\n"); 2712 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2713 facet->value); 2714 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2717 } else { 2718 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2719 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2720 } 2721 } else { 2722 msg = xmlStrcat(msg, (const xmlChar *) message); 2723 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2724 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2725 } 2726 FREE_AND_NULL(str) 2727 xmlFree(msg); 2728} 2729 2730#define VERROR(err, type, msg) \ 2731 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2732 2733#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2734 2735#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2736#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2737 2738#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2739 2740 2741/** 2742 * xmlSchemaPMissingAttrErr: 2743 * @ctxt: the schema validation context 2744 * @ownerDes: the designation of the owner 2745 * @ownerName: the name of the owner 2746 * @ownerItem: the owner as a schema object 2747 * @ownerElem: the owner as an element node 2748 * @node: the parent element node of the missing attribute node 2749 * @type: the corresponding type of the attribute node 2750 * 2751 * Reports an illegal attribute. 2752 */ 2753static void 2754xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2755 xmlParserErrors error, 2756 xmlSchemaBasicItemPtr ownerItem, 2757 xmlNodePtr ownerElem, 2758 const char *name, 2759 const char *message) 2760{ 2761 xmlChar *des = NULL; 2762 2763 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2764 2765 if (message != NULL) 2766 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2767 else 2768 xmlSchemaPErr(ctxt, ownerElem, error, 2769 "%s: The attribute '%s' is required but missing.\n", 2770 BAD_CAST des, BAD_CAST name); 2771 FREE_AND_NULL(des); 2772} 2773 2774 2775/** 2776 * xmlSchemaPResCompAttrErr: 2777 * @ctxt: the schema validation context 2778 * @error: the error code 2779 * @ownerDes: the designation of the owner 2780 * @ownerItem: the owner as a schema object 2781 * @ownerElem: the owner as an element node 2782 * @name: the name of the attribute holding the QName 2783 * @refName: the referenced local name 2784 * @refURI: the referenced namespace URI 2785 * @message: optional message 2786 * 2787 * Used to report QName attribute values that failed to resolve 2788 * to schema components. 2789 */ 2790static void 2791xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2792 xmlParserErrors error, 2793 xmlSchemaBasicItemPtr ownerItem, 2794 xmlNodePtr ownerElem, 2795 const char *name, 2796 const xmlChar *refName, 2797 const xmlChar *refURI, 2798 xmlSchemaTypeType refType, 2799 const char *refTypeStr) 2800{ 2801 xmlChar *des = NULL, *strA = NULL; 2802 2803 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2804 if (refTypeStr == NULL) 2805 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2806 xmlSchemaPErrExt(ctxt, ownerElem, error, 2807 NULL, NULL, NULL, 2808 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2809 "%s.\n", BAD_CAST des, BAD_CAST name, 2810 xmlSchemaFormatQName(&strA, refURI, refName), 2811 BAD_CAST refTypeStr, NULL); 2812 FREE_AND_NULL(des) 2813 FREE_AND_NULL(strA) 2814} 2815 2816/** 2817 * xmlSchemaPCustomAttrErr: 2818 * @ctxt: the schema parser context 2819 * @error: the error code 2820 * @ownerDes: the designation of the owner 2821 * @ownerItem: the owner as a schema object 2822 * @attr: the illegal attribute node 2823 * 2824 * Reports an illegal attribute during the parse. 2825 */ 2826static void 2827xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2828 xmlParserErrors error, 2829 xmlChar **ownerDes, 2830 xmlSchemaBasicItemPtr ownerItem, 2831 xmlAttrPtr attr, 2832 const char *msg) 2833{ 2834 xmlChar *des = NULL; 2835 2836 if (ownerDes == NULL) 2837 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2838 else if (*ownerDes == NULL) { 2839 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2840 des = *ownerDes; 2841 } else 2842 des = *ownerDes; 2843 if (attr == NULL) { 2844 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2845 "%s, attribute '%s': %s.\n", 2846 BAD_CAST des, (const xmlChar *) "Unknown", 2847 (const xmlChar *) msg, NULL, NULL); 2848 } else { 2849 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2850 "%s, attribute '%s': %s.\n", 2851 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2852 } 2853 if (ownerDes == NULL) 2854 FREE_AND_NULL(des); 2855} 2856 2857/** 2858 * xmlSchemaPIllegalAttrErr: 2859 * @ctxt: the schema parser context 2860 * @error: the error code 2861 * @ownerDes: the designation of the attribute's owner 2862 * @ownerItem: the attribute's owner item 2863 * @attr: the illegal attribute node 2864 * 2865 * Reports an illegal attribute during the parse. 2866 */ 2867static void 2868xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2869 xmlParserErrors error, 2870 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2871 xmlAttrPtr attr) 2872{ 2873 xmlChar *strA = NULL, *strB = NULL; 2874 2875 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2876 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2877 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2878 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2879 NULL, NULL); 2880 FREE_AND_NULL(strA); 2881 FREE_AND_NULL(strB); 2882} 2883 2884/** 2885 * xmlSchemaPCustomErr: 2886 * @ctxt: the schema parser context 2887 * @error: the error code 2888 * @itemDes: the designation of the schema item 2889 * @item: the schema item 2890 * @itemElem: the node of the schema item 2891 * @message: the error message 2892 * @str1: an optional param for the error message 2893 * @str2: an optional param for the error message 2894 * @str3: an optional param for the error message 2895 * 2896 * Reports an error during parsing. 2897 */ 2898static void 2899xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2900 xmlParserErrors error, 2901 xmlSchemaBasicItemPtr item, 2902 xmlNodePtr itemElem, 2903 const char *message, 2904 const xmlChar *str1, 2905 const xmlChar *str2, 2906 const xmlChar *str3) 2907{ 2908 xmlChar *des = NULL, *msg = NULL; 2909 2910 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2911 msg = xmlStrdup(BAD_CAST "%s: "); 2912 msg = xmlStrcat(msg, (const xmlChar *) message); 2913 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2914 if ((itemElem == NULL) && (item != NULL)) 2915 itemElem = WXS_ITEM_NODE(item); 2916 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2917 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2918 FREE_AND_NULL(des); 2919 FREE_AND_NULL(msg); 2920} 2921 2922/** 2923 * xmlSchemaPCustomErr: 2924 * @ctxt: the schema parser context 2925 * @error: the error code 2926 * @itemDes: the designation of the schema item 2927 * @item: the schema item 2928 * @itemElem: the node of the schema item 2929 * @message: the error message 2930 * @str1: the optional param for the error message 2931 * 2932 * Reports an error during parsing. 2933 */ 2934static void 2935xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2936 xmlParserErrors error, 2937 xmlSchemaBasicItemPtr item, 2938 xmlNodePtr itemElem, 2939 const char *message, 2940 const xmlChar *str1) 2941{ 2942 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2943 str1, NULL, NULL); 2944} 2945 2946/** 2947 * xmlSchemaPAttrUseErr: 2948 * @ctxt: the schema parser context 2949 * @error: the error code 2950 * @itemDes: the designation of the schema type 2951 * @item: the schema type 2952 * @itemElem: the node of the schema type 2953 * @attr: the invalid schema attribute 2954 * @message: the error message 2955 * @str1: the optional param for the error message 2956 * 2957 * Reports an attribute use error during parsing. 2958 */ 2959static void 2960xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2961 xmlParserErrors error, 2962 xmlNodePtr node, 2963 xmlSchemaBasicItemPtr ownerItem, 2964 const xmlSchemaAttributeUsePtr attruse, 2965 const char *message, 2966 const xmlChar *str1, const xmlChar *str2, 2967 const xmlChar *str3,const xmlChar *str4) 2968{ 2969 xmlChar *str = NULL, *msg = NULL; 2970 2971 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 2972 msg = xmlStrcat(msg, BAD_CAST ", "); 2973 msg = xmlStrcat(msg, 2974 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 2975 WXS_BASIC_CAST attruse, NULL)); 2976 FREE_AND_NULL(str); 2977 msg = xmlStrcat(msg, BAD_CAST ": "); 2978 msg = xmlStrcat(msg, (const xmlChar *) message); 2979 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2980 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 2981 (const char *) msg, str1, str2, str3, str4); 2982 xmlFree(msg); 2983} 2984 2985/** 2986 * xmlSchemaPIllegalFacetAtomicErr: 2987 * @ctxt: the schema parser context 2988 * @error: the error code 2989 * @type: the schema type 2990 * @baseType: the base type of type 2991 * @facet: the illegal facet 2992 * 2993 * Reports an illegal facet for atomic simple types. 2994 */ 2995static void 2996xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 2997 xmlParserErrors error, 2998 xmlSchemaTypePtr type, 2999 xmlSchemaTypePtr baseType, 3000 xmlSchemaFacetPtr facet) 3001{ 3002 xmlChar *des = NULL, *strT = NULL; 3003 3004 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3005 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3006 "%s: The facet '%s' is not allowed on types derived from the " 3007 "type %s.\n", 3008 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3009 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3010 NULL, NULL); 3011 FREE_AND_NULL(des); 3012 FREE_AND_NULL(strT); 3013} 3014 3015/** 3016 * xmlSchemaPIllegalFacetListUnionErr: 3017 * @ctxt: the schema parser context 3018 * @error: the error code 3019 * @itemDes: the designation of the schema item involved 3020 * @item: the schema item involved 3021 * @facet: the illegal facet 3022 * 3023 * Reports an illegal facet for <list> and <union>. 3024 */ 3025static void 3026xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3027 xmlParserErrors error, 3028 xmlSchemaTypePtr type, 3029 xmlSchemaFacetPtr facet) 3030{ 3031 xmlChar *des = NULL; 3032 3033 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3034 type->node); 3035 xmlSchemaPErr(ctxt, type->node, error, 3036 "%s: The facet '%s' is not allowed.\n", 3037 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3038 FREE_AND_NULL(des); 3039} 3040 3041/** 3042 * xmlSchemaPMutualExclAttrErr: 3043 * @ctxt: the schema validation context 3044 * @error: the error code 3045 * @elemDes: the designation of the parent element node 3046 * @attr: the bad attribute node 3047 * @type: the corresponding type of the attribute node 3048 * 3049 * Reports an illegal attribute. 3050 */ 3051static void 3052xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3053 xmlParserErrors error, 3054 xmlSchemaBasicItemPtr ownerItem, 3055 xmlAttrPtr attr, 3056 const char *name1, 3057 const char *name2) 3058{ 3059 xmlChar *des = NULL; 3060 3061 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3062 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3063 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3064 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3065 FREE_AND_NULL(des); 3066} 3067 3068/** 3069 * xmlSchemaPSimpleTypeErr: 3070 * @ctxt: the schema validation context 3071 * @error: the error code 3072 * @type: the type specifier 3073 * @ownerDes: the designation of the owner 3074 * @ownerItem: the schema object if existent 3075 * @node: the validated node 3076 * @value: the validated value 3077 * 3078 * Reports a simple type validation error. 3079 * TODO: Should this report the value of an element as well? 3080 */ 3081static void 3082xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3083 xmlParserErrors error, 3084 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3085 xmlNodePtr node, 3086 xmlSchemaTypePtr type, 3087 const char *expected, 3088 const xmlChar *value, 3089 const char *message, 3090 const xmlChar *str1, 3091 const xmlChar *str2) 3092{ 3093 xmlChar *msg = NULL; 3094 3095 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3096 if (message == NULL) { 3097 /* 3098 * Use default messages. 3099 */ 3100 if (type != NULL) { 3101 if (node->type == XML_ATTRIBUTE_NODE) 3102 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3103 else 3104 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3105 "valid value of "); 3106 if (! xmlSchemaIsGlobalItem(type)) 3107 msg = xmlStrcat(msg, BAD_CAST "the local "); 3108 else 3109 msg = xmlStrcat(msg, BAD_CAST "the "); 3110 3111 if (WXS_IS_ATOMIC(type)) 3112 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3113 else if (WXS_IS_LIST(type)) 3114 msg = xmlStrcat(msg, BAD_CAST "list type"); 3115 else if (WXS_IS_UNION(type)) 3116 msg = xmlStrcat(msg, BAD_CAST "union type"); 3117 3118 if (xmlSchemaIsGlobalItem(type)) { 3119 xmlChar *str = NULL; 3120 msg = xmlStrcat(msg, BAD_CAST " '"); 3121 if (type->builtInType != 0) { 3122 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3123 msg = xmlStrcat(msg, type->name); 3124 } else 3125 msg = xmlStrcat(msg, 3126 xmlSchemaFormatQName(&str, 3127 type->targetNamespace, type->name)); 3128 msg = xmlStrcat(msg, BAD_CAST "'."); 3129 FREE_AND_NULL(str); 3130 } 3131 } else { 3132 if (node->type == XML_ATTRIBUTE_NODE) 3133 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3134 else 3135 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3136 "valid."); 3137 } 3138 if (expected) { 3139 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3140 msg = xmlStrcat(msg, BAD_CAST expected); 3141 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3142 } else 3143 msg = xmlStrcat(msg, BAD_CAST "\n"); 3144 if (node->type == XML_ATTRIBUTE_NODE) 3145 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3146 else 3147 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3148 } else { 3149 msg = xmlStrcat(msg, BAD_CAST message); 3150 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3151 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3152 (const char*) msg, str1, str2, NULL, NULL, NULL); 3153 } 3154 /* Cleanup. */ 3155 FREE_AND_NULL(msg) 3156} 3157 3158/** 3159 * xmlSchemaPContentErr: 3160 * @ctxt: the schema parser context 3161 * @error: the error code 3162 * @onwerDes: the designation of the holder of the content 3163 * @ownerItem: the owner item of the holder of the content 3164 * @ownerElem: the node of the holder of the content 3165 * @child: the invalid child node 3166 * @message: the optional error message 3167 * @content: the optional string describing the correct content 3168 * 3169 * Reports an error concerning the content of a schema element. 3170 */ 3171static void 3172xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3173 xmlParserErrors error, 3174 xmlSchemaBasicItemPtr ownerItem, 3175 xmlNodePtr ownerElem, 3176 xmlNodePtr child, 3177 const char *message, 3178 const char *content) 3179{ 3180 xmlChar *des = NULL; 3181 3182 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3183 if (message != NULL) 3184 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3185 "%s: %s.\n", 3186 BAD_CAST des, BAD_CAST message); 3187 else { 3188 if (content != NULL) { 3189 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3190 "%s: The content is not valid. Expected is %s.\n", 3191 BAD_CAST des, BAD_CAST content); 3192 } else { 3193 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3194 "%s: The content is not valid.\n", 3195 BAD_CAST des, NULL); 3196 } 3197 } 3198 FREE_AND_NULL(des) 3199} 3200 3201/************************************************************************ 3202 * * 3203 * Streamable error functions * 3204 * * 3205 ************************************************************************/ 3206 3207 3208 3209 3210/************************************************************************ 3211 * * 3212 * Validation helper functions * 3213 * * 3214 ************************************************************************/ 3215 3216 3217/************************************************************************ 3218 * * 3219 * Allocation functions * 3220 * * 3221 ************************************************************************/ 3222 3223/** 3224 * xmlSchemaNewSchemaForParserCtxt: 3225 * @ctxt: a schema validation context 3226 * 3227 * Allocate a new Schema structure. 3228 * 3229 * Returns the newly allocated structure or NULL in case or error 3230 */ 3231static xmlSchemaPtr 3232xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3233{ 3234 xmlSchemaPtr ret; 3235 3236 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3237 if (ret == NULL) { 3238 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3239 return (NULL); 3240 } 3241 memset(ret, 0, sizeof(xmlSchema)); 3242 ret->dict = ctxt->dict; 3243 xmlDictReference(ret->dict); 3244 3245 return (ret); 3246} 3247 3248/** 3249 * xmlSchemaNewFacet: 3250 * 3251 * Allocate a new Facet structure. 3252 * 3253 * Returns the newly allocated structure or NULL in case or error 3254 */ 3255xmlSchemaFacetPtr 3256xmlSchemaNewFacet(void) 3257{ 3258 xmlSchemaFacetPtr ret; 3259 3260 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3261 if (ret == NULL) { 3262 return (NULL); 3263 } 3264 memset(ret, 0, sizeof(xmlSchemaFacet)); 3265 3266 return (ret); 3267} 3268 3269/** 3270 * xmlSchemaNewAnnot: 3271 * @ctxt: a schema validation context 3272 * @node: a node 3273 * 3274 * Allocate a new annotation structure. 3275 * 3276 * Returns the newly allocated structure or NULL in case or error 3277 */ 3278static xmlSchemaAnnotPtr 3279xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3280{ 3281 xmlSchemaAnnotPtr ret; 3282 3283 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3284 if (ret == NULL) { 3285 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3286 return (NULL); 3287 } 3288 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3289 ret->content = node; 3290 return (ret); 3291} 3292 3293static xmlSchemaItemListPtr 3294xmlSchemaItemListCreate(void) 3295{ 3296 xmlSchemaItemListPtr ret; 3297 3298 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3299 if (ret == NULL) { 3300 xmlSchemaPErrMemory(NULL, 3301 "allocating an item list structure", NULL); 3302 return (NULL); 3303 } 3304 memset(ret, 0, sizeof(xmlSchemaItemList)); 3305 return (ret); 3306} 3307 3308static void 3309xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3310{ 3311 if (list->items != NULL) { 3312 xmlFree(list->items); 3313 list->items = NULL; 3314 } 3315 list->nbItems = 0; 3316 list->sizeItems = 0; 3317} 3318 3319static int 3320xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3321{ 3322 if (list->items == NULL) { 3323 list->items = (void **) xmlMalloc( 3324 20 * sizeof(void *)); 3325 if (list->items == NULL) { 3326 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3327 return(-1); 3328 } 3329 list->sizeItems = 20; 3330 } else if (list->sizeItems <= list->nbItems) { 3331 list->sizeItems *= 2; 3332 list->items = (void **) xmlRealloc(list->items, 3333 list->sizeItems * sizeof(void *)); 3334 if (list->items == NULL) { 3335 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3336 list->sizeItems = 0; 3337 return(-1); 3338 } 3339 } 3340 list->items[list->nbItems++] = item; 3341 return(0); 3342} 3343 3344static int 3345xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3346 int initialSize, 3347 void *item) 3348{ 3349 if (list->items == NULL) { 3350 if (initialSize <= 0) 3351 initialSize = 1; 3352 list->items = (void **) xmlMalloc( 3353 initialSize * sizeof(void *)); 3354 if (list->items == NULL) { 3355 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3356 return(-1); 3357 } 3358 list->sizeItems = initialSize; 3359 } else if (list->sizeItems <= list->nbItems) { 3360 list->sizeItems *= 2; 3361 list->items = (void **) xmlRealloc(list->items, 3362 list->sizeItems * sizeof(void *)); 3363 if (list->items == NULL) { 3364 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3365 list->sizeItems = 0; 3366 return(-1); 3367 } 3368 } 3369 list->items[list->nbItems++] = item; 3370 return(0); 3371} 3372 3373static int 3374xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3375{ 3376 if (list->items == NULL) { 3377 list->items = (void **) xmlMalloc( 3378 20 * sizeof(void *)); 3379 if (list->items == NULL) { 3380 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3381 return(-1); 3382 } 3383 list->sizeItems = 20; 3384 } else if (list->sizeItems <= list->nbItems) { 3385 list->sizeItems *= 2; 3386 list->items = (void **) xmlRealloc(list->items, 3387 list->sizeItems * sizeof(void *)); 3388 if (list->items == NULL) { 3389 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3390 list->sizeItems = 0; 3391 return(-1); 3392 } 3393 } 3394 /* 3395 * Just append if the index is greater/equal than the item count. 3396 */ 3397 if (idx >= list->nbItems) { 3398 list->items[list->nbItems++] = item; 3399 } else { 3400 int i; 3401 for (i = list->nbItems; i > idx; i--) 3402 list->items[i] = list->items[i-1]; 3403 list->items[idx] = item; 3404 list->nbItems++; 3405 } 3406 return(0); 3407} 3408 3409#if 0 /* enable if ever needed */ 3410static int 3411xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3412 int initialSize, 3413 void *item, 3414 int idx) 3415{ 3416 if (list->items == NULL) { 3417 if (initialSize <= 0) 3418 initialSize = 1; 3419 list->items = (void **) xmlMalloc( 3420 initialSize * sizeof(void *)); 3421 if (list->items == NULL) { 3422 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3423 return(-1); 3424 } 3425 list->sizeItems = initialSize; 3426 } else if (list->sizeItems <= list->nbItems) { 3427 list->sizeItems *= 2; 3428 list->items = (void **) xmlRealloc(list->items, 3429 list->sizeItems * sizeof(void *)); 3430 if (list->items == NULL) { 3431 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3432 list->sizeItems = 0; 3433 return(-1); 3434 } 3435 } 3436 /* 3437 * Just append if the index is greater/equal than the item count. 3438 */ 3439 if (idx >= list->nbItems) { 3440 list->items[list->nbItems++] = item; 3441 } else { 3442 int i; 3443 for (i = list->nbItems; i > idx; i--) 3444 list->items[i] = list->items[i-1]; 3445 list->items[idx] = item; 3446 list->nbItems++; 3447 } 3448 return(0); 3449} 3450#endif 3451 3452static int 3453xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3454{ 3455 int i; 3456 if ((list->items == NULL) || (idx >= list->nbItems)) { 3457 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3458 "index error.\n"); 3459 return(-1); 3460 } 3461 3462 if (list->nbItems == 1) { 3463 /* TODO: Really free the list? */ 3464 xmlFree(list->items); 3465 list->items = NULL; 3466 list->nbItems = 0; 3467 list->sizeItems = 0; 3468 } else if (list->nbItems -1 == idx) { 3469 list->nbItems--; 3470 } else { 3471 for (i = idx; i < list->nbItems -1; i++) 3472 list->items[i] = list->items[i+1]; 3473 list->nbItems--; 3474 } 3475 return(0); 3476} 3477 3478/** 3479 * xmlSchemaItemListFree: 3480 * @annot: a schema type structure 3481 * 3482 * Deallocate a annotation structure 3483 */ 3484static void 3485xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3486{ 3487 if (list == NULL) 3488 return; 3489 if (list->items != NULL) 3490 xmlFree(list->items); 3491 xmlFree(list); 3492} 3493 3494static void 3495xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3496{ 3497 if (bucket == NULL) 3498 return; 3499 if (bucket->globals != NULL) { 3500 xmlSchemaComponentListFree(bucket->globals); 3501 xmlSchemaItemListFree(bucket->globals); 3502 } 3503 if (bucket->locals != NULL) { 3504 xmlSchemaComponentListFree(bucket->locals); 3505 xmlSchemaItemListFree(bucket->locals); 3506 } 3507 if (bucket->relations != NULL) { 3508 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3509 do { 3510 prev = cur; 3511 cur = cur->next; 3512 xmlFree(prev); 3513 } while (cur != NULL); 3514 } 3515 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3516 xmlFreeDoc(bucket->doc); 3517 } 3518 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3519 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3520 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3521 } 3522 xmlFree(bucket); 3523} 3524 3525static xmlSchemaBucketPtr 3526xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3527 int type, const xmlChar *targetNamespace) 3528{ 3529 xmlSchemaBucketPtr ret; 3530 int size; 3531 xmlSchemaPtr mainSchema; 3532 3533 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3534 PERROR_INT("xmlSchemaBucketCreate", 3535 "no main schema on constructor"); 3536 return(NULL); 3537 } 3538 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3539 /* Create the schema bucket. */ 3540 if (WXS_IS_BUCKET_INCREDEF(type)) 3541 size = sizeof(xmlSchemaInclude); 3542 else 3543 size = sizeof(xmlSchemaImport); 3544 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3545 if (ret == NULL) { 3546 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3547 return(NULL); 3548 } 3549 memset(ret, 0, size); 3550 ret->targetNamespace = targetNamespace; 3551 ret->type = type; 3552 ret->globals = xmlSchemaItemListCreate(); 3553 if (ret->globals == NULL) { 3554 xmlFree(ret); 3555 return(NULL); 3556 } 3557 ret->locals = xmlSchemaItemListCreate(); 3558 if (ret->locals == NULL) { 3559 xmlFree(ret); 3560 return(NULL); 3561 } 3562 /* 3563 * The following will assure that only the first bucket is marked as 3564 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3565 * For each following import buckets an xmlSchema will be created. 3566 * An xmlSchema will be created for every distinct targetNamespace. 3567 * We assign the targetNamespace to the schemata here. 3568 */ 3569 if (! WXS_HAS_BUCKETS(pctxt)) { 3570 if (WXS_IS_BUCKET_INCREDEF(type)) { 3571 PERROR_INT("xmlSchemaBucketCreate", 3572 "first bucket but it's an include or redefine"); 3573 xmlSchemaBucketFree(ret); 3574 return(NULL); 3575 } 3576 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3577 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3578 /* Point to the *main* schema. */ 3579 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3580 WXS_IMPBUCKET(ret)->schema = mainSchema; 3581 /* 3582 * Ensure that the main schema gets a targetNamespace. 3583 */ 3584 mainSchema->targetNamespace = targetNamespace; 3585 } else { 3586 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3587 PERROR_INT("xmlSchemaBucketCreate", 3588 "main bucket but it's not the first one"); 3589 xmlSchemaBucketFree(ret); 3590 return(NULL); 3591 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3592 /* 3593 * Create a schema for imports and assign the 3594 * targetNamespace. 3595 */ 3596 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3597 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3598 xmlSchemaBucketFree(ret); 3599 return(NULL); 3600 } 3601 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3602 } 3603 } 3604 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3605 int res; 3606 /* 3607 * Imports go into the "schemasImports" slot of the main *schema*. 3608 * Note that we create an import entry for the main schema as well; i.e., 3609 * even if there's only one schema, we'll get an import. 3610 */ 3611 if (mainSchema->schemasImports == NULL) { 3612 mainSchema->schemasImports = xmlHashCreateDict(5, 3613 WXS_CONSTRUCTOR(pctxt)->dict); 3614 if (mainSchema->schemasImports == NULL) { 3615 xmlSchemaBucketFree(ret); 3616 return(NULL); 3617 } 3618 } 3619 if (targetNamespace == NULL) 3620 res = xmlHashAddEntry(mainSchema->schemasImports, 3621 XML_SCHEMAS_NO_NAMESPACE, ret); 3622 else 3623 res = xmlHashAddEntry(mainSchema->schemasImports, 3624 targetNamespace, ret); 3625 if (res != 0) { 3626 PERROR_INT("xmlSchemaBucketCreate", 3627 "failed to add the schema bucket to the hash"); 3628 xmlSchemaBucketFree(ret); 3629 return(NULL); 3630 } 3631 } else { 3632 /* Set the @ownerImport of an include bucket. */ 3633 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3634 WXS_INCBUCKET(ret)->ownerImport = 3635 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3636 else 3637 WXS_INCBUCKET(ret)->ownerImport = 3638 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3639 3640 /* Includes got into the "includes" slot of the *main* schema. */ 3641 if (mainSchema->includes == NULL) { 3642 mainSchema->includes = xmlSchemaItemListCreate(); 3643 if (mainSchema->includes == NULL) { 3644 xmlSchemaBucketFree(ret); 3645 return(NULL); 3646 } 3647 } 3648 xmlSchemaItemListAdd(mainSchema->includes, ret); 3649 } 3650 /* 3651 * Add to list of all buckets; this is used for lookup 3652 * during schema construction time only. 3653 */ 3654 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3655 return(NULL); 3656 return(ret); 3657} 3658 3659static int 3660xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3661{ 3662 if (*list == NULL) { 3663 *list = xmlSchemaItemListCreate(); 3664 if (*list == NULL) 3665 return(-1); 3666 } 3667 xmlSchemaItemListAddSize(*list, initialSize, item); 3668 return(0); 3669} 3670 3671/** 3672 * xmlSchemaFreeAnnot: 3673 * @annot: a schema type structure 3674 * 3675 * Deallocate a annotation structure 3676 */ 3677static void 3678xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3679{ 3680 if (annot == NULL) 3681 return; 3682 if (annot->next == NULL) { 3683 xmlFree(annot); 3684 } else { 3685 xmlSchemaAnnotPtr prev; 3686 3687 do { 3688 prev = annot; 3689 annot = annot->next; 3690 xmlFree(prev); 3691 } while (annot != NULL); 3692 } 3693} 3694 3695/** 3696 * xmlSchemaFreeNotation: 3697 * @schema: a schema notation structure 3698 * 3699 * Deallocate a Schema Notation structure. 3700 */ 3701static void 3702xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3703{ 3704 if (nota == NULL) 3705 return; 3706 xmlFree(nota); 3707} 3708 3709/** 3710 * xmlSchemaFreeAttribute: 3711 * @attr: an attribute declaration 3712 * 3713 * Deallocates an attribute declaration structure. 3714 */ 3715static void 3716xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3717{ 3718 if (attr == NULL) 3719 return; 3720 if (attr->annot != NULL) 3721 xmlSchemaFreeAnnot(attr->annot); 3722 if (attr->defVal != NULL) 3723 xmlSchemaFreeValue(attr->defVal); 3724 xmlFree(attr); 3725} 3726 3727/** 3728 * xmlSchemaFreeAttributeUse: 3729 * @use: an attribute use 3730 * 3731 * Deallocates an attribute use structure. 3732 */ 3733static void 3734xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3735{ 3736 if (use == NULL) 3737 return; 3738 if (use->annot != NULL) 3739 xmlSchemaFreeAnnot(use->annot); 3740 if (use->defVal != NULL) 3741 xmlSchemaFreeValue(use->defVal); 3742 xmlFree(use); 3743} 3744 3745/** 3746 * xmlSchemaFreeAttributeUseProhib: 3747 * @prohib: an attribute use prohibition 3748 * 3749 * Deallocates an attribute use structure. 3750 */ 3751static void 3752xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3753{ 3754 if (prohib == NULL) 3755 return; 3756 xmlFree(prohib); 3757} 3758 3759/** 3760 * xmlSchemaFreeWildcardNsSet: 3761 * set: a schema wildcard namespace 3762 * 3763 * Deallocates a list of wildcard constraint structures. 3764 */ 3765static void 3766xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3767{ 3768 xmlSchemaWildcardNsPtr next; 3769 3770 while (set != NULL) { 3771 next = set->next; 3772 xmlFree(set); 3773 set = next; 3774 } 3775} 3776 3777/** 3778 * xmlSchemaFreeWildcard: 3779 * @wildcard: a wildcard structure 3780 * 3781 * Deallocates a wildcard structure. 3782 */ 3783void 3784xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3785{ 3786 if (wildcard == NULL) 3787 return; 3788 if (wildcard->annot != NULL) 3789 xmlSchemaFreeAnnot(wildcard->annot); 3790 if (wildcard->nsSet != NULL) 3791 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3792 if (wildcard->negNsSet != NULL) 3793 xmlFree(wildcard->negNsSet); 3794 xmlFree(wildcard); 3795} 3796 3797/** 3798 * xmlSchemaFreeAttributeGroup: 3799 * @schema: a schema attribute group structure 3800 * 3801 * Deallocate a Schema Attribute Group structure. 3802 */ 3803static void 3804xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3805{ 3806 if (attrGr == NULL) 3807 return; 3808 if (attrGr->annot != NULL) 3809 xmlSchemaFreeAnnot(attrGr->annot); 3810 if (attrGr->attrUses != NULL) 3811 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3812 xmlFree(attrGr); 3813} 3814 3815/** 3816 * xmlSchemaFreeQNameRef: 3817 * @item: a QName reference structure 3818 * 3819 * Deallocatea a QName reference structure. 3820 */ 3821static void 3822xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3823{ 3824 xmlFree(item); 3825} 3826 3827/** 3828 * xmlSchemaFreeTypeLinkList: 3829 * @alink: a type link 3830 * 3831 * Deallocate a list of types. 3832 */ 3833static void 3834xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3835{ 3836 xmlSchemaTypeLinkPtr next; 3837 3838 while (link != NULL) { 3839 next = link->next; 3840 xmlFree(link); 3841 link = next; 3842 } 3843} 3844 3845static void 3846xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3847{ 3848 xmlSchemaIDCStateObjPtr next; 3849 while (sto != NULL) { 3850 next = sto->next; 3851 if (sto->history != NULL) 3852 xmlFree(sto->history); 3853 if (sto->xpathCtxt != NULL) 3854 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3855 xmlFree(sto); 3856 sto = next; 3857 } 3858} 3859 3860/** 3861 * xmlSchemaFreeIDC: 3862 * @idc: a identity-constraint definition 3863 * 3864 * Deallocates an identity-constraint definition. 3865 */ 3866static void 3867xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3868{ 3869 xmlSchemaIDCSelectPtr cur, prev; 3870 3871 if (idcDef == NULL) 3872 return; 3873 if (idcDef->annot != NULL) 3874 xmlSchemaFreeAnnot(idcDef->annot); 3875 /* Selector */ 3876 if (idcDef->selector != NULL) { 3877 if (idcDef->selector->xpathComp != NULL) 3878 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3879 xmlFree(idcDef->selector); 3880 } 3881 /* Fields */ 3882 if (idcDef->fields != NULL) { 3883 cur = idcDef->fields; 3884 do { 3885 prev = cur; 3886 cur = cur->next; 3887 if (prev->xpathComp != NULL) 3888 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3889 xmlFree(prev); 3890 } while (cur != NULL); 3891 } 3892 xmlFree(idcDef); 3893} 3894 3895/** 3896 * xmlSchemaFreeElement: 3897 * @schema: a schema element structure 3898 * 3899 * Deallocate a Schema Element structure. 3900 */ 3901static void 3902xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3903{ 3904 if (elem == NULL) 3905 return; 3906 if (elem->annot != NULL) 3907 xmlSchemaFreeAnnot(elem->annot); 3908 if (elem->contModel != NULL) 3909 xmlRegFreeRegexp(elem->contModel); 3910 if (elem->defVal != NULL) 3911 xmlSchemaFreeValue(elem->defVal); 3912 xmlFree(elem); 3913} 3914 3915/** 3916 * xmlSchemaFreeFacet: 3917 * @facet: a schema facet structure 3918 * 3919 * Deallocate a Schema Facet structure. 3920 */ 3921void 3922xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3923{ 3924 if (facet == NULL) 3925 return; 3926 if (facet->val != NULL) 3927 xmlSchemaFreeValue(facet->val); 3928 if (facet->regexp != NULL) 3929 xmlRegFreeRegexp(facet->regexp); 3930 if (facet->annot != NULL) 3931 xmlSchemaFreeAnnot(facet->annot); 3932 xmlFree(facet); 3933} 3934 3935/** 3936 * xmlSchemaFreeType: 3937 * @type: a schema type structure 3938 * 3939 * Deallocate a Schema Type structure. 3940 */ 3941void 3942xmlSchemaFreeType(xmlSchemaTypePtr type) 3943{ 3944 if (type == NULL) 3945 return; 3946 if (type->annot != NULL) 3947 xmlSchemaFreeAnnot(type->annot); 3948 if (type->facets != NULL) { 3949 xmlSchemaFacetPtr facet, next; 3950 3951 facet = type->facets; 3952 while (facet != NULL) { 3953 next = facet->next; 3954 xmlSchemaFreeFacet(facet); 3955 facet = next; 3956 } 3957 } 3958 if (type->attrUses != NULL) 3959 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3960 if (type->memberTypes != NULL) 3961 xmlSchemaFreeTypeLinkList(type->memberTypes); 3962 if (type->facetSet != NULL) { 3963 xmlSchemaFacetLinkPtr next, link; 3964 3965 link = type->facetSet; 3966 do { 3967 next = link->next; 3968 xmlFree(link); 3969 link = next; 3970 } while (link != NULL); 3971 } 3972 if (type->contModel != NULL) 3973 xmlRegFreeRegexp(type->contModel); 3974 xmlFree(type); 3975} 3976 3977/** 3978 * xmlSchemaFreeModelGroupDef: 3979 * @item: a schema model group definition 3980 * 3981 * Deallocates a schema model group definition. 3982 */ 3983static void 3984xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 3985{ 3986 if (item->annot != NULL) 3987 xmlSchemaFreeAnnot(item->annot); 3988 xmlFree(item); 3989} 3990 3991/** 3992 * xmlSchemaFreeModelGroup: 3993 * @item: a schema model group 3994 * 3995 * Deallocates a schema model group structure. 3996 */ 3997static void 3998xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 3999{ 4000 if (item->annot != NULL) 4001 xmlSchemaFreeAnnot(item->annot); 4002 xmlFree(item); 4003} 4004 4005static void 4006xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4007{ 4008 if ((list == NULL) || (list->nbItems == 0)) 4009 return; 4010 { 4011 xmlSchemaTreeItemPtr item; 4012 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4013 int i; 4014 4015 for (i = 0; i < list->nbItems; i++) { 4016 item = items[i]; 4017 if (item == NULL) 4018 continue; 4019 switch (item->type) { 4020 case XML_SCHEMA_TYPE_SIMPLE: 4021 case XML_SCHEMA_TYPE_COMPLEX: 4022 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4023 break; 4024 case XML_SCHEMA_TYPE_ATTRIBUTE: 4025 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4026 break; 4027 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4028 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4029 break; 4030 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4031 xmlSchemaFreeAttributeUseProhib( 4032 (xmlSchemaAttributeUseProhibPtr) item); 4033 break; 4034 case XML_SCHEMA_TYPE_ELEMENT: 4035 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4036 break; 4037 case XML_SCHEMA_TYPE_PARTICLE: 4038 if (item->annot != NULL) 4039 xmlSchemaFreeAnnot(item->annot); 4040 xmlFree(item); 4041 break; 4042 case XML_SCHEMA_TYPE_SEQUENCE: 4043 case XML_SCHEMA_TYPE_CHOICE: 4044 case XML_SCHEMA_TYPE_ALL: 4045 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4046 break; 4047 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4048 xmlSchemaFreeAttributeGroup( 4049 (xmlSchemaAttributeGroupPtr) item); 4050 break; 4051 case XML_SCHEMA_TYPE_GROUP: 4052 xmlSchemaFreeModelGroupDef( 4053 (xmlSchemaModelGroupDefPtr) item); 4054 break; 4055 case XML_SCHEMA_TYPE_ANY: 4056 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4057 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4058 break; 4059 case XML_SCHEMA_TYPE_IDC_KEY: 4060 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4061 case XML_SCHEMA_TYPE_IDC_KEYREF: 4062 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4063 break; 4064 case XML_SCHEMA_TYPE_NOTATION: 4065 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4066 break; 4067 case XML_SCHEMA_EXTRA_QNAMEREF: 4068 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4069 break; 4070 default: { 4071 /* TODO: This should never be hit. */ 4072 xmlSchemaPSimpleInternalErr(NULL, 4073 "Internal error: xmlSchemaComponentListFree, " 4074 "unexpected component type '%s'\n", 4075 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4076 } 4077 break; 4078 } 4079 } 4080 list->nbItems = 0; 4081 } 4082} 4083 4084/** 4085 * xmlSchemaFree: 4086 * @schema: a schema structure 4087 * 4088 * Deallocate a Schema structure. 4089 */ 4090void 4091xmlSchemaFree(xmlSchemaPtr schema) 4092{ 4093 if (schema == NULL) 4094 return; 4095 /* @volatiles is not used anymore :-/ */ 4096 if (schema->volatiles != NULL) 4097 TODO 4098 /* 4099 * Note that those slots are not responsible for freeing 4100 * schema components anymore; this will now be done by 4101 * the schema buckets. 4102 */ 4103 if (schema->notaDecl != NULL) 4104 xmlHashFree(schema->notaDecl, NULL); 4105 if (schema->attrDecl != NULL) 4106 xmlHashFree(schema->attrDecl, NULL); 4107 if (schema->attrgrpDecl != NULL) 4108 xmlHashFree(schema->attrgrpDecl, NULL); 4109 if (schema->elemDecl != NULL) 4110 xmlHashFree(schema->elemDecl, NULL); 4111 if (schema->typeDecl != NULL) 4112 xmlHashFree(schema->typeDecl, NULL); 4113 if (schema->groupDecl != NULL) 4114 xmlHashFree(schema->groupDecl, NULL); 4115 if (schema->idcDef != NULL) 4116 xmlHashFree(schema->idcDef, NULL); 4117 4118 if (schema->schemasImports != NULL) 4119 xmlHashFree(schema->schemasImports, 4120 (xmlHashDeallocator) xmlSchemaBucketFree); 4121 if (schema->includes != NULL) { 4122 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4123 int i; 4124 for (i = 0; i < list->nbItems; i++) { 4125 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4126 } 4127 xmlSchemaItemListFree(list); 4128 } 4129 if (schema->annot != NULL) 4130 xmlSchemaFreeAnnot(schema->annot); 4131 /* Never free the doc here, since this will be done by the buckets. */ 4132 4133 xmlDictFree(schema->dict); 4134 xmlFree(schema); 4135} 4136 4137/************************************************************************ 4138 * * 4139 * Debug functions * 4140 * * 4141 ************************************************************************/ 4142 4143#ifdef LIBXML_OUTPUT_ENABLED 4144 4145static void 4146xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4147 4148/** 4149 * xmlSchemaElementDump: 4150 * @elem: an element 4151 * @output: the file output 4152 * 4153 * Dump the element 4154 */ 4155static void 4156xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4157 const xmlChar * name ATTRIBUTE_UNUSED, 4158 const xmlChar * namespace ATTRIBUTE_UNUSED, 4159 const xmlChar * context ATTRIBUTE_UNUSED) 4160{ 4161 if (elem == NULL) 4162 return; 4163 4164 4165 fprintf(output, "Element"); 4166 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4167 fprintf(output, " (global)"); 4168 fprintf(output, ": '%s' ", elem->name); 4169 if (namespace != NULL) 4170 fprintf(output, "ns '%s'", namespace); 4171 fprintf(output, "\n"); 4172#if 0 4173 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4174 fprintf(output, " min %d ", elem->minOccurs); 4175 if (elem->maxOccurs >= UNBOUNDED) 4176 fprintf(output, "max: unbounded\n"); 4177 else if (elem->maxOccurs != 1) 4178 fprintf(output, "max: %d\n", elem->maxOccurs); 4179 else 4180 fprintf(output, "\n"); 4181 } 4182#endif 4183 /* 4184 * Misc other properties. 4185 */ 4186 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4187 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4188 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4189 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4190 fprintf(output, " props: "); 4191 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4192 fprintf(output, "[fixed] "); 4193 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4194 fprintf(output, "[default] "); 4195 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4196 fprintf(output, "[abstract] "); 4197 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4198 fprintf(output, "[nillable] "); 4199 fprintf(output, "\n"); 4200 } 4201 /* 4202 * Default/fixed value. 4203 */ 4204 if (elem->value != NULL) 4205 fprintf(output, " value: '%s'\n", elem->value); 4206 /* 4207 * Type. 4208 */ 4209 if (elem->namedType != NULL) { 4210 fprintf(output, " type: '%s' ", elem->namedType); 4211 if (elem->namedTypeNs != NULL) 4212 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4213 else 4214 fprintf(output, "\n"); 4215 } else if (elem->subtypes != NULL) { 4216 /* 4217 * Dump local types. 4218 */ 4219 xmlSchemaTypeDump(elem->subtypes, output); 4220 } 4221 /* 4222 * Substitution group. 4223 */ 4224 if (elem->substGroup != NULL) { 4225 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4226 if (elem->substGroupNs != NULL) 4227 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4228 else 4229 fprintf(output, "\n"); 4230 } 4231} 4232 4233/** 4234 * xmlSchemaAnnotDump: 4235 * @output: the file output 4236 * @annot: a annotation 4237 * 4238 * Dump the annotation 4239 */ 4240static void 4241xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4242{ 4243 xmlChar *content; 4244 4245 if (annot == NULL) 4246 return; 4247 4248 content = xmlNodeGetContent(annot->content); 4249 if (content != NULL) { 4250 fprintf(output, " Annot: %s\n", content); 4251 xmlFree(content); 4252 } else 4253 fprintf(output, " Annot: empty\n"); 4254} 4255 4256/** 4257 * xmlSchemaContentModelDump: 4258 * @particle: the schema particle 4259 * @output: the file output 4260 * @depth: the depth used for intentation 4261 * 4262 * Dump a SchemaType structure 4263 */ 4264static void 4265xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4266{ 4267 xmlChar *str = NULL; 4268 xmlSchemaTreeItemPtr term; 4269 char shift[100]; 4270 int i; 4271 4272 if (particle == NULL) 4273 return; 4274 for (i = 0;((i < depth) && (i < 25));i++) 4275 shift[2 * i] = shift[2 * i + 1] = ' '; 4276 shift[2 * i] = shift[2 * i + 1] = 0; 4277 fprintf(output, shift); 4278 if (particle->children == NULL) { 4279 fprintf(output, "MISSING particle term\n"); 4280 return; 4281 } 4282 term = particle->children; 4283 if (term == NULL) { 4284 fprintf(output, "(NULL)"); 4285 } else { 4286 switch (term->type) { 4287 case XML_SCHEMA_TYPE_ELEMENT: 4288 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4289 ((xmlSchemaElementPtr)term)->targetNamespace, 4290 ((xmlSchemaElementPtr)term)->name)); 4291 FREE_AND_NULL(str); 4292 break; 4293 case XML_SCHEMA_TYPE_SEQUENCE: 4294 fprintf(output, "SEQUENCE"); 4295 break; 4296 case XML_SCHEMA_TYPE_CHOICE: 4297 fprintf(output, "CHOICE"); 4298 break; 4299 case XML_SCHEMA_TYPE_ALL: 4300 fprintf(output, "ALL"); 4301 break; 4302 case XML_SCHEMA_TYPE_ANY: 4303 fprintf(output, "ANY"); 4304 break; 4305 default: 4306 fprintf(output, "UNKNOWN\n"); 4307 return; 4308 } 4309 } 4310 if (particle->minOccurs != 1) 4311 fprintf(output, " min: %d", particle->minOccurs); 4312 if (particle->maxOccurs >= UNBOUNDED) 4313 fprintf(output, " max: unbounded"); 4314 else if (particle->maxOccurs != 1) 4315 fprintf(output, " max: %d", particle->maxOccurs); 4316 fprintf(output, "\n"); 4317 if (term && 4318 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4319 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4320 (term->type == XML_SCHEMA_TYPE_ALL)) && 4321 (term->children != NULL)) { 4322 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4323 output, depth +1); 4324 } 4325 if (particle->next != NULL) 4326 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4327 output, depth); 4328} 4329 4330/** 4331 * xmlSchemaAttrUsesDump: 4332 * @uses: attribute uses list 4333 * @output: the file output 4334 * 4335 * Dumps a list of attribute use components. 4336 */ 4337static void 4338xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4339{ 4340 xmlSchemaAttributeUsePtr use; 4341 xmlSchemaAttributeUseProhibPtr prohib; 4342 xmlSchemaQNameRefPtr ref; 4343 const xmlChar *name, *tns; 4344 xmlChar *str = NULL; 4345 int i; 4346 4347 if ((uses == NULL) || (uses->nbItems == 0)) 4348 return; 4349 4350 fprintf(output, " attributes:\n"); 4351 for (i = 0; i < uses->nbItems; i++) { 4352 use = uses->items[i]; 4353 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4354 fprintf(output, " [prohibition] "); 4355 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4356 name = prohib->name; 4357 tns = prohib->targetNamespace; 4358 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4359 fprintf(output, " [reference] "); 4360 ref = (xmlSchemaQNameRefPtr) use; 4361 name = ref->name; 4362 tns = ref->targetNamespace; 4363 } else { 4364 fprintf(output, " [use] "); 4365 name = WXS_ATTRUSE_DECL_NAME(use); 4366 tns = WXS_ATTRUSE_DECL_TNS(use); 4367 } 4368 fprintf(output, "'%s'\n", 4369 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4370 FREE_AND_NULL(str); 4371 } 4372} 4373 4374/** 4375 * xmlSchemaTypeDump: 4376 * @output: the file output 4377 * @type: a type structure 4378 * 4379 * Dump a SchemaType structure 4380 */ 4381static void 4382xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4383{ 4384 if (type == NULL) { 4385 fprintf(output, "Type: NULL\n"); 4386 return; 4387 } 4388 fprintf(output, "Type: "); 4389 if (type->name != NULL) 4390 fprintf(output, "'%s' ", type->name); 4391 else 4392 fprintf(output, "(no name) "); 4393 if (type->targetNamespace != NULL) 4394 fprintf(output, "ns '%s' ", type->targetNamespace); 4395 switch (type->type) { 4396 case XML_SCHEMA_TYPE_BASIC: 4397 fprintf(output, "[basic] "); 4398 break; 4399 case XML_SCHEMA_TYPE_SIMPLE: 4400 fprintf(output, "[simple] "); 4401 break; 4402 case XML_SCHEMA_TYPE_COMPLEX: 4403 fprintf(output, "[complex] "); 4404 break; 4405 case XML_SCHEMA_TYPE_SEQUENCE: 4406 fprintf(output, "[sequence] "); 4407 break; 4408 case XML_SCHEMA_TYPE_CHOICE: 4409 fprintf(output, "[choice] "); 4410 break; 4411 case XML_SCHEMA_TYPE_ALL: 4412 fprintf(output, "[all] "); 4413 break; 4414 case XML_SCHEMA_TYPE_UR: 4415 fprintf(output, "[ur] "); 4416 break; 4417 case XML_SCHEMA_TYPE_RESTRICTION: 4418 fprintf(output, "[restriction] "); 4419 break; 4420 case XML_SCHEMA_TYPE_EXTENSION: 4421 fprintf(output, "[extension] "); 4422 break; 4423 default: 4424 fprintf(output, "[unknown type %d] ", type->type); 4425 break; 4426 } 4427 fprintf(output, "content: "); 4428 switch (type->contentType) { 4429 case XML_SCHEMA_CONTENT_UNKNOWN: 4430 fprintf(output, "[unknown] "); 4431 break; 4432 case XML_SCHEMA_CONTENT_EMPTY: 4433 fprintf(output, "[empty] "); 4434 break; 4435 case XML_SCHEMA_CONTENT_ELEMENTS: 4436 fprintf(output, "[element] "); 4437 break; 4438 case XML_SCHEMA_CONTENT_MIXED: 4439 fprintf(output, "[mixed] "); 4440 break; 4441 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4442 /* not used. */ 4443 break; 4444 case XML_SCHEMA_CONTENT_BASIC: 4445 fprintf(output, "[basic] "); 4446 break; 4447 case XML_SCHEMA_CONTENT_SIMPLE: 4448 fprintf(output, "[simple] "); 4449 break; 4450 case XML_SCHEMA_CONTENT_ANY: 4451 fprintf(output, "[any] "); 4452 break; 4453 } 4454 fprintf(output, "\n"); 4455 if (type->base != NULL) { 4456 fprintf(output, " base type: '%s'", type->base); 4457 if (type->baseNs != NULL) 4458 fprintf(output, " ns '%s'\n", type->baseNs); 4459 else 4460 fprintf(output, "\n"); 4461 } 4462 if (type->attrUses != NULL) 4463 xmlSchemaAttrUsesDump(type->attrUses, output); 4464 if (type->annot != NULL) 4465 xmlSchemaAnnotDump(output, type->annot); 4466#ifdef DUMP_CONTENT_MODEL 4467 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4468 (type->subtypes != NULL)) { 4469 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4470 output, 1); 4471 } 4472#endif 4473} 4474 4475/** 4476 * xmlSchemaDump: 4477 * @output: the file output 4478 * @schema: a schema structure 4479 * 4480 * Dump a Schema structure. 4481 */ 4482void 4483xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4484{ 4485 if (output == NULL) 4486 return; 4487 if (schema == NULL) { 4488 fprintf(output, "Schemas: NULL\n"); 4489 return; 4490 } 4491 fprintf(output, "Schemas: "); 4492 if (schema->name != NULL) 4493 fprintf(output, "%s, ", schema->name); 4494 else 4495 fprintf(output, "no name, "); 4496 if (schema->targetNamespace != NULL) 4497 fprintf(output, "%s", (const char *) schema->targetNamespace); 4498 else 4499 fprintf(output, "no target namespace"); 4500 fprintf(output, "\n"); 4501 if (schema->annot != NULL) 4502 xmlSchemaAnnotDump(output, schema->annot); 4503 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4504 output); 4505 xmlHashScanFull(schema->elemDecl, 4506 (xmlHashScannerFull) xmlSchemaElementDump, output); 4507} 4508 4509#ifdef DEBUG_IDC_NODE_TABLE 4510/** 4511 * xmlSchemaDebugDumpIDCTable: 4512 * @vctxt: the WXS validation context 4513 * 4514 * Displays the current IDC table for debug purposes. 4515 */ 4516static void 4517xmlSchemaDebugDumpIDCTable(FILE * output, 4518 const xmlChar *namespaceName, 4519 const xmlChar *localName, 4520 xmlSchemaPSVIIDCBindingPtr bind) 4521{ 4522 xmlChar *str = NULL; 4523 const xmlChar *value; 4524 xmlSchemaPSVIIDCNodePtr tab; 4525 xmlSchemaPSVIIDCKeyPtr key; 4526 int i, j, res; 4527 4528 fprintf(output, "IDC: TABLES on '%s'\n", 4529 xmlSchemaFormatQName(&str, namespaceName, localName)); 4530 FREE_AND_NULL(str) 4531 4532 if (bind == NULL) 4533 return; 4534 do { 4535 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4536 xmlSchemaGetComponentQName(&str, 4537 bind->definition), bind->nbNodes); 4538 FREE_AND_NULL(str) 4539 for (i = 0; i < bind->nbNodes; i++) { 4540 tab = bind->nodeTable[i]; 4541 fprintf(output, " ( "); 4542 for (j = 0; j < bind->definition->nbFields; j++) { 4543 key = tab->keys[j]; 4544 if ((key != NULL) && (key->val != NULL)) { 4545 res = xmlSchemaGetCanonValue(key->val, &value); 4546 if (res >= 0) 4547 fprintf(output, "'%s' ", value); 4548 else 4549 fprintf(output, "CANON-VALUE-FAILED "); 4550 if (res == 0) 4551 FREE_AND_NULL(value) 4552 } else if (key != NULL) 4553 fprintf(output, "(no val), "); 4554 else 4555 fprintf(output, "(key missing), "); 4556 } 4557 fprintf(output, ")\n"); 4558 } 4559 if (bind->dupls && bind->dupls->nbItems) { 4560 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4561 for (i = 0; i < bind->dupls->nbItems; i++) { 4562 tab = bind->dupls->items[i]; 4563 fprintf(output, " ( "); 4564 for (j = 0; j < bind->definition->nbFields; j++) { 4565 key = tab->keys[j]; 4566 if ((key != NULL) && (key->val != NULL)) { 4567 res = xmlSchemaGetCanonValue(key->val, &value); 4568 if (res >= 0) 4569 fprintf(output, "'%s' ", value); 4570 else 4571 fprintf(output, "CANON-VALUE-FAILED "); 4572 if (res == 0) 4573 FREE_AND_NULL(value) 4574 } else if (key != NULL) 4575 fprintf(output, "(no val), "); 4576 else 4577 fprintf(output, "(key missing), "); 4578 } 4579 fprintf(output, ")\n"); 4580 } 4581 } 4582 bind = bind->next; 4583 } while (bind != NULL); 4584} 4585#endif /* DEBUG_IDC */ 4586#endif /* LIBXML_OUTPUT_ENABLED */ 4587 4588/************************************************************************ 4589 * * 4590 * Utilities * 4591 * * 4592 ************************************************************************/ 4593 4594/** 4595 * xmlSchemaGetPropNode: 4596 * @node: the element node 4597 * @name: the name of the attribute 4598 * 4599 * Seeks an attribute with a name of @name in 4600 * no namespace. 4601 * 4602 * Returns the attribute or NULL if not present. 4603 */ 4604static xmlAttrPtr 4605xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4606{ 4607 xmlAttrPtr prop; 4608 4609 if ((node == NULL) || (name == NULL)) 4610 return(NULL); 4611 prop = node->properties; 4612 while (prop != NULL) { 4613 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4614 return(prop); 4615 prop = prop->next; 4616 } 4617 return (NULL); 4618} 4619 4620/** 4621 * xmlSchemaGetPropNodeNs: 4622 * @node: the element node 4623 * @uri: the uri 4624 * @name: the name of the attribute 4625 * 4626 * Seeks an attribute with a local name of @name and 4627 * a namespace URI of @uri. 4628 * 4629 * Returns the attribute or NULL if not present. 4630 */ 4631static xmlAttrPtr 4632xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4633{ 4634 xmlAttrPtr prop; 4635 4636 if ((node == NULL) || (name == NULL)) 4637 return(NULL); 4638 prop = node->properties; 4639 while (prop != NULL) { 4640 if ((prop->ns != NULL) && 4641 xmlStrEqual(prop->name, BAD_CAST name) && 4642 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4643 return(prop); 4644 prop = prop->next; 4645 } 4646 return (NULL); 4647} 4648 4649static const xmlChar * 4650xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4651{ 4652 xmlChar *val; 4653 const xmlChar *ret; 4654 4655 val = xmlNodeGetContent(node); 4656 if (val == NULL) 4657 val = xmlStrdup((xmlChar *)""); 4658 ret = xmlDictLookup(ctxt->dict, val, -1); 4659 xmlFree(val); 4660 return(ret); 4661} 4662 4663static const xmlChar * 4664xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4665{ 4666 return((const xmlChar*) xmlNodeGetContent(node)); 4667} 4668 4669/** 4670 * xmlSchemaGetProp: 4671 * @ctxt: the parser context 4672 * @node: the node 4673 * @name: the property name 4674 * 4675 * Read a attribute value and internalize the string 4676 * 4677 * Returns the string or NULL if not present. 4678 */ 4679static const xmlChar * 4680xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4681 const char *name) 4682{ 4683 xmlChar *val; 4684 const xmlChar *ret; 4685 4686 val = xmlGetNoNsProp(node, BAD_CAST name); 4687 if (val == NULL) 4688 return(NULL); 4689 ret = xmlDictLookup(ctxt->dict, val, -1); 4690 xmlFree(val); 4691 return(ret); 4692} 4693 4694/************************************************************************ 4695 * * 4696 * Parsing functions * 4697 * * 4698 ************************************************************************/ 4699 4700#define WXS_FIND_GLOBAL_ITEM(slot) \ 4701 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4702 ret = xmlHashLookup(schema->slot, name); \ 4703 if (ret != NULL) goto exit; \ 4704 } \ 4705 if (xmlHashSize(schema->schemasImports) > 1) { \ 4706 xmlSchemaImportPtr import; \ 4707 if (nsName == NULL) \ 4708 import = xmlHashLookup(schema->schemasImports, \ 4709 XML_SCHEMAS_NO_NAMESPACE); \ 4710 else \ 4711 import = xmlHashLookup(schema->schemasImports, nsName); \ 4712 if (import == NULL) \ 4713 goto exit; \ 4714 ret = xmlHashLookup(import->schema->slot, name); \ 4715 } 4716 4717/** 4718 * xmlSchemaGetElem: 4719 * @schema: the schema context 4720 * @name: the element name 4721 * @ns: the element namespace 4722 * 4723 * Lookup a global element declaration in the schema. 4724 * 4725 * Returns the element declaration or NULL if not found. 4726 */ 4727static xmlSchemaElementPtr 4728xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4729 const xmlChar * nsName) 4730{ 4731 xmlSchemaElementPtr ret = NULL; 4732 4733 if ((name == NULL) || (schema == NULL)) 4734 return(NULL); 4735 if (schema != NULL) { 4736 WXS_FIND_GLOBAL_ITEM(elemDecl) 4737 } 4738exit: 4739#ifdef DEBUG 4740 if (ret == NULL) { 4741 if (nsName == NULL) 4742 fprintf(stderr, "Unable to lookup element decl. %s", name); 4743 else 4744 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4745 nsName); 4746 } 4747#endif 4748 return (ret); 4749} 4750 4751/** 4752 * xmlSchemaGetType: 4753 * @schema: the main schema 4754 * @name: the type's name 4755 * nsName: the type's namespace 4756 * 4757 * Lookup a type in the schemas or the predefined types 4758 * 4759 * Returns the group definition or NULL if not found. 4760 */ 4761static xmlSchemaTypePtr 4762xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4763 const xmlChar * nsName) 4764{ 4765 xmlSchemaTypePtr ret = NULL; 4766 4767 if (name == NULL) 4768 return (NULL); 4769 /* First try the built-in types. */ 4770 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4771 ret = xmlSchemaGetPredefinedType(name, nsName); 4772 if (ret != NULL) 4773 goto exit; 4774 /* 4775 * Note that we try the parsed schemas as well here 4776 * since one might have parsed the S4S, which contain more 4777 * than the built-in types. 4778 * TODO: Can we optimize this? 4779 */ 4780 } 4781 if (schema != NULL) { 4782 WXS_FIND_GLOBAL_ITEM(typeDecl) 4783 } 4784exit: 4785 4786#ifdef DEBUG 4787 if (ret == NULL) { 4788 if (nsName == NULL) 4789 fprintf(stderr, "Unable to lookup type %s", name); 4790 else 4791 fprintf(stderr, "Unable to lookup type %s:%s", name, 4792 nsName); 4793 } 4794#endif 4795 return (ret); 4796} 4797 4798/** 4799 * xmlSchemaGetAttributeDecl: 4800 * @schema: the context of the schema 4801 * @name: the name of the attribute 4802 * @ns: the target namespace of the attribute 4803 * 4804 * Lookup a an attribute in the schema or imported schemas 4805 * 4806 * Returns the attribute declaration or NULL if not found. 4807 */ 4808static xmlSchemaAttributePtr 4809xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4810 const xmlChar * nsName) 4811{ 4812 xmlSchemaAttributePtr ret = NULL; 4813 4814 if ((name == NULL) || (schema == NULL)) 4815 return (NULL); 4816 if (schema != NULL) { 4817 WXS_FIND_GLOBAL_ITEM(attrDecl) 4818 } 4819exit: 4820#ifdef DEBUG 4821 if (ret == NULL) { 4822 if (nsName == NULL) 4823 fprintf(stderr, "Unable to lookup attribute %s", name); 4824 else 4825 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4826 nsName); 4827 } 4828#endif 4829 return (ret); 4830} 4831 4832/** 4833 * xmlSchemaGetAttributeGroup: 4834 * @schema: the context of the schema 4835 * @name: the name of the attribute group 4836 * @ns: the target namespace of the attribute group 4837 * 4838 * Lookup a an attribute group in the schema or imported schemas 4839 * 4840 * Returns the attribute group definition or NULL if not found. 4841 */ 4842static xmlSchemaAttributeGroupPtr 4843xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4844 const xmlChar * nsName) 4845{ 4846 xmlSchemaAttributeGroupPtr ret = NULL; 4847 4848 if ((name == NULL) || (schema == NULL)) 4849 return (NULL); 4850 if (schema != NULL) { 4851 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4852 } 4853exit: 4854 /* TODO: 4855 if ((ret != NULL) && (ret->redef != NULL)) { 4856 * Return the last redefinition. * 4857 ret = ret->redef; 4858 } 4859 */ 4860#ifdef DEBUG 4861 if (ret == NULL) { 4862 if (nsName == NULL) 4863 fprintf(stderr, "Unable to lookup attribute group %s", name); 4864 else 4865 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4866 nsName); 4867 } 4868#endif 4869 return (ret); 4870} 4871 4872/** 4873 * xmlSchemaGetGroup: 4874 * @schema: the context of the schema 4875 * @name: the name of the group 4876 * @ns: the target namespace of the group 4877 * 4878 * Lookup a group in the schema or imported schemas 4879 * 4880 * Returns the group definition or NULL if not found. 4881 */ 4882static xmlSchemaModelGroupDefPtr 4883xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4884 const xmlChar * nsName) 4885{ 4886 xmlSchemaModelGroupDefPtr ret = NULL; 4887 4888 if ((name == NULL) || (schema == NULL)) 4889 return (NULL); 4890 if (schema != NULL) { 4891 WXS_FIND_GLOBAL_ITEM(groupDecl) 4892 } 4893exit: 4894 4895#ifdef DEBUG 4896 if (ret == NULL) { 4897 if (nsName == NULL) 4898 fprintf(stderr, "Unable to lookup group %s", name); 4899 else 4900 fprintf(stderr, "Unable to lookup group %s:%s", name, 4901 nsName); 4902 } 4903#endif 4904 return (ret); 4905} 4906 4907static xmlSchemaNotationPtr 4908xmlSchemaGetNotation(xmlSchemaPtr schema, 4909 const xmlChar *name, 4910 const xmlChar *nsName) 4911{ 4912 xmlSchemaNotationPtr ret = NULL; 4913 4914 if ((name == NULL) || (schema == NULL)) 4915 return (NULL); 4916 if (schema != NULL) { 4917 WXS_FIND_GLOBAL_ITEM(notaDecl) 4918 } 4919exit: 4920 return (ret); 4921} 4922 4923static xmlSchemaIDCPtr 4924xmlSchemaGetIDC(xmlSchemaPtr schema, 4925 const xmlChar *name, 4926 const xmlChar *nsName) 4927{ 4928 xmlSchemaIDCPtr ret = NULL; 4929 4930 if ((name == NULL) || (schema == NULL)) 4931 return (NULL); 4932 if (schema != NULL) { 4933 WXS_FIND_GLOBAL_ITEM(idcDef) 4934 } 4935exit: 4936 return (ret); 4937} 4938 4939/** 4940 * xmlSchemaGetNamedComponent: 4941 * @schema: the schema 4942 * @name: the name of the group 4943 * @ns: the target namespace of the group 4944 * 4945 * Lookup a group in the schema or imported schemas 4946 * 4947 * Returns the group definition or NULL if not found. 4948 */ 4949static xmlSchemaBasicItemPtr 4950xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4951 xmlSchemaTypeType itemType, 4952 const xmlChar *name, 4953 const xmlChar *targetNs) 4954{ 4955 switch (itemType) { 4956 case XML_SCHEMA_TYPE_GROUP: 4957 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4958 name, targetNs)); 4959 case XML_SCHEMA_TYPE_ELEMENT: 4960 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4961 name, targetNs)); 4962 default: 4963 TODO 4964 return (NULL); 4965 } 4966} 4967 4968/************************************************************************ 4969 * * 4970 * Parsing functions * 4971 * * 4972 ************************************************************************/ 4973 4974#define IS_BLANK_NODE(n) \ 4975 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 4976 4977/** 4978 * xmlSchemaIsBlank: 4979 * @str: a string 4980 * @len: the length of the string or -1 4981 * 4982 * Check if a string is ignorable 4983 * 4984 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 4985 */ 4986static int 4987xmlSchemaIsBlank(xmlChar * str, int len) 4988{ 4989 if (str == NULL) 4990 return (1); 4991 if (len < 0) { 4992 while (*str != 0) { 4993 if (!(IS_BLANK_CH(*str))) 4994 return (0); 4995 str++; 4996 } 4997 } else while ((*str != 0) && (len != 0)) { 4998 if (!(IS_BLANK_CH(*str))) 4999 return (0); 5000 str++; 5001 len--; 5002 } 5003 5004 return (1); 5005} 5006 5007#define WXS_COMP_NAME(c, t) ((t) (c))->name 5008#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5009/* 5010* xmlSchemaFindRedefCompInGraph: 5011* ATTENTION TODO: This uses pointer comp. for strings. 5012*/ 5013static xmlSchemaBasicItemPtr 5014xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5015 xmlSchemaTypeType type, 5016 const xmlChar *name, 5017 const xmlChar *nsName) 5018{ 5019 xmlSchemaBasicItemPtr ret; 5020 int i; 5021 5022 if ((bucket == NULL) || (name == NULL)) 5023 return(NULL); 5024 if ((bucket->globals == NULL) || 5025 (bucket->globals->nbItems == 0)) 5026 goto subschemas; 5027 /* 5028 * Search in global components. 5029 */ 5030 for (i = 0; i < bucket->globals->nbItems; i++) { 5031 ret = bucket->globals->items[i]; 5032 if (ret->type == type) { 5033 switch (type) { 5034 case XML_SCHEMA_TYPE_COMPLEX: 5035 case XML_SCHEMA_TYPE_SIMPLE: 5036 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5037 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5038 nsName)) 5039 { 5040 return(ret); 5041 } 5042 break; 5043 case XML_SCHEMA_TYPE_GROUP: 5044 if ((WXS_COMP_NAME(ret, 5045 xmlSchemaModelGroupDefPtr) == name) && 5046 (WXS_COMP_TNS(ret, 5047 xmlSchemaModelGroupDefPtr) == nsName)) 5048 { 5049 return(ret); 5050 } 5051 break; 5052 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5053 if ((WXS_COMP_NAME(ret, 5054 xmlSchemaAttributeGroupPtr) == name) && 5055 (WXS_COMP_TNS(ret, 5056 xmlSchemaAttributeGroupPtr) == nsName)) 5057 { 5058 return(ret); 5059 } 5060 break; 5061 default: 5062 /* Should not be hit. */ 5063 return(NULL); 5064 } 5065 } 5066 } 5067subschemas: 5068 /* 5069 * Process imported/included schemas. 5070 */ 5071 if (bucket->relations != NULL) { 5072 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5073 5074 /* 5075 * TODO: Marking the bucket will not avoid multiple searches 5076 * in the same schema, but avoids at least circularity. 5077 */ 5078 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5079 do { 5080 if ((rel->bucket != NULL) && 5081 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5082 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5083 type, name, nsName); 5084 if (ret != NULL) 5085 return(ret); 5086 } 5087 rel = rel->next; 5088 } while (rel != NULL); 5089 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5090 } 5091 return(NULL); 5092} 5093 5094/** 5095 * xmlSchemaAddNotation: 5096 * @ctxt: a schema parser context 5097 * @schema: the schema being built 5098 * @name: the item name 5099 * 5100 * Add an XML schema annotation declaration 5101 * *WARNING* this interface is highly subject to change 5102 * 5103 * Returns the new struture or NULL in case of error 5104 */ 5105static xmlSchemaNotationPtr 5106xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5107 const xmlChar *name, const xmlChar *nsName, 5108 xmlNodePtr node ATTRIBUTE_UNUSED) 5109{ 5110 xmlSchemaNotationPtr ret = NULL; 5111 5112 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5113 return (NULL); 5114 5115 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5116 if (ret == NULL) { 5117 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5118 return (NULL); 5119 } 5120 memset(ret, 0, sizeof(xmlSchemaNotation)); 5121 ret->type = XML_SCHEMA_TYPE_NOTATION; 5122 ret->name = name; 5123 ret->targetNamespace = nsName; 5124 /* TODO: do we need the node to be set? 5125 * ret->node = node;*/ 5126 WXS_ADD_GLOBAL(ctxt, ret); 5127 return (ret); 5128} 5129 5130/** 5131 * xmlSchemaAddAttribute: 5132 * @ctxt: a schema parser context 5133 * @schema: the schema being built 5134 * @name: the item name 5135 * @namespace: the namespace 5136 * 5137 * Add an XML schema Attrribute declaration 5138 * *WARNING* this interface is highly subject to change 5139 * 5140 * Returns the new struture or NULL in case of error 5141 */ 5142static xmlSchemaAttributePtr 5143xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5144 const xmlChar * name, const xmlChar * nsName, 5145 xmlNodePtr node, int topLevel) 5146{ 5147 xmlSchemaAttributePtr ret = NULL; 5148 5149 if ((ctxt == NULL) || (schema == NULL)) 5150 return (NULL); 5151 5152 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5153 if (ret == NULL) { 5154 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5155 return (NULL); 5156 } 5157 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5158 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5159 ret->node = node; 5160 ret->name = name; 5161 ret->targetNamespace = nsName; 5162 5163 if (topLevel) 5164 WXS_ADD_GLOBAL(ctxt, ret); 5165 else 5166 WXS_ADD_LOCAL(ctxt, ret); 5167 WXS_ADD_PENDING(ctxt, ret); 5168 return (ret); 5169} 5170 5171/** 5172 * xmlSchemaAddAttributeUse: 5173 * @ctxt: a schema parser context 5174 * @schema: the schema being built 5175 * @name: the item name 5176 * @namespace: the namespace 5177 * 5178 * Add an XML schema Attrribute declaration 5179 * *WARNING* this interface is highly subject to change 5180 * 5181 * Returns the new struture or NULL in case of error 5182 */ 5183static xmlSchemaAttributeUsePtr 5184xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5185 xmlNodePtr node) 5186{ 5187 xmlSchemaAttributeUsePtr ret = NULL; 5188 5189 if (pctxt == NULL) 5190 return (NULL); 5191 5192 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5193 if (ret == NULL) { 5194 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5195 return (NULL); 5196 } 5197 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5198 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5199 ret->node = node; 5200 5201 WXS_ADD_LOCAL(pctxt, ret); 5202 return (ret); 5203} 5204 5205/* 5206* xmlSchemaAddRedef: 5207* 5208* Adds a redefinition information. This is used at a later stage to: 5209* resolve references to the redefined components and to check constraints. 5210*/ 5211static xmlSchemaRedefPtr 5212xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5213 xmlSchemaBucketPtr targetBucket, 5214 void *item, 5215 const xmlChar *refName, 5216 const xmlChar *refTargetNs) 5217{ 5218 xmlSchemaRedefPtr ret; 5219 5220 ret = (xmlSchemaRedefPtr) 5221 xmlMalloc(sizeof(xmlSchemaRedef)); 5222 if (ret == NULL) { 5223 xmlSchemaPErrMemory(pctxt, 5224 "allocating redefinition info", NULL); 5225 return (NULL); 5226 } 5227 memset(ret, 0, sizeof(xmlSchemaRedef)); 5228 ret->item = item; 5229 ret->targetBucket = targetBucket; 5230 ret->refName = refName; 5231 ret->refTargetNs = refTargetNs; 5232 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5233 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5234 else 5235 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5236 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5237 5238 return (ret); 5239} 5240 5241/** 5242 * xmlSchemaAddAttributeGroupDefinition: 5243 * @ctxt: a schema parser context 5244 * @schema: the schema being built 5245 * @name: the item name 5246 * @nsName: the target namespace 5247 * @node: the corresponding node 5248 * 5249 * Add an XML schema Attrribute Group definition. 5250 * 5251 * Returns the new struture or NULL in case of error 5252 */ 5253static xmlSchemaAttributeGroupPtr 5254xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5255 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5256 const xmlChar *name, 5257 const xmlChar *nsName, 5258 xmlNodePtr node) 5259{ 5260 xmlSchemaAttributeGroupPtr ret = NULL; 5261 5262 if ((pctxt == NULL) || (name == NULL)) 5263 return (NULL); 5264 5265 ret = (xmlSchemaAttributeGroupPtr) 5266 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5267 if (ret == NULL) { 5268 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5269 return (NULL); 5270 } 5271 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5272 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5273 ret->name = name; 5274 ret->targetNamespace = nsName; 5275 ret->node = node; 5276 5277 /* TODO: Remove the flag. */ 5278 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5279 if (pctxt->isRedefine) { 5280 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5281 ret, name, nsName); 5282 if (pctxt->redef == NULL) { 5283 xmlFree(ret); 5284 return(NULL); 5285 } 5286 pctxt->redefCounter = 0; 5287 } 5288 WXS_ADD_GLOBAL(pctxt, ret); 5289 WXS_ADD_PENDING(pctxt, ret); 5290 return (ret); 5291} 5292 5293/** 5294 * xmlSchemaAddElement: 5295 * @ctxt: a schema parser context 5296 * @schema: the schema being built 5297 * @name: the type name 5298 * @namespace: the type namespace 5299 * 5300 * Add an XML schema Element declaration 5301 * *WARNING* this interface is highly subject to change 5302 * 5303 * Returns the new struture or NULL in case of error 5304 */ 5305static xmlSchemaElementPtr 5306xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5307 const xmlChar * name, const xmlChar * nsName, 5308 xmlNodePtr node, int topLevel) 5309{ 5310 xmlSchemaElementPtr ret = NULL; 5311 5312 if ((ctxt == NULL) || (name == NULL)) 5313 return (NULL); 5314 5315 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5316 if (ret == NULL) { 5317 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5318 return (NULL); 5319 } 5320 memset(ret, 0, sizeof(xmlSchemaElement)); 5321 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5322 ret->name = name; 5323 ret->targetNamespace = nsName; 5324 ret->node = node; 5325 5326 if (topLevel) 5327 WXS_ADD_GLOBAL(ctxt, ret); 5328 else 5329 WXS_ADD_LOCAL(ctxt, ret); 5330 WXS_ADD_PENDING(ctxt, ret); 5331 return (ret); 5332} 5333 5334/** 5335 * xmlSchemaAddType: 5336 * @ctxt: a schema parser context 5337 * @schema: the schema being built 5338 * @name: the item name 5339 * @namespace: the namespace 5340 * 5341 * Add an XML schema item 5342 * *WARNING* this interface is highly subject to change 5343 * 5344 * Returns the new struture or NULL in case of error 5345 */ 5346static xmlSchemaTypePtr 5347xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5348 xmlSchemaTypeType type, 5349 const xmlChar * name, const xmlChar * nsName, 5350 xmlNodePtr node, int topLevel) 5351{ 5352 xmlSchemaTypePtr ret = NULL; 5353 5354 if ((ctxt == NULL) || (schema == NULL)) 5355 return (NULL); 5356 5357 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5358 if (ret == NULL) { 5359 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5360 return (NULL); 5361 } 5362 memset(ret, 0, sizeof(xmlSchemaType)); 5363 ret->type = type; 5364 ret->name = name; 5365 ret->targetNamespace = nsName; 5366 ret->node = node; 5367 if (topLevel) { 5368 if (ctxt->isRedefine) { 5369 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5370 ret, name, nsName); 5371 if (ctxt->redef == NULL) { 5372 xmlFree(ret); 5373 return(NULL); 5374 } 5375 ctxt->redefCounter = 0; 5376 } 5377 WXS_ADD_GLOBAL(ctxt, ret); 5378 } else 5379 WXS_ADD_LOCAL(ctxt, ret); 5380 WXS_ADD_PENDING(ctxt, ret); 5381 return (ret); 5382} 5383 5384static xmlSchemaQNameRefPtr 5385xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5386 xmlSchemaTypeType refType, 5387 const xmlChar *refName, 5388 const xmlChar *refNs) 5389{ 5390 xmlSchemaQNameRefPtr ret; 5391 5392 ret = (xmlSchemaQNameRefPtr) 5393 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5394 if (ret == NULL) { 5395 xmlSchemaPErrMemory(pctxt, 5396 "allocating QName reference item", NULL); 5397 return (NULL); 5398 } 5399 ret->node = NULL; 5400 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5401 ret->name = refName; 5402 ret->targetNamespace = refNs; 5403 ret->item = NULL; 5404 ret->itemType = refType; 5405 /* 5406 * Store the reference item in the schema. 5407 */ 5408 WXS_ADD_LOCAL(pctxt, ret); 5409 return (ret); 5410} 5411 5412static xmlSchemaAttributeUseProhibPtr 5413xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5414{ 5415 xmlSchemaAttributeUseProhibPtr ret; 5416 5417 ret = (xmlSchemaAttributeUseProhibPtr) 5418 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5419 if (ret == NULL) { 5420 xmlSchemaPErrMemory(pctxt, 5421 "allocating attribute use prohibition", NULL); 5422 return (NULL); 5423 } 5424 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5425 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5426 WXS_ADD_LOCAL(pctxt, ret); 5427 return (ret); 5428} 5429 5430 5431/** 5432 * xmlSchemaAddModelGroup: 5433 * @ctxt: a schema parser context 5434 * @schema: the schema being built 5435 * @type: the "compositor" type of the model group 5436 * @node: the node in the schema doc 5437 * 5438 * Adds a schema model group 5439 * *WARNING* this interface is highly subject to change 5440 * 5441 * Returns the new struture or NULL in case of error 5442 */ 5443static xmlSchemaModelGroupPtr 5444xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5445 xmlSchemaPtr schema, 5446 xmlSchemaTypeType type, 5447 xmlNodePtr node) 5448{ 5449 xmlSchemaModelGroupPtr ret = NULL; 5450 5451 if ((ctxt == NULL) || (schema == NULL)) 5452 return (NULL); 5453 5454 ret = (xmlSchemaModelGroupPtr) 5455 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5456 if (ret == NULL) { 5457 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5458 NULL); 5459 return (NULL); 5460 } 5461 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5462 ret->type = type; 5463 ret->node = node; 5464 WXS_ADD_LOCAL(ctxt, ret); 5465 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5466 (type == XML_SCHEMA_TYPE_CHOICE)) 5467 WXS_ADD_PENDING(ctxt, ret); 5468 return (ret); 5469} 5470 5471 5472/** 5473 * xmlSchemaAddParticle: 5474 * @ctxt: a schema parser context 5475 * @schema: the schema being built 5476 * @node: the corresponding node in the schema doc 5477 * @min: the minOccurs 5478 * @max: the maxOccurs 5479 * 5480 * Adds an XML schema particle component. 5481 * *WARNING* this interface is highly subject to change 5482 * 5483 * Returns the new struture or NULL in case of error 5484 */ 5485static xmlSchemaParticlePtr 5486xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5487 xmlNodePtr node, int min, int max) 5488{ 5489 xmlSchemaParticlePtr ret = NULL; 5490 if (ctxt == NULL) 5491 return (NULL); 5492 5493#ifdef DEBUG 5494 fprintf(stderr, "Adding particle component\n"); 5495#endif 5496 ret = (xmlSchemaParticlePtr) 5497 xmlMalloc(sizeof(xmlSchemaParticle)); 5498 if (ret == NULL) { 5499 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5500 NULL); 5501 return (NULL); 5502 } 5503 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5504 ret->annot = NULL; 5505 ret->node = node; 5506 ret->minOccurs = min; 5507 ret->maxOccurs = max; 5508 ret->next = NULL; 5509 ret->children = NULL; 5510 5511 WXS_ADD_LOCAL(ctxt, ret); 5512 /* 5513 * Note that addition to pending components will be done locally 5514 * to the specific parsing function, since the most particles 5515 * need not to be fixed up (i.e. the reference to be resolved). 5516 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5517 */ 5518 return (ret); 5519} 5520 5521/** 5522 * xmlSchemaAddModelGroupDefinition: 5523 * @ctxt: a schema validation context 5524 * @schema: the schema being built 5525 * @name: the group name 5526 * 5527 * Add an XML schema Group definition 5528 * 5529 * Returns the new struture or NULL in case of error 5530 */ 5531static xmlSchemaModelGroupDefPtr 5532xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5533 xmlSchemaPtr schema, 5534 const xmlChar *name, 5535 const xmlChar *nsName, 5536 xmlNodePtr node) 5537{ 5538 xmlSchemaModelGroupDefPtr ret = NULL; 5539 5540 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5541 return (NULL); 5542 5543 ret = (xmlSchemaModelGroupDefPtr) 5544 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5545 if (ret == NULL) { 5546 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5547 return (NULL); 5548 } 5549 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5550 ret->name = name; 5551 ret->type = XML_SCHEMA_TYPE_GROUP; 5552 ret->node = node; 5553 ret->targetNamespace = nsName; 5554 5555 if (ctxt->isRedefine) { 5556 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5557 ret, name, nsName); 5558 if (ctxt->redef == NULL) { 5559 xmlFree(ret); 5560 return(NULL); 5561 } 5562 ctxt->redefCounter = 0; 5563 } 5564 WXS_ADD_GLOBAL(ctxt, ret); 5565 WXS_ADD_PENDING(ctxt, ret); 5566 return (ret); 5567} 5568 5569/** 5570 * xmlSchemaNewWildcardNs: 5571 * @ctxt: a schema validation context 5572 * 5573 * Creates a new wildcard namespace constraint. 5574 * 5575 * Returns the new struture or NULL in case of error 5576 */ 5577static xmlSchemaWildcardNsPtr 5578xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5579{ 5580 xmlSchemaWildcardNsPtr ret; 5581 5582 ret = (xmlSchemaWildcardNsPtr) 5583 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5584 if (ret == NULL) { 5585 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5586 return (NULL); 5587 } 5588 ret->value = NULL; 5589 ret->next = NULL; 5590 return (ret); 5591} 5592 5593static xmlSchemaIDCPtr 5594xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5595 const xmlChar *name, const xmlChar *nsName, 5596 int category, xmlNodePtr node) 5597{ 5598 xmlSchemaIDCPtr ret = NULL; 5599 5600 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5601 return (NULL); 5602 5603 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5604 if (ret == NULL) { 5605 xmlSchemaPErrMemory(ctxt, 5606 "allocating an identity-constraint definition", NULL); 5607 return (NULL); 5608 } 5609 memset(ret, 0, sizeof(xmlSchemaIDC)); 5610 /* The target namespace of the parent element declaration. */ 5611 ret->targetNamespace = nsName; 5612 ret->name = name; 5613 ret->type = category; 5614 ret->node = node; 5615 5616 WXS_ADD_GLOBAL(ctxt, ret); 5617 /* 5618 * Only keyrefs need to be fixup up. 5619 */ 5620 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5621 WXS_ADD_PENDING(ctxt, ret); 5622 return (ret); 5623} 5624 5625/** 5626 * xmlSchemaAddWildcard: 5627 * @ctxt: a schema validation context 5628 * @schema: a schema 5629 * 5630 * Adds a wildcard. 5631 * It corresponds to a xsd:anyAttribute and xsd:any. 5632 * 5633 * Returns the new struture or NULL in case of error 5634 */ 5635static xmlSchemaWildcardPtr 5636xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5637 xmlSchemaTypeType type, xmlNodePtr node) 5638{ 5639 xmlSchemaWildcardPtr ret = NULL; 5640 5641 if ((ctxt == NULL) || (schema == NULL)) 5642 return (NULL); 5643 5644 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5645 if (ret == NULL) { 5646 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5647 return (NULL); 5648 } 5649 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5650 ret->type = type; 5651 ret->node = node; 5652 WXS_ADD_LOCAL(ctxt, ret); 5653 return (ret); 5654} 5655 5656static void 5657xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5658{ 5659 if (group == NULL) 5660 return; 5661 if (group->members != NULL) 5662 xmlSchemaItemListFree(group->members); 5663 xmlFree(group); 5664} 5665 5666static xmlSchemaSubstGroupPtr 5667xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5668 xmlSchemaElementPtr head) 5669{ 5670 xmlSchemaSubstGroupPtr ret; 5671 5672 /* Init subst group hash. */ 5673 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5674 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5675 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5676 return(NULL); 5677 } 5678 /* Create a new substitution group. */ 5679 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5680 if (ret == NULL) { 5681 xmlSchemaPErrMemory(NULL, 5682 "allocating a substitution group container", NULL); 5683 return(NULL); 5684 } 5685 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5686 ret->head = head; 5687 /* Create list of members. */ 5688 ret->members = xmlSchemaItemListCreate(); 5689 if (ret->members == NULL) { 5690 xmlSchemaSubstGroupFree(ret); 5691 return(NULL); 5692 } 5693 /* Add subst group to hash. */ 5694 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5695 head->name, head->targetNamespace, ret) != 0) { 5696 PERROR_INT("xmlSchemaSubstGroupAdd", 5697 "failed to add a new substitution container"); 5698 xmlSchemaSubstGroupFree(ret); 5699 return(NULL); 5700 } 5701 return(ret); 5702} 5703 5704static xmlSchemaSubstGroupPtr 5705xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5706 xmlSchemaElementPtr head) 5707{ 5708 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5709 return(NULL); 5710 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5711 head->name, head->targetNamespace)); 5712 5713} 5714 5715/** 5716 * xmlSchemaAddElementSubstitutionMember: 5717 * @pctxt: a schema parser context 5718 * @head: the head of the substitution group 5719 * @member: the new member of the substitution group 5720 * 5721 * Allocate a new annotation structure. 5722 * 5723 * Returns the newly allocated structure or NULL in case or error 5724 */ 5725static int 5726xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5727 xmlSchemaElementPtr head, 5728 xmlSchemaElementPtr member) 5729{ 5730 xmlSchemaSubstGroupPtr substGroup = NULL; 5731 5732 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5733 return (-1); 5734 5735 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5736 if (substGroup == NULL) 5737 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5738 if (substGroup == NULL) 5739 return(-1); 5740 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5741 return(-1); 5742 return(0); 5743} 5744 5745/************************************************************************ 5746 * * 5747 * Utilities for parsing * 5748 * * 5749 ************************************************************************/ 5750 5751/** 5752 * xmlSchemaPValAttrNodeQNameValue: 5753 * @ctxt: a schema parser context 5754 * @schema: the schema context 5755 * @ownerDes: the designation of the parent element 5756 * @ownerItem: the parent as a schema object 5757 * @value: the QName value 5758 * @local: the resulting local part if found, the attribute value otherwise 5759 * @uri: the resulting namespace URI if found 5760 * 5761 * Extracts the local name and the URI of a QName value and validates it. 5762 * This one is intended to be used on attribute values that 5763 * should resolve to schema components. 5764 * 5765 * Returns 0, in case the QName is valid, a positive error code 5766 * if not valid and -1 if an internal error occurs. 5767 */ 5768static int 5769xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5770 xmlSchemaPtr schema, 5771 xmlSchemaBasicItemPtr ownerItem, 5772 xmlAttrPtr attr, 5773 const xmlChar *value, 5774 const xmlChar **uri, 5775 const xmlChar **local) 5776{ 5777 const xmlChar *pref; 5778 xmlNsPtr ns; 5779 int len, ret; 5780 5781 *uri = NULL; 5782 *local = NULL; 5783 ret = xmlValidateQName(value, 1); 5784 if (ret > 0) { 5785 xmlSchemaPSimpleTypeErr(ctxt, 5786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5787 ownerItem, (xmlNodePtr) attr, 5788 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5789 NULL, value, NULL, NULL, NULL); 5790 *local = value; 5791 return (ctxt->err); 5792 } else if (ret < 0) 5793 return (-1); 5794 5795 if (!strchr((char *) value, ':')) { 5796 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5797 if (ns) 5798 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5799 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5800 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5801 * parser context. */ 5802 /* 5803 * This one takes care of included schemas with no 5804 * target namespace. 5805 */ 5806 *uri = ctxt->targetNamespace; 5807 } 5808 *local = xmlDictLookup(ctxt->dict, value, -1); 5809 return (0); 5810 } 5811 /* 5812 * At this point xmlSplitQName3 has to return a local name. 5813 */ 5814 *local = xmlSplitQName3(value, &len); 5815 *local = xmlDictLookup(ctxt->dict, *local, -1); 5816 pref = xmlDictLookup(ctxt->dict, value, len); 5817 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5818 if (ns == NULL) { 5819 xmlSchemaPSimpleTypeErr(ctxt, 5820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5821 ownerItem, (xmlNodePtr) attr, 5822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5823 "The value '%s' of simple type 'xs:QName' has no " 5824 "corresponding namespace declaration in scope", value, NULL); 5825 return (ctxt->err); 5826 } else { 5827 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5828 } 5829 return (0); 5830} 5831 5832/** 5833 * xmlSchemaPValAttrNodeQName: 5834 * @ctxt: a schema parser context 5835 * @schema: the schema context 5836 * @ownerDes: the designation of the owner element 5837 * @ownerItem: the owner as a schema object 5838 * @attr: the attribute node 5839 * @local: the resulting local part if found, the attribute value otherwise 5840 * @uri: the resulting namespace URI if found 5841 * 5842 * Extracts and validates the QName of an attribute value. 5843 * This one is intended to be used on attribute values that 5844 * should resolve to schema components. 5845 * 5846 * Returns 0, in case the QName is valid, a positive error code 5847 * if not valid and -1 if an internal error occurs. 5848 */ 5849static int 5850xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5851 xmlSchemaPtr schema, 5852 xmlSchemaBasicItemPtr ownerItem, 5853 xmlAttrPtr attr, 5854 const xmlChar **uri, 5855 const xmlChar **local) 5856{ 5857 const xmlChar *value; 5858 5859 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5860 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5861 ownerItem, attr, value, uri, local)); 5862} 5863 5864/** 5865 * xmlSchemaPValAttrQName: 5866 * @ctxt: a schema parser context 5867 * @schema: the schema context 5868 * @ownerDes: the designation of the parent element 5869 * @ownerItem: the owner as a schema object 5870 * @ownerElem: the parent node of the attribute 5871 * @name: the name of the attribute 5872 * @local: the resulting local part if found, the attribute value otherwise 5873 * @uri: the resulting namespace URI if found 5874 * 5875 * Extracts and validates the QName of an attribute value. 5876 * 5877 * Returns 0, in case the QName is valid, a positive error code 5878 * if not valid and -1 if an internal error occurs. 5879 */ 5880static int 5881xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5882 xmlSchemaPtr schema, 5883 xmlSchemaBasicItemPtr ownerItem, 5884 xmlNodePtr ownerElem, 5885 const char *name, 5886 const xmlChar **uri, 5887 const xmlChar **local) 5888{ 5889 xmlAttrPtr attr; 5890 5891 attr = xmlSchemaGetPropNode(ownerElem, name); 5892 if (attr == NULL) { 5893 *local = NULL; 5894 *uri = NULL; 5895 return (0); 5896 } 5897 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5898 ownerItem, attr, uri, local)); 5899} 5900 5901/** 5902 * xmlSchemaPValAttrID: 5903 * @ctxt: a schema parser context 5904 * @schema: the schema context 5905 * @ownerDes: the designation of the parent element 5906 * @ownerItem: the owner as a schema object 5907 * @ownerElem: the parent node of the attribute 5908 * @name: the name of the attribute 5909 * 5910 * Extracts and validates the ID of an attribute value. 5911 * 5912 * Returns 0, in case the ID is valid, a positive error code 5913 * if not valid and -1 if an internal error occurs. 5914 */ 5915static int 5916xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5917{ 5918 int ret; 5919 const xmlChar *value; 5920 5921 if (attr == NULL) 5922 return(0); 5923 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5924 ret = xmlValidateNCName(value, 1); 5925 if (ret == 0) { 5926 /* 5927 * NOTE: the IDness might have already be declared in the DTD 5928 */ 5929 if (attr->atype != XML_ATTRIBUTE_ID) { 5930 xmlIDPtr res; 5931 xmlChar *strip; 5932 5933 /* 5934 * TODO: Use xmlSchemaStrip here; it's not exported at this 5935 * moment. 5936 */ 5937 strip = xmlSchemaCollapseString(value); 5938 if (strip != NULL) { 5939 xmlFree((xmlChar *) value); 5940 value = strip; 5941 } 5942 res = xmlAddID(NULL, attr->doc, value, attr); 5943 if (res == NULL) { 5944 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5945 xmlSchemaPSimpleTypeErr(ctxt, 5946 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5947 NULL, (xmlNodePtr) attr, 5948 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5949 NULL, NULL, "Duplicate value '%s' of simple " 5950 "type 'xs:ID'", value, NULL); 5951 } else 5952 attr->atype = XML_ATTRIBUTE_ID; 5953 } 5954 } else if (ret > 0) { 5955 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5956 xmlSchemaPSimpleTypeErr(ctxt, 5957 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5958 NULL, (xmlNodePtr) attr, 5959 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5960 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5961 "not a valid 'xs:NCName'", 5962 value, NULL); 5963 } 5964 if (value != NULL) 5965 xmlFree((xmlChar *)value); 5966 5967 return (ret); 5968} 5969 5970static int 5971xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 5972 xmlNodePtr ownerElem, 5973 const xmlChar *name) 5974{ 5975 xmlAttrPtr attr; 5976 5977 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 5978 if (attr == NULL) 5979 return(0); 5980 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 5981 5982} 5983 5984/** 5985 * xmlGetMaxOccurs: 5986 * @ctxt: a schema validation context 5987 * @node: a subtree containing XML Schema informations 5988 * 5989 * Get the maxOccurs property 5990 * 5991 * Returns the default if not found, or the value 5992 */ 5993static int 5994xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 5995 int min, int max, int def, const char *expected) 5996{ 5997 const xmlChar *val, *cur; 5998 int ret = 0; 5999 xmlAttrPtr attr; 6000 6001 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6002 if (attr == NULL) 6003 return (def); 6004 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6005 6006 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6007 if (max != UNBOUNDED) { 6008 xmlSchemaPSimpleTypeErr(ctxt, 6009 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6010 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6011 NULL, (xmlNodePtr) attr, NULL, expected, 6012 val, NULL, NULL, NULL); 6013 return (def); 6014 } else 6015 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6016 } 6017 6018 cur = val; 6019 while (IS_BLANK_CH(*cur)) 6020 cur++; 6021 if (*cur == 0) { 6022 xmlSchemaPSimpleTypeErr(ctxt, 6023 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6024 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6025 NULL, (xmlNodePtr) attr, NULL, expected, 6026 val, NULL, NULL, NULL); 6027 return (def); 6028 } 6029 while ((*cur >= '0') && (*cur <= '9')) { 6030 ret = ret * 10 + (*cur - '0'); 6031 cur++; 6032 } 6033 while (IS_BLANK_CH(*cur)) 6034 cur++; 6035 /* 6036 * TODO: Restrict the maximal value to Integer. 6037 */ 6038 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6039 xmlSchemaPSimpleTypeErr(ctxt, 6040 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6041 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6042 NULL, (xmlNodePtr) attr, NULL, expected, 6043 val, NULL, NULL, NULL); 6044 return (def); 6045 } 6046 return (ret); 6047} 6048 6049/** 6050 * xmlGetMinOccurs: 6051 * @ctxt: a schema validation context 6052 * @node: a subtree containing XML Schema informations 6053 * 6054 * Get the minOccurs property 6055 * 6056 * Returns the default if not found, or the value 6057 */ 6058static int 6059xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6060 int min, int max, int def, const char *expected) 6061{ 6062 const xmlChar *val, *cur; 6063 int ret = 0; 6064 xmlAttrPtr attr; 6065 6066 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6067 if (attr == NULL) 6068 return (def); 6069 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6070 cur = val; 6071 while (IS_BLANK_CH(*cur)) 6072 cur++; 6073 if (*cur == 0) { 6074 xmlSchemaPSimpleTypeErr(ctxt, 6075 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6076 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6077 NULL, (xmlNodePtr) attr, NULL, expected, 6078 val, NULL, NULL, NULL); 6079 return (def); 6080 } 6081 while ((*cur >= '0') && (*cur <= '9')) { 6082 ret = ret * 10 + (*cur - '0'); 6083 cur++; 6084 } 6085 while (IS_BLANK_CH(*cur)) 6086 cur++; 6087 /* 6088 * TODO: Restrict the maximal value to Integer. 6089 */ 6090 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6091 xmlSchemaPSimpleTypeErr(ctxt, 6092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6093 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6094 NULL, (xmlNodePtr) attr, NULL, expected, 6095 val, NULL, NULL, NULL); 6096 return (def); 6097 } 6098 return (ret); 6099} 6100 6101/** 6102 * xmlSchemaPGetBoolNodeValue: 6103 * @ctxt: a schema validation context 6104 * @ownerDes: owner designation 6105 * @ownerItem: the owner as a schema item 6106 * @node: the node holding the value 6107 * 6108 * Converts a boolean string value into 1 or 0. 6109 * 6110 * Returns 0 or 1. 6111 */ 6112static int 6113xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6114 xmlSchemaBasicItemPtr ownerItem, 6115 xmlNodePtr node) 6116{ 6117 xmlChar *value = NULL; 6118 int res = 0; 6119 6120 value = xmlNodeGetContent(node); 6121 /* 6122 * 3.2.2.1 Lexical representation 6123 * An instance of a datatype that is defined as �boolean� 6124 * can have the following legal literals {true, false, 1, 0}. 6125 */ 6126 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6127 res = 1; 6128 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6129 res = 0; 6130 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6131 res = 1; 6132 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6133 res = 0; 6134 else { 6135 xmlSchemaPSimpleTypeErr(ctxt, 6136 XML_SCHEMAP_INVALID_BOOLEAN, 6137 ownerItem, node, 6138 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6139 NULL, BAD_CAST value, 6140 NULL, NULL, NULL); 6141 } 6142 if (value != NULL) 6143 xmlFree(value); 6144 return (res); 6145} 6146 6147/** 6148 * xmlGetBooleanProp: 6149 * @ctxt: a schema validation context 6150 * @node: a subtree containing XML Schema informations 6151 * @name: the attribute name 6152 * @def: the default value 6153 * 6154 * Evaluate if a boolean property is set 6155 * 6156 * Returns the default if not found, 0 if found to be false, 6157 * 1 if found to be true 6158 */ 6159static int 6160xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6161 xmlNodePtr node, 6162 const char *name, int def) 6163{ 6164 const xmlChar *val; 6165 6166 val = xmlSchemaGetProp(ctxt, node, name); 6167 if (val == NULL) 6168 return (def); 6169 /* 6170 * 3.2.2.1 Lexical representation 6171 * An instance of a datatype that is defined as �boolean� 6172 * can have the following legal literals {true, false, 1, 0}. 6173 */ 6174 if (xmlStrEqual(val, BAD_CAST "true")) 6175 def = 1; 6176 else if (xmlStrEqual(val, BAD_CAST "false")) 6177 def = 0; 6178 else if (xmlStrEqual(val, BAD_CAST "1")) 6179 def = 1; 6180 else if (xmlStrEqual(val, BAD_CAST "0")) 6181 def = 0; 6182 else { 6183 xmlSchemaPSimpleTypeErr(ctxt, 6184 XML_SCHEMAP_INVALID_BOOLEAN, 6185 NULL, 6186 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6187 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6188 NULL, val, NULL, NULL, NULL); 6189 } 6190 return (def); 6191} 6192 6193/************************************************************************ 6194 * * 6195 * Shema extraction from an Infoset * 6196 * * 6197 ************************************************************************/ 6198static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6199 ctxt, xmlSchemaPtr schema, 6200 xmlNodePtr node, 6201 int topLevel); 6202static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6203 ctxt, 6204 xmlSchemaPtr schema, 6205 xmlNodePtr node, 6206 int topLevel); 6207static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6208 ctxt, 6209 xmlSchemaPtr schema, 6210 xmlNodePtr node, 6211 xmlSchemaTypeType parentType); 6212static xmlSchemaBasicItemPtr 6213xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6214 xmlSchemaPtr schema, 6215 xmlNodePtr node, 6216 xmlSchemaItemListPtr uses, 6217 int parentType); 6218static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6219 xmlSchemaPtr schema, 6220 xmlNodePtr node); 6221static xmlSchemaWildcardPtr 6222xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6223 xmlSchemaPtr schema, xmlNodePtr node); 6224 6225/** 6226 * xmlSchemaPValAttrNodeValue: 6227 * 6228 * @ctxt: a schema parser context 6229 * @ownerDes: the designation of the parent element 6230 * @ownerItem: the schema object owner if existent 6231 * @attr: the schema attribute node being validated 6232 * @value: the value 6233 * @type: the built-in type to be validated against 6234 * 6235 * Validates a value against the given built-in type. 6236 * This one is intended to be used internally for validation 6237 * of schema attribute values during parsing of the schema. 6238 * 6239 * Returns 0 if the value is valid, a positive error code 6240 * number otherwise and -1 in case of an internal or API error. 6241 */ 6242static int 6243xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6244 xmlSchemaBasicItemPtr ownerItem, 6245 xmlAttrPtr attr, 6246 const xmlChar *value, 6247 xmlSchemaTypePtr type) 6248{ 6249 6250 int ret = 0; 6251 6252 /* 6253 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6254 * one is really meant to be used internally, so better not. 6255 */ 6256 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6257 return (-1); 6258 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6259 PERROR_INT("xmlSchemaPValAttrNodeValue", 6260 "the given type is not a built-in type"); 6261 return (-1); 6262 } 6263 switch (type->builtInType) { 6264 case XML_SCHEMAS_NCNAME: 6265 case XML_SCHEMAS_QNAME: 6266 case XML_SCHEMAS_ANYURI: 6267 case XML_SCHEMAS_TOKEN: 6268 case XML_SCHEMAS_LANGUAGE: 6269 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6270 (xmlNodePtr) attr); 6271 break; 6272 default: { 6273 PERROR_INT("xmlSchemaPValAttrNodeValue", 6274 "validation using the given type is not supported while " 6275 "parsing a schema"); 6276 return (-1); 6277 } 6278 } 6279 /* 6280 * TODO: Should we use the S4S error codes instead? 6281 */ 6282 if (ret < 0) { 6283 PERROR_INT("xmlSchemaPValAttrNodeValue", 6284 "failed to validate a schema attribute value"); 6285 return (-1); 6286 } else if (ret > 0) { 6287 if (WXS_IS_LIST(type)) 6288 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6289 else 6290 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6291 xmlSchemaPSimpleTypeErr(pctxt, 6292 ret, ownerItem, (xmlNodePtr) attr, 6293 type, NULL, value, NULL, NULL, NULL); 6294 } 6295 return (ret); 6296} 6297 6298/** 6299 * xmlSchemaPValAttrNode: 6300 * 6301 * @ctxt: a schema parser context 6302 * @ownerDes: the designation of the parent element 6303 * @ownerItem: the schema object owner if existent 6304 * @attr: the schema attribute node being validated 6305 * @type: the built-in type to be validated against 6306 * @value: the resulting value if any 6307 * 6308 * Extracts and validates a value against the given built-in type. 6309 * This one is intended to be used internally for validation 6310 * of schema attribute values during parsing of the schema. 6311 * 6312 * Returns 0 if the value is valid, a positive error code 6313 * number otherwise and -1 in case of an internal or API error. 6314 */ 6315static int 6316xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6317 xmlSchemaBasicItemPtr ownerItem, 6318 xmlAttrPtr attr, 6319 xmlSchemaTypePtr type, 6320 const xmlChar **value) 6321{ 6322 const xmlChar *val; 6323 6324 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6325 return (-1); 6326 6327 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6328 if (value != NULL) 6329 *value = val; 6330 6331 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6332 val, type)); 6333} 6334 6335/** 6336 * xmlSchemaPValAttr: 6337 * 6338 * @ctxt: a schema parser context 6339 * @node: the element node of the attribute 6340 * @ownerDes: the designation of the parent element 6341 * @ownerItem: the schema object owner if existent 6342 * @ownerElem: the owner element node 6343 * @name: the name of the schema attribute node 6344 * @type: the built-in type to be validated against 6345 * @value: the resulting value if any 6346 * 6347 * Extracts and validates a value against the given built-in type. 6348 * This one is intended to be used internally for validation 6349 * of schema attribute values during parsing of the schema. 6350 * 6351 * Returns 0 if the value is valid, a positive error code 6352 * number otherwise and -1 in case of an internal or API error. 6353 */ 6354static int 6355xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6356 xmlSchemaBasicItemPtr ownerItem, 6357 xmlNodePtr ownerElem, 6358 const char *name, 6359 xmlSchemaTypePtr type, 6360 const xmlChar **value) 6361{ 6362 xmlAttrPtr attr; 6363 6364 if ((ctxt == NULL) || (type == NULL)) { 6365 if (value != NULL) 6366 *value = NULL; 6367 return (-1); 6368 } 6369 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6370 if (value != NULL) 6371 *value = NULL; 6372 xmlSchemaPErr(ctxt, ownerElem, 6373 XML_SCHEMAP_INTERNAL, 6374 "Internal error: xmlSchemaPValAttr, the given " 6375 "type '%s' is not a built-in type.\n", 6376 type->name, NULL); 6377 return (-1); 6378 } 6379 attr = xmlSchemaGetPropNode(ownerElem, name); 6380 if (attr == NULL) { 6381 if (value != NULL) 6382 *value = NULL; 6383 return (0); 6384 } 6385 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6386 type, value)); 6387} 6388 6389static int 6390xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6391 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6392 xmlNodePtr node, 6393 xmlAttrPtr attr, 6394 const xmlChar *namespaceName) 6395{ 6396 /* TODO: Pointer comparison instead? */ 6397 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6398 return (0); 6399 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6400 return (0); 6401 /* 6402 * Check if the referenced namespace was <import>ed. 6403 */ 6404 if (WXS_BUCKET(pctxt)->relations != NULL) { 6405 xmlSchemaSchemaRelationPtr rel; 6406 6407 rel = WXS_BUCKET(pctxt)->relations; 6408 do { 6409 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6410 xmlStrEqual(namespaceName, rel->importNamespace)) 6411 return (0); 6412 rel = rel->next; 6413 } while (rel != NULL); 6414 } 6415 /* 6416 * No matching <import>ed namespace found. 6417 */ 6418 { 6419 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6420 6421 if (namespaceName == NULL) 6422 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6423 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6424 "References from this schema to components in no " 6425 "namespace are not allowed, since not indicated by an " 6426 "import statement", NULL, NULL); 6427 else 6428 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6429 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6430 "References from this schema to components in the " 6431 "namespace '%s' are not allowed, since not indicated by an " 6432 "import statement", namespaceName, NULL); 6433 } 6434 return (XML_SCHEMAP_SRC_RESOLVE); 6435} 6436 6437/** 6438 * xmlSchemaParseLocalAttributes: 6439 * @ctxt: a schema validation context 6440 * @schema: the schema being built 6441 * @node: a subtree containing XML Schema informations 6442 * @type: the hosting type where the attributes will be anchored 6443 * 6444 * Parses attribute uses and attribute declarations and 6445 * attribute group references. 6446 */ 6447static int 6448xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6449 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6450 int parentType, int *hasRefs) 6451{ 6452 void *item; 6453 6454 while ((IS_SCHEMA((*child), "attribute")) || 6455 (IS_SCHEMA((*child), "attributeGroup"))) { 6456 if (IS_SCHEMA((*child), "attribute")) { 6457 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6458 *list, parentType); 6459 } else { 6460 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6461 if ((item != NULL) && (hasRefs != NULL)) 6462 *hasRefs = 1; 6463 } 6464 if (item != NULL) { 6465 if (*list == NULL) { 6466 /* TODO: Customize grow factor. */ 6467 *list = xmlSchemaItemListCreate(); 6468 if (*list == NULL) 6469 return(-1); 6470 } 6471 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6472 return(-1); 6473 } 6474 *child = (*child)->next; 6475 } 6476 return (0); 6477} 6478 6479/** 6480 * xmlSchemaParseAnnotation: 6481 * @ctxt: a schema validation context 6482 * @schema: the schema being built 6483 * @node: a subtree containing XML Schema informations 6484 * 6485 * parse a XML schema Attrribute declaration 6486 * *WARNING* this interface is highly subject to change 6487 * 6488 * Returns -1 in case of error, 0 if the declaration is improper and 6489 * 1 in case of success. 6490 */ 6491static xmlSchemaAnnotPtr 6492xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6493{ 6494 xmlSchemaAnnotPtr ret; 6495 xmlNodePtr child = NULL; 6496 xmlAttrPtr attr; 6497 int barked = 0; 6498 6499 /* 6500 * INFO: S4S completed. 6501 */ 6502 /* 6503 * id = ID 6504 * {any attributes with non-schema namespace . . .}> 6505 * Content: (appinfo | documentation)* 6506 */ 6507 if ((ctxt == NULL) || (node == NULL)) 6508 return (NULL); 6509 if (needed) 6510 ret = xmlSchemaNewAnnot(ctxt, node); 6511 else 6512 ret = NULL; 6513 attr = node->properties; 6514 while (attr != NULL) { 6515 if (((attr->ns == NULL) && 6516 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6517 ((attr->ns != NULL) && 6518 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6519 6520 xmlSchemaPIllegalAttrErr(ctxt, 6521 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6522 } 6523 attr = attr->next; 6524 } 6525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6526 /* 6527 * And now for the children... 6528 */ 6529 child = node->children; 6530 while (child != NULL) { 6531 if (IS_SCHEMA(child, "appinfo")) { 6532 /* TODO: make available the content of "appinfo". */ 6533 /* 6534 * source = anyURI 6535 * {any attributes with non-schema namespace . . .}> 6536 * Content: ({any})* 6537 */ 6538 attr = child->properties; 6539 while (attr != NULL) { 6540 if (((attr->ns == NULL) && 6541 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6542 ((attr->ns != NULL) && 6543 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6544 6545 xmlSchemaPIllegalAttrErr(ctxt, 6546 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6547 } 6548 attr = attr->next; 6549 } 6550 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6551 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6552 child = child->next; 6553 } else if (IS_SCHEMA(child, "documentation")) { 6554 /* TODO: make available the content of "documentation". */ 6555 /* 6556 * source = anyURI 6557 * {any attributes with non-schema namespace . . .}> 6558 * Content: ({any})* 6559 */ 6560 attr = child->properties; 6561 while (attr != NULL) { 6562 if (attr->ns == NULL) { 6563 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6564 xmlSchemaPIllegalAttrErr(ctxt, 6565 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6566 } 6567 } else { 6568 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6569 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6570 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6571 6572 xmlSchemaPIllegalAttrErr(ctxt, 6573 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6574 } 6575 } 6576 attr = attr->next; 6577 } 6578 /* 6579 * Attribute "xml:lang". 6580 */ 6581 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6582 if (attr != NULL) 6583 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6584 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6585 child = child->next; 6586 } else { 6587 if (!barked) 6588 xmlSchemaPContentErr(ctxt, 6589 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6590 NULL, node, child, NULL, "(appinfo | documentation)*"); 6591 barked = 1; 6592 child = child->next; 6593 } 6594 } 6595 6596 return (ret); 6597} 6598 6599/** 6600 * xmlSchemaParseFacet: 6601 * @ctxt: a schema validation context 6602 * @schema: the schema being built 6603 * @node: a subtree containing XML Schema informations 6604 * 6605 * parse a XML schema Facet declaration 6606 * *WARNING* this interface is highly subject to change 6607 * 6608 * Returns the new type structure or NULL in case of error 6609 */ 6610static xmlSchemaFacetPtr 6611xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6612 xmlNodePtr node) 6613{ 6614 xmlSchemaFacetPtr facet; 6615 xmlNodePtr child = NULL; 6616 const xmlChar *value; 6617 6618 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6619 return (NULL); 6620 6621 facet = xmlSchemaNewFacet(); 6622 if (facet == NULL) { 6623 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6624 return (NULL); 6625 } 6626 facet->node = node; 6627 value = xmlSchemaGetProp(ctxt, node, "value"); 6628 if (value == NULL) { 6629 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6630 "Facet %s has no value\n", node->name, NULL); 6631 xmlSchemaFreeFacet(facet); 6632 return (NULL); 6633 } 6634 if (IS_SCHEMA(node, "minInclusive")) { 6635 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6636 } else if (IS_SCHEMA(node, "minExclusive")) { 6637 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6638 } else if (IS_SCHEMA(node, "maxInclusive")) { 6639 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6640 } else if (IS_SCHEMA(node, "maxExclusive")) { 6641 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6642 } else if (IS_SCHEMA(node, "totalDigits")) { 6643 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6644 } else if (IS_SCHEMA(node, "fractionDigits")) { 6645 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6646 } else if (IS_SCHEMA(node, "pattern")) { 6647 facet->type = XML_SCHEMA_FACET_PATTERN; 6648 } else if (IS_SCHEMA(node, "enumeration")) { 6649 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6650 } else if (IS_SCHEMA(node, "whiteSpace")) { 6651 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6652 } else if (IS_SCHEMA(node, "length")) { 6653 facet->type = XML_SCHEMA_FACET_LENGTH; 6654 } else if (IS_SCHEMA(node, "maxLength")) { 6655 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6656 } else if (IS_SCHEMA(node, "minLength")) { 6657 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6658 } else { 6659 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6660 "Unknown facet type %s\n", node->name, NULL); 6661 xmlSchemaFreeFacet(facet); 6662 return (NULL); 6663 } 6664 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6665 facet->value = value; 6666 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6667 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6668 const xmlChar *fixed; 6669 6670 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6671 if (fixed != NULL) { 6672 if (xmlStrEqual(fixed, BAD_CAST "true")) 6673 facet->fixed = 1; 6674 } 6675 } 6676 child = node->children; 6677 6678 if (IS_SCHEMA(child, "annotation")) { 6679 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6680 child = child->next; 6681 } 6682 if (child != NULL) { 6683 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6684 "Facet %s has unexpected child content\n", 6685 node->name, NULL); 6686 } 6687 return (facet); 6688} 6689 6690/** 6691 * xmlSchemaParseWildcardNs: 6692 * @ctxt: a schema parser context 6693 * @wildc: the wildcard, already created 6694 * @node: a subtree containing XML Schema informations 6695 * 6696 * Parses the attribute "processContents" and "namespace" 6697 * of a xsd:anyAttribute and xsd:any. 6698 * *WARNING* this interface is highly subject to change 6699 * 6700 * Returns 0 if everything goes fine, a positive error code 6701 * if something is not valid and -1 if an internal error occurs. 6702 */ 6703static int 6704xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6705 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6706 xmlSchemaWildcardPtr wildc, 6707 xmlNodePtr node) 6708{ 6709 const xmlChar *pc, *ns, *dictnsItem; 6710 int ret = 0; 6711 xmlChar *nsItem; 6712 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6713 xmlAttrPtr attr; 6714 6715 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6716 if ((pc == NULL) 6717 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6718 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6719 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6720 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6721 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6722 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6723 } else { 6724 xmlSchemaPSimpleTypeErr(ctxt, 6725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6726 NULL, node, 6727 NULL, "(strict | skip | lax)", pc, 6728 NULL, NULL, NULL); 6729 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6730 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6731 } 6732 /* 6733 * Build the namespace constraints. 6734 */ 6735 attr = xmlSchemaGetPropNode(node, "namespace"); 6736 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6737 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6738 wildc->any = 1; 6739 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6740 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6741 if (wildc->negNsSet == NULL) { 6742 return (-1); 6743 } 6744 wildc->negNsSet->value = ctxt->targetNamespace; 6745 } else { 6746 const xmlChar *end, *cur; 6747 6748 cur = ns; 6749 do { 6750 while (IS_BLANK_CH(*cur)) 6751 cur++; 6752 end = cur; 6753 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6754 end++; 6755 if (end == cur) 6756 break; 6757 nsItem = xmlStrndup(cur, end - cur); 6758 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6759 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6760 xmlSchemaPSimpleTypeErr(ctxt, 6761 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6762 NULL, (xmlNodePtr) attr, 6763 NULL, 6764 "((##any | ##other) | List of (xs:anyURI | " 6765 "(##targetNamespace | ##local)))", 6766 nsItem, NULL, NULL, NULL); 6767 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6768 } else { 6769 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6770 dictnsItem = ctxt->targetNamespace; 6771 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6772 dictnsItem = NULL; 6773 } else { 6774 /* 6775 * Validate the item (anyURI). 6776 */ 6777 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6778 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6779 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6780 } 6781 /* 6782 * Avoid dublicate namespaces. 6783 */ 6784 tmp = wildc->nsSet; 6785 while (tmp != NULL) { 6786 if (dictnsItem == tmp->value) 6787 break; 6788 tmp = tmp->next; 6789 } 6790 if (tmp == NULL) { 6791 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6792 if (tmp == NULL) { 6793 xmlFree(nsItem); 6794 return (-1); 6795 } 6796 tmp->value = dictnsItem; 6797 tmp->next = NULL; 6798 if (wildc->nsSet == NULL) 6799 wildc->nsSet = tmp; 6800 else 6801 lastNs->next = tmp; 6802 lastNs = tmp; 6803 } 6804 6805 } 6806 xmlFree(nsItem); 6807 cur = end; 6808 } while (*cur != 0); 6809 } 6810 return (ret); 6811} 6812 6813static int 6814xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6815 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6816 xmlNodePtr node, 6817 int minOccurs, 6818 int maxOccurs) { 6819 6820 if ((maxOccurs == 0) && ( minOccurs == 0)) 6821 return (0); 6822 if (maxOccurs != UNBOUNDED) { 6823 /* 6824 * TODO: Maybe we should better not create the particle, 6825 * if min/max is invalid, since it could confuse the build of the 6826 * content model. 6827 */ 6828 /* 6829 * 3.9.6 Schema Component Constraint: Particle Correct 6830 * 6831 */ 6832 if (maxOccurs < 1) { 6833 /* 6834 * 2.2 {max occurs} must be greater than or equal to 1. 6835 */ 6836 xmlSchemaPCustomAttrErr(ctxt, 6837 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6838 NULL, NULL, 6839 xmlSchemaGetPropNode(node, "maxOccurs"), 6840 "The value must be greater than or equal to 1"); 6841 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6842 } else if (minOccurs > maxOccurs) { 6843 /* 6844 * 2.1 {min occurs} must not be greater than {max occurs}. 6845 */ 6846 xmlSchemaPCustomAttrErr(ctxt, 6847 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6848 NULL, NULL, 6849 xmlSchemaGetPropNode(node, "minOccurs"), 6850 "The value must not be greater than the value of 'maxOccurs'"); 6851 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6852 } 6853 } 6854 return (0); 6855} 6856 6857/** 6858 * xmlSchemaParseAny: 6859 * @ctxt: a schema validation context 6860 * @schema: the schema being built 6861 * @node: a subtree containing XML Schema informations 6862 * 6863 * Parsea a XML schema <any> element. A particle and wildcard 6864 * will be created (except if minOccurs==maxOccurs==0, in this case 6865 * nothing will be created). 6866 * *WARNING* this interface is highly subject to change 6867 * 6868 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6869 */ 6870static xmlSchemaParticlePtr 6871xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6872 xmlNodePtr node) 6873{ 6874 xmlSchemaParticlePtr particle; 6875 xmlNodePtr child = NULL; 6876 xmlSchemaWildcardPtr wild; 6877 int min, max; 6878 xmlAttrPtr attr; 6879 xmlSchemaAnnotPtr annot = NULL; 6880 6881 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6882 return (NULL); 6883 /* 6884 * Check for illegal attributes. 6885 */ 6886 attr = node->properties; 6887 while (attr != NULL) { 6888 if (attr->ns == NULL) { 6889 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6890 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6891 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6892 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6893 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6894 xmlSchemaPIllegalAttrErr(ctxt, 6895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6896 } 6897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6898 xmlSchemaPIllegalAttrErr(ctxt, 6899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6900 } 6901 attr = attr->next; 6902 } 6903 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6904 /* 6905 * minOccurs/maxOccurs. 6906 */ 6907 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6908 "(xs:nonNegativeInteger | unbounded)"); 6909 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6910 "xs:nonNegativeInteger"); 6911 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6912 /* 6913 * Create & parse the wildcard. 6914 */ 6915 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6916 if (wild == NULL) 6917 return (NULL); 6918 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6919 /* 6920 * And now for the children... 6921 */ 6922 child = node->children; 6923 if (IS_SCHEMA(child, "annotation")) { 6924 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6925 child = child->next; 6926 } 6927 if (child != NULL) { 6928 xmlSchemaPContentErr(ctxt, 6929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6930 NULL, node, child, 6931 NULL, "(annotation?)"); 6932 } 6933 /* 6934 * No component if minOccurs==maxOccurs==0. 6935 */ 6936 if ((min == 0) && (max == 0)) { 6937 /* Don't free the wildcard, since it's already on the list. */ 6938 return (NULL); 6939 } 6940 /* 6941 * Create the particle. 6942 */ 6943 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6944 if (particle == NULL) 6945 return (NULL); 6946 particle->annot = annot; 6947 particle->children = (xmlSchemaTreeItemPtr) wild; 6948 6949 return (particle); 6950} 6951 6952/** 6953 * xmlSchemaParseNotation: 6954 * @ctxt: a schema validation context 6955 * @schema: the schema being built 6956 * @node: a subtree containing XML Schema informations 6957 * 6958 * parse a XML schema Notation declaration 6959 * 6960 * Returns the new structure or NULL in case of error 6961 */ 6962static xmlSchemaNotationPtr 6963xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6964 xmlNodePtr node) 6965{ 6966 const xmlChar *name; 6967 xmlSchemaNotationPtr ret; 6968 xmlNodePtr child = NULL; 6969 6970 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6971 return (NULL); 6972 name = xmlSchemaGetProp(ctxt, node, "name"); 6973 if (name == NULL) { 6974 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 6975 "Notation has no name\n", NULL, NULL); 6976 return (NULL); 6977 } 6978 ret = xmlSchemaAddNotation(ctxt, schema, name, 6979 ctxt->targetNamespace, node); 6980 if (ret == NULL) 6981 return (NULL); 6982 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6983 6984 child = node->children; 6985 if (IS_SCHEMA(child, "annotation")) { 6986 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6987 child = child->next; 6988 } 6989 if (child != NULL) { 6990 xmlSchemaPContentErr(ctxt, 6991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6992 NULL, node, child, 6993 NULL, "(annotation?)"); 6994 } 6995 6996 return (ret); 6997} 6998 6999/** 7000 * xmlSchemaParseAnyAttribute: 7001 * @ctxt: a schema validation context 7002 * @schema: the schema being built 7003 * @node: a subtree containing XML Schema informations 7004 * 7005 * parse a XML schema AnyAttrribute declaration 7006 * *WARNING* this interface is highly subject to change 7007 * 7008 * Returns a wildcard or NULL. 7009 */ 7010static xmlSchemaWildcardPtr 7011xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7012 xmlSchemaPtr schema, xmlNodePtr node) 7013{ 7014 xmlSchemaWildcardPtr ret; 7015 xmlNodePtr child = NULL; 7016 xmlAttrPtr attr; 7017 7018 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7019 return (NULL); 7020 7021 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7022 node); 7023 if (ret == NULL) { 7024 return (NULL); 7025 } 7026 /* 7027 * Check for illegal attributes. 7028 */ 7029 attr = node->properties; 7030 while (attr != NULL) { 7031 if (attr->ns == NULL) { 7032 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7033 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7034 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7035 xmlSchemaPIllegalAttrErr(ctxt, 7036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7037 } 7038 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7039 xmlSchemaPIllegalAttrErr(ctxt, 7040 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7041 } 7042 attr = attr->next; 7043 } 7044 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7045 /* 7046 * Parse the namespace list. 7047 */ 7048 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7049 return (NULL); 7050 /* 7051 * And now for the children... 7052 */ 7053 child = node->children; 7054 if (IS_SCHEMA(child, "annotation")) { 7055 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7056 child = child->next; 7057 } 7058 if (child != NULL) { 7059 xmlSchemaPContentErr(ctxt, 7060 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7061 NULL, node, child, 7062 NULL, "(annotation?)"); 7063 } 7064 7065 return (ret); 7066} 7067 7068 7069/** 7070 * xmlSchemaParseAttribute: 7071 * @ctxt: a schema validation context 7072 * @schema: the schema being built 7073 * @node: a subtree containing XML Schema informations 7074 * 7075 * parse a XML schema Attrribute declaration 7076 * *WARNING* this interface is highly subject to change 7077 * 7078 * Returns the attribute declaration. 7079 */ 7080static xmlSchemaBasicItemPtr 7081xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7082 xmlSchemaPtr schema, 7083 xmlNodePtr node, 7084 xmlSchemaItemListPtr uses, 7085 int parentType) 7086{ 7087 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7088 xmlSchemaAttributeUsePtr use = NULL; 7089 xmlNodePtr child = NULL; 7090 xmlAttrPtr attr; 7091 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7092 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7093 int nberrors, hasForm = 0, defValueType = 0; 7094 7095#define WXS_ATTR_DEF_VAL_DEFAULT 1 7096#define WXS_ATTR_DEF_VAL_FIXED 2 7097 7098 /* 7099 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7100 */ 7101 7102 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7103 return (NULL); 7104 attr = xmlSchemaGetPropNode(node, "ref"); 7105 if (attr != NULL) { 7106 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7107 NULL, attr, &tmpNs, &tmpName) != 0) { 7108 return (NULL); 7109 } 7110 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7111 return(NULL); 7112 isRef = 1; 7113 } 7114 nberrors = pctxt->nberrors; 7115 /* 7116 * Check for illegal attributes. 7117 */ 7118 attr = node->properties; 7119 while (attr != NULL) { 7120 if (attr->ns == NULL) { 7121 if (isRef) { 7122 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7123 xmlSchemaPValAttrNodeID(pctxt, attr); 7124 goto attr_next; 7125 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7126 goto attr_next; 7127 } 7128 } else { 7129 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7130 goto attr_next; 7131 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7132 xmlSchemaPValAttrNodeID(pctxt, attr); 7133 goto attr_next; 7134 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7135 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7136 attr, &tmpNs, &tmpName); 7137 goto attr_next; 7138 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7139 /* 7140 * Evaluate the target namespace 7141 */ 7142 hasForm = 1; 7143 attrValue = xmlSchemaGetNodeContent(pctxt, 7144 (xmlNodePtr) attr); 7145 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7146 ns = pctxt->targetNamespace; 7147 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7148 { 7149 xmlSchemaPSimpleTypeErr(pctxt, 7150 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7151 NULL, (xmlNodePtr) attr, 7152 NULL, "(qualified | unqualified)", 7153 attrValue, NULL, NULL, NULL); 7154 } 7155 goto attr_next; 7156 } 7157 } 7158 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7159 7160 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7161 /* TODO: Maybe we need to normalize the value beforehand. */ 7162 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7163 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7164 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7165 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7166 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7167 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7168 else { 7169 xmlSchemaPSimpleTypeErr(pctxt, 7170 XML_SCHEMAP_INVALID_ATTR_USE, 7171 NULL, (xmlNodePtr) attr, 7172 NULL, "(optional | prohibited | required)", 7173 attrValue, NULL, NULL, NULL); 7174 } 7175 goto attr_next; 7176 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7177 /* 7178 * 3.2.3 : 1 7179 * default and fixed must not both be present. 7180 */ 7181 if (defValue) { 7182 xmlSchemaPMutualExclAttrErr(pctxt, 7183 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7184 NULL, attr, "default", "fixed"); 7185 } else { 7186 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7187 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7188 } 7189 goto attr_next; 7190 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7191 /* 7192 * 3.2.3 : 1 7193 * default and fixed must not both be present. 7194 */ 7195 if (defValue) { 7196 xmlSchemaPMutualExclAttrErr(pctxt, 7197 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7198 NULL, attr, "default", "fixed"); 7199 } else { 7200 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7201 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7202 } 7203 goto attr_next; 7204 } 7205 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7206 goto attr_next; 7207 7208 xmlSchemaPIllegalAttrErr(pctxt, 7209 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7210 7211attr_next: 7212 attr = attr->next; 7213 } 7214 /* 7215 * 3.2.3 : 2 7216 * If default and use are both present, use must have 7217 * the actual value optional. 7218 */ 7219 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7220 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7221 xmlSchemaPSimpleTypeErr(pctxt, 7222 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7223 NULL, node, NULL, 7224 "(optional | prohibited | required)", NULL, 7225 "The value of the attribute 'use' must be 'optional' " 7226 "if the attribute 'default' is present", 7227 NULL, NULL); 7228 } 7229 /* 7230 * We want correct attributes. 7231 */ 7232 if (nberrors != pctxt->nberrors) 7233 return(NULL); 7234 if (! isRef) { 7235 xmlSchemaAttributePtr attrDecl; 7236 7237 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7238 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7239 ns = pctxt->targetNamespace; 7240 /* 7241 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7242 * TODO: Move this to the component layer. 7243 */ 7244 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7246 XML_SCHEMAP_NO_XSI, 7247 node, NULL, 7248 "The target namespace must not match '%s'", 7249 xmlSchemaInstanceNs, NULL); 7250 } 7251 attr = xmlSchemaGetPropNode(node, "name"); 7252 if (attr == NULL) { 7253 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7254 NULL, node, "name", NULL); 7255 return (NULL); 7256 } 7257 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7259 return (NULL); 7260 } 7261 /* 7262 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7263 * TODO: Move this to the component layer. 7264 */ 7265 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7266 xmlSchemaPSimpleTypeErr(pctxt, 7267 XML_SCHEMAP_NO_XMLNS, 7268 NULL, (xmlNodePtr) attr, 7269 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7270 "The value of the attribute must not match 'xmlns'", 7271 NULL, NULL); 7272 return (NULL); 7273 } 7274 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7275 goto check_children; 7276 /* 7277 * Create the attribute use component. 7278 */ 7279 use = xmlSchemaAddAttributeUse(pctxt, node); 7280 if (use == NULL) 7281 return(NULL); 7282 use->occurs = occurs; 7283 /* 7284 * Create the attribute declaration. 7285 */ 7286 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7287 if (attrDecl == NULL) 7288 return (NULL); 7289 if (tmpName != NULL) { 7290 attrDecl->typeName = tmpName; 7291 attrDecl->typeNs = tmpNs; 7292 } 7293 use->attrDecl = attrDecl; 7294 /* 7295 * Value constraint. 7296 */ 7297 if (defValue != NULL) { 7298 attrDecl->defValue = defValue; 7299 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7300 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7301 } 7302 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7303 xmlSchemaQNameRefPtr ref; 7304 7305 /* 7306 * Create the attribute use component. 7307 */ 7308 use = xmlSchemaAddAttributeUse(pctxt, node); 7309 if (use == NULL) 7310 return(NULL); 7311 /* 7312 * We need to resolve the reference at later stage. 7313 */ 7314 WXS_ADD_PENDING(pctxt, use); 7315 use->occurs = occurs; 7316 /* 7317 * Create a QName reference to the attribute declaration. 7318 */ 7319 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7320 tmpName, tmpNs); 7321 if (ref == NULL) 7322 return(NULL); 7323 /* 7324 * Assign the reference. This will be substituted for the 7325 * referenced attribute declaration when the QName is resolved. 7326 */ 7327 use->attrDecl = WXS_ATTR_CAST ref; 7328 /* 7329 * Value constraint. 7330 */ 7331 if (defValue != NULL) 7332 use->defValue = defValue; 7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7334 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7335 } 7336 7337check_children: 7338 /* 7339 * And now for the children... 7340 */ 7341 child = node->children; 7342 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7343 xmlSchemaAttributeUseProhibPtr prohib; 7344 7345 if (IS_SCHEMA(child, "annotation")) { 7346 xmlSchemaParseAnnotation(pctxt, child, 0); 7347 child = child->next; 7348 } 7349 if (child != NULL) { 7350 xmlSchemaPContentErr(pctxt, 7351 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7352 NULL, node, child, NULL, 7353 "(annotation?)"); 7354 } 7355 /* 7356 * Check for pointlessness of attribute prohibitions. 7357 */ 7358 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7359 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7360 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7361 node, NULL, 7362 "Skipping attribute use prohibition, since it is " 7363 "pointless inside an <attributeGroup>", 7364 NULL, NULL, NULL); 7365 return(NULL); 7366 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7367 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7368 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7369 node, NULL, 7370 "Skipping attribute use prohibition, since it is " 7371 "pointless when extending a type", 7372 NULL, NULL, NULL); 7373 return(NULL); 7374 } 7375 if (! isRef) { 7376 tmpName = name; 7377 tmpNs = ns; 7378 } 7379 /* 7380 * Check for duplicate attribute prohibitions. 7381 */ 7382 if (uses) { 7383 int i; 7384 7385 for (i = 0; i < uses->nbItems; i++) { 7386 use = uses->items[i]; 7387 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7388 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7389 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7390 { 7391 xmlChar *str = NULL; 7392 7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7395 node, NULL, 7396 "Skipping duplicate attribute use prohibition '%s'", 7397 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7398 NULL, NULL); 7399 FREE_AND_NULL(str) 7400 return(NULL); 7401 } 7402 } 7403 } 7404 /* 7405 * Create the attribute prohibition helper component. 7406 */ 7407 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7408 if (prohib == NULL) 7409 return(NULL); 7410 prohib->node = node; 7411 prohib->name = tmpName; 7412 prohib->targetNamespace = tmpNs; 7413 if (isRef) { 7414 /* 7415 * We need at least to resolve to the attribute declaration. 7416 */ 7417 WXS_ADD_PENDING(pctxt, prohib); 7418 } 7419 return(WXS_BASIC_CAST prohib); 7420 } else { 7421 if (IS_SCHEMA(child, "annotation")) { 7422 /* 7423 * TODO: Should this go into the attr decl? 7424 */ 7425 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7426 child = child->next; 7427 } 7428 if (isRef) { 7429 if (child != NULL) { 7430 if (IS_SCHEMA(child, "simpleType")) 7431 /* 7432 * 3.2.3 : 3.2 7433 * If ref is present, then all of <simpleType>, 7434 * form and type must be absent. 7435 */ 7436 xmlSchemaPContentErr(pctxt, 7437 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7438 NULL, node, child, NULL, 7439 "(annotation?)"); 7440 else 7441 xmlSchemaPContentErr(pctxt, 7442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7443 NULL, node, child, NULL, 7444 "(annotation?)"); 7445 } 7446 } else { 7447 if (IS_SCHEMA(child, "simpleType")) { 7448 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7449 /* 7450 * 3.2.3 : 4 7451 * type and <simpleType> must not both be present. 7452 */ 7453 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7454 NULL, node, child, 7455 "The attribute 'type' and the <simpleType> child " 7456 "are mutually exclusive", NULL); 7457 } else 7458 WXS_ATTRUSE_TYPEDEF(use) = 7459 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7460 child = child->next; 7461 } 7462 if (child != NULL) 7463 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7464 NULL, node, child, NULL, 7465 "(annotation?, simpleType?)"); 7466 } 7467 } 7468 return (WXS_BASIC_CAST use); 7469} 7470 7471 7472static xmlSchemaAttributePtr 7473xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7474 xmlSchemaPtr schema, 7475 xmlNodePtr node) 7476{ 7477 const xmlChar *attrValue; 7478 xmlSchemaAttributePtr ret; 7479 xmlNodePtr child = NULL; 7480 xmlAttrPtr attr; 7481 7482 /* 7483 * Note that the w3c spec assumes the schema to be validated with schema 7484 * for schemas beforehand. 7485 * 7486 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7487 */ 7488 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7489 return (NULL); 7490 /* 7491 * 3.2.3 : 3.1 7492 * One of ref or name must be present, but not both 7493 */ 7494 attr = xmlSchemaGetPropNode(node, "name"); 7495 if (attr == NULL) { 7496 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7497 NULL, node, "name", NULL); 7498 return (NULL); 7499 } 7500 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7502 return (NULL); 7503 } 7504 /* 7505 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7506 * TODO: Move this to the component layer. 7507 */ 7508 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7509 xmlSchemaPSimpleTypeErr(pctxt, 7510 XML_SCHEMAP_NO_XMLNS, 7511 NULL, (xmlNodePtr) attr, 7512 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7513 "The value of the attribute must not match 'xmlns'", 7514 NULL, NULL); 7515 return (NULL); 7516 } 7517 /* 7518 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7519 * TODO: Move this to the component layer. 7520 * Or better leave it here and add it to the component layer 7521 * if we have a schema construction API. 7522 */ 7523 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7524 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7525 XML_SCHEMAP_NO_XSI, node, NULL, 7526 "The target namespace must not match '%s'", 7527 xmlSchemaInstanceNs, NULL); 7528 } 7529 7530 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7531 pctxt->targetNamespace, node, 1); 7532 if (ret == NULL) 7533 return (NULL); 7534 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7535 7536 /* 7537 * Check for illegal attributes. 7538 */ 7539 attr = node->properties; 7540 while (attr != NULL) { 7541 if (attr->ns == NULL) { 7542 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7543 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7544 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7545 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7546 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7547 { 7548 xmlSchemaPIllegalAttrErr(pctxt, 7549 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7550 } 7551 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7552 xmlSchemaPIllegalAttrErr(pctxt, 7553 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7554 } 7555 attr = attr->next; 7556 } 7557 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7558 node, "type", &ret->typeNs, &ret->typeName); 7559 7560 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7561 /* 7562 * Attribute "fixed". 7563 */ 7564 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7565 if (ret->defValue != NULL) 7566 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7567 /* 7568 * Attribute "default". 7569 */ 7570 attr = xmlSchemaGetPropNode(node, "default"); 7571 if (attr != NULL) { 7572 /* 7573 * 3.2.3 : 1 7574 * default and fixed must not both be present. 7575 */ 7576 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7577 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7578 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7579 } else 7580 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7581 } 7582 /* 7583 * And now for the children... 7584 */ 7585 child = node->children; 7586 if (IS_SCHEMA(child, "annotation")) { 7587 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7588 child = child->next; 7589 } 7590 if (IS_SCHEMA(child, "simpleType")) { 7591 if (ret->typeName != NULL) { 7592 /* 7593 * 3.2.3 : 4 7594 * type and <simpleType> must not both be present. 7595 */ 7596 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7597 NULL, node, child, 7598 "The attribute 'type' and the <simpleType> child " 7599 "are mutually exclusive", NULL); 7600 } else 7601 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7602 child = child->next; 7603 } 7604 if (child != NULL) 7605 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7606 NULL, node, child, NULL, 7607 "(annotation?, simpleType?)"); 7608 7609 return (ret); 7610} 7611 7612/** 7613 * xmlSchemaParseAttributeGroupRef: 7614 * @ctxt: a schema validation context 7615 * @schema: the schema being built 7616 * @node: a subtree containing XML Schema informations 7617 * 7618 * Parse an attribute group definition reference. 7619 * Note that a reference to an attribute group does not 7620 * correspond to any component at all. 7621 * *WARNING* this interface is highly subject to change 7622 * 7623 * Returns the attribute group or NULL in case of error. 7624 */ 7625static xmlSchemaQNameRefPtr 7626xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7627 xmlSchemaPtr schema, 7628 xmlNodePtr node) 7629{ 7630 xmlSchemaQNameRefPtr ret; 7631 xmlNodePtr child = NULL; 7632 xmlAttrPtr attr; 7633 const xmlChar *refNs = NULL, *ref = NULL; 7634 7635 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7636 return (NULL); 7637 7638 attr = xmlSchemaGetPropNode(node, "ref"); 7639 if (attr == NULL) { 7640 xmlSchemaPMissingAttrErr(pctxt, 7641 XML_SCHEMAP_S4S_ATTR_MISSING, 7642 NULL, node, "ref", NULL); 7643 return (NULL); 7644 } 7645 xmlSchemaPValAttrNodeQName(pctxt, schema, 7646 NULL, attr, &refNs, &ref); 7647 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7648 return(NULL); 7649 7650 /* 7651 * Check for illegal attributes. 7652 */ 7653 attr = node->properties; 7654 while (attr != NULL) { 7655 if (attr->ns == NULL) { 7656 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7657 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7658 { 7659 xmlSchemaPIllegalAttrErr(pctxt, 7660 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7661 } 7662 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7663 xmlSchemaPIllegalAttrErr(pctxt, 7664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7665 } 7666 attr = attr->next; 7667 } 7668 /* Attribute ID */ 7669 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7670 7671 /* 7672 * And now for the children... 7673 */ 7674 child = node->children; 7675 if (IS_SCHEMA(child, "annotation")) { 7676 /* 7677 * TODO: We do not have a place to store the annotation, do we? 7678 */ 7679 xmlSchemaParseAnnotation(pctxt, child, 0); 7680 child = child->next; 7681 } 7682 if (child != NULL) { 7683 xmlSchemaPContentErr(pctxt, 7684 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7685 NULL, node, child, NULL, 7686 "(annotation?)"); 7687 } 7688 7689 /* 7690 * Handle attribute group redefinitions. 7691 */ 7692 if (pctxt->isRedefine && pctxt->redef && 7693 (pctxt->redef->item->type == 7694 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7695 (ref == pctxt->redef->refName) && 7696 (refNs == pctxt->redef->refTargetNs)) 7697 { 7698 /* 7699 * SPEC src-redefine: 7700 * (7.1) "If it has an <attributeGroup> among its contents 7701 * the �actual value� of whose ref [attribute] is the same 7702 * as the �actual value� of its own name attribute plus 7703 * target namespace, then it must have exactly one such group." 7704 */ 7705 if (pctxt->redefCounter != 0) { 7706 xmlChar *str = NULL; 7707 7708 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7709 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7710 "The redefining attribute group definition " 7711 "'%s' must not contain more than one " 7712 "reference to the redefined definition", 7713 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7714 FREE_AND_NULL(str); 7715 return(NULL); 7716 } 7717 pctxt->redefCounter++; 7718 /* 7719 * URGENT TODO: How to ensure that the reference will not be 7720 * handled by the normal component resolution mechanism? 7721 */ 7722 ret = xmlSchemaNewQNameRef(pctxt, 7723 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7724 if (ret == NULL) 7725 return(NULL); 7726 ret->node = node; 7727 pctxt->redef->reference = WXS_BASIC_CAST ret; 7728 } else { 7729 /* 7730 * Create a QName-reference helper component. We will substitute this 7731 * component for the attribute uses of the referenced attribute group 7732 * definition. 7733 */ 7734 ret = xmlSchemaNewQNameRef(pctxt, 7735 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7736 if (ret == NULL) 7737 return(NULL); 7738 ret->node = node; 7739 /* Add to pending items, to be able to resolve the reference. */ 7740 WXS_ADD_PENDING(pctxt, ret); 7741 } 7742 return (ret); 7743} 7744 7745/** 7746 * xmlSchemaParseAttributeGroupDefinition: 7747 * @pctxt: a schema validation context 7748 * @schema: the schema being built 7749 * @node: a subtree containing XML Schema informations 7750 * 7751 * parse a XML schema Attribute Group declaration 7752 * *WARNING* this interface is highly subject to change 7753 * 7754 * Returns the attribute group definition or NULL in case of error. 7755 */ 7756static xmlSchemaAttributeGroupPtr 7757xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7758 xmlSchemaPtr schema, 7759 xmlNodePtr node) 7760{ 7761 const xmlChar *name; 7762 xmlSchemaAttributeGroupPtr ret; 7763 xmlNodePtr child = NULL; 7764 xmlAttrPtr attr; 7765 int hasRefs = 0; 7766 7767 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7768 return (NULL); 7769 7770 attr = xmlSchemaGetPropNode(node, "name"); 7771 if (attr == NULL) { 7772 xmlSchemaPMissingAttrErr(pctxt, 7773 XML_SCHEMAP_S4S_ATTR_MISSING, 7774 NULL, node, "name", NULL); 7775 return (NULL); 7776 } 7777 /* 7778 * The name is crucial, exit if invalid. 7779 */ 7780 if (xmlSchemaPValAttrNode(pctxt, 7781 NULL, attr, 7782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7783 return (NULL); 7784 } 7785 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7786 name, pctxt->targetNamespace, node); 7787 if (ret == NULL) 7788 return (NULL); 7789 /* 7790 * Check for illegal attributes. 7791 */ 7792 attr = node->properties; 7793 while (attr != NULL) { 7794 if (attr->ns == NULL) { 7795 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7796 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7797 { 7798 xmlSchemaPIllegalAttrErr(pctxt, 7799 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7800 } 7801 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7802 xmlSchemaPIllegalAttrErr(pctxt, 7803 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7804 } 7805 attr = attr->next; 7806 } 7807 /* Attribute ID */ 7808 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7809 /* 7810 * And now for the children... 7811 */ 7812 child = node->children; 7813 if (IS_SCHEMA(child, "annotation")) { 7814 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7815 child = child->next; 7816 } 7817 /* 7818 * Parse contained attribute decls/refs. 7819 */ 7820 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7821 (xmlSchemaItemListPtr *) &(ret->attrUses), 7822 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7823 return(NULL); 7824 if (hasRefs) 7825 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7826 /* 7827 * Parse the attribute wildcard. 7828 */ 7829 if (IS_SCHEMA(child, "anyAttribute")) { 7830 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7831 schema, child); 7832 child = child->next; 7833 } 7834 if (child != NULL) { 7835 xmlSchemaPContentErr(pctxt, 7836 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7837 NULL, node, child, NULL, 7838 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7839 } 7840 return (ret); 7841} 7842 7843/** 7844 * xmlSchemaPValAttrFormDefault: 7845 * @value: the value 7846 * @flags: the flags to be modified 7847 * @flagQualified: the specific flag for "qualified" 7848 * 7849 * Returns 0 if the value is valid, 1 otherwise. 7850 */ 7851static int 7852xmlSchemaPValAttrFormDefault(const xmlChar *value, 7853 int *flags, 7854 int flagQualified) 7855{ 7856 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7857 if ((*flags & flagQualified) == 0) 7858 *flags |= flagQualified; 7859 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7860 return (1); 7861 7862 return (0); 7863} 7864 7865/** 7866 * xmlSchemaPValAttrBlockFinal: 7867 * @value: the value 7868 * @flags: the flags to be modified 7869 * @flagAll: the specific flag for "#all" 7870 * @flagExtension: the specific flag for "extension" 7871 * @flagRestriction: the specific flag for "restriction" 7872 * @flagSubstitution: the specific flag for "substitution" 7873 * @flagList: the specific flag for "list" 7874 * @flagUnion: the specific flag for "union" 7875 * 7876 * Validates the value of the attribute "final" and "block". The value 7877 * is converted into the specified flag values and returned in @flags. 7878 * 7879 * Returns 0 if the value is valid, 1 otherwise. 7880 */ 7881 7882static int 7883xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7884 int *flags, 7885 int flagAll, 7886 int flagExtension, 7887 int flagRestriction, 7888 int flagSubstitution, 7889 int flagList, 7890 int flagUnion) 7891{ 7892 int ret = 0; 7893 7894 /* 7895 * TODO: This does not check for dublicate entries. 7896 */ 7897 if ((flags == NULL) || (value == NULL)) 7898 return (-1); 7899 if (value[0] == 0) 7900 return (0); 7901 if (xmlStrEqual(value, BAD_CAST "#all")) { 7902 if (flagAll != -1) 7903 *flags |= flagAll; 7904 else { 7905 if (flagExtension != -1) 7906 *flags |= flagExtension; 7907 if (flagRestriction != -1) 7908 *flags |= flagRestriction; 7909 if (flagSubstitution != -1) 7910 *flags |= flagSubstitution; 7911 if (flagList != -1) 7912 *flags |= flagList; 7913 if (flagUnion != -1) 7914 *flags |= flagUnion; 7915 } 7916 } else { 7917 const xmlChar *end, *cur = value; 7918 xmlChar *item; 7919 7920 do { 7921 while (IS_BLANK_CH(*cur)) 7922 cur++; 7923 end = cur; 7924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7925 end++; 7926 if (end == cur) 7927 break; 7928 item = xmlStrndup(cur, end - cur); 7929 if (xmlStrEqual(item, BAD_CAST "extension")) { 7930 if (flagExtension != -1) { 7931 if ((*flags & flagExtension) == 0) 7932 *flags |= flagExtension; 7933 } else 7934 ret = 1; 7935 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7936 if (flagRestriction != -1) { 7937 if ((*flags & flagRestriction) == 0) 7938 *flags |= flagRestriction; 7939 } else 7940 ret = 1; 7941 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7942 if (flagSubstitution != -1) { 7943 if ((*flags & flagSubstitution) == 0) 7944 *flags |= flagSubstitution; 7945 } else 7946 ret = 1; 7947 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7948 if (flagList != -1) { 7949 if ((*flags & flagList) == 0) 7950 *flags |= flagList; 7951 } else 7952 ret = 1; 7953 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7954 if (flagUnion != -1) { 7955 if ((*flags & flagUnion) == 0) 7956 *flags |= flagUnion; 7957 } else 7958 ret = 1; 7959 } else 7960 ret = 1; 7961 if (item != NULL) 7962 xmlFree(item); 7963 cur = end; 7964 } while ((ret == 0) && (*cur != 0)); 7965 } 7966 7967 return (ret); 7968} 7969 7970static int 7971xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 7972 xmlSchemaIDCPtr idc, 7973 xmlSchemaIDCSelectPtr selector, 7974 xmlAttrPtr attr, 7975 int isField) 7976{ 7977 xmlNodePtr node; 7978 7979 /* 7980 * c-selector-xpath: 7981 * Schema Component Constraint: Selector Value OK 7982 * 7983 * TODO: 1 The {selector} must be a valid XPath expression, as defined 7984 * in [XPath]. 7985 */ 7986 if (selector == NULL) { 7987 xmlSchemaPErr(ctxt, idc->node, 7988 XML_SCHEMAP_INTERNAL, 7989 "Internal error: xmlSchemaCheckCSelectorXPath, " 7990 "the selector is not specified.\n", NULL, NULL); 7991 return (-1); 7992 } 7993 if (attr == NULL) 7994 node = idc->node; 7995 else 7996 node = (xmlNodePtr) attr; 7997 if (selector->xpath == NULL) { 7998 xmlSchemaPCustomErr(ctxt, 7999 /* TODO: Adjust error code. */ 8000 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8001 NULL, node, 8002 "The XPath expression of the selector is not valid", NULL); 8003 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8004 } else { 8005 const xmlChar **nsArray = NULL; 8006 xmlNsPtr *nsList = NULL; 8007 /* 8008 * Compile the XPath expression. 8009 */ 8010 /* 8011 * TODO: We need the array of in-scope namespaces for compilation. 8012 * TODO: Call xmlPatterncompile with different options for selector/ 8013 * field. 8014 */ 8015 if (attr == NULL) 8016 nsList = NULL; 8017 else 8018 nsList = xmlGetNsList(attr->doc, attr->parent); 8019 /* 8020 * Build an array of prefixes and namespaces. 8021 */ 8022 if (nsList != NULL) { 8023 int i, count = 0; 8024 8025 for (i = 0; nsList[i] != NULL; i++) 8026 count++; 8027 8028 nsArray = (const xmlChar **) xmlMalloc( 8029 (count * 2 + 1) * sizeof(const xmlChar *)); 8030 if (nsArray == NULL) { 8031 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8032 NULL); 8033 xmlFree(nsList); 8034 return (-1); 8035 } 8036 for (i = 0; i < count; i++) { 8037 nsArray[2 * i] = nsList[i]->href; 8038 nsArray[2 * i + 1] = nsList[i]->prefix; 8039 } 8040 nsArray[count * 2] = NULL; 8041 xmlFree(nsList); 8042 } 8043 /* 8044 * TODO: Differentiate between "selector" and "field". 8045 */ 8046 if (isField) 8047 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8048 NULL, XML_PATTERN_XSFIELD, nsArray); 8049 else 8050 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8051 NULL, XML_PATTERN_XSSEL, nsArray); 8052 if (nsArray != NULL) 8053 xmlFree((xmlChar **) nsArray); 8054 8055 if (selector->xpathComp == NULL) { 8056 xmlSchemaPCustomErr(ctxt, 8057 /* TODO: Adjust error code? */ 8058 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8059 NULL, node, 8060 "The XPath expression '%s' could not be " 8061 "compiled", selector->xpath); 8062 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8063 } 8064 } 8065 return (0); 8066} 8067 8068#define ADD_ANNOTATION(annot) \ 8069 xmlSchemaAnnotPtr cur = item->annot; \ 8070 if (item->annot == NULL) { \ 8071 item->annot = annot; \ 8072 return (annot); \ 8073 } \ 8074 cur = item->annot; \ 8075 if (cur->next != NULL) { \ 8076 cur = cur->next; \ 8077 } \ 8078 cur->next = annot; 8079 8080/** 8081 * xmlSchemaAssignAnnotation: 8082 * @item: the schema component 8083 * @annot: the annotation 8084 * 8085 * Adds the annotation to the given schema component. 8086 * 8087 * Returns the given annotaion. 8088 */ 8089static xmlSchemaAnnotPtr 8090xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8091 xmlSchemaAnnotPtr annot) 8092{ 8093 if ((annItem == NULL) || (annot == NULL)) 8094 return (NULL); 8095 switch (annItem->type) { 8096 case XML_SCHEMA_TYPE_ELEMENT: { 8097 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8098 ADD_ANNOTATION(annot) 8099 } 8100 break; 8101 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8102 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8103 ADD_ANNOTATION(annot) 8104 } 8105 break; 8106 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8107 case XML_SCHEMA_TYPE_ANY: { 8108 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8109 ADD_ANNOTATION(annot) 8110 } 8111 break; 8112 case XML_SCHEMA_TYPE_PARTICLE: 8113 case XML_SCHEMA_TYPE_IDC_KEY: 8114 case XML_SCHEMA_TYPE_IDC_KEYREF: 8115 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8116 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8117 ADD_ANNOTATION(annot) 8118 } 8119 break; 8120 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8121 xmlSchemaAttributeGroupPtr item = 8122 (xmlSchemaAttributeGroupPtr) annItem; 8123 ADD_ANNOTATION(annot) 8124 } 8125 break; 8126 case XML_SCHEMA_TYPE_NOTATION: { 8127 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8128 ADD_ANNOTATION(annot) 8129 } 8130 break; 8131 case XML_SCHEMA_FACET_MININCLUSIVE: 8132 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8133 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8134 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8135 case XML_SCHEMA_FACET_TOTALDIGITS: 8136 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8137 case XML_SCHEMA_FACET_PATTERN: 8138 case XML_SCHEMA_FACET_ENUMERATION: 8139 case XML_SCHEMA_FACET_WHITESPACE: 8140 case XML_SCHEMA_FACET_LENGTH: 8141 case XML_SCHEMA_FACET_MAXLENGTH: 8142 case XML_SCHEMA_FACET_MINLENGTH: { 8143 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8144 ADD_ANNOTATION(annot) 8145 } 8146 break; 8147 case XML_SCHEMA_TYPE_SIMPLE: 8148 case XML_SCHEMA_TYPE_COMPLEX: { 8149 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8150 ADD_ANNOTATION(annot) 8151 } 8152 break; 8153 case XML_SCHEMA_TYPE_GROUP: { 8154 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8155 ADD_ANNOTATION(annot) 8156 } 8157 break; 8158 case XML_SCHEMA_TYPE_SEQUENCE: 8159 case XML_SCHEMA_TYPE_CHOICE: 8160 case XML_SCHEMA_TYPE_ALL: { 8161 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8162 ADD_ANNOTATION(annot) 8163 } 8164 break; 8165 default: 8166 xmlSchemaPCustomErr(NULL, 8167 XML_SCHEMAP_INTERNAL, 8168 NULL, NULL, 8169 "Internal error: xmlSchemaAddAnnotation, " 8170 "The item is not a annotated schema component", NULL); 8171 break; 8172 } 8173 return (annot); 8174} 8175 8176/** 8177 * xmlSchemaParseIDCSelectorAndField: 8178 * @ctxt: a schema validation context 8179 * @schema: the schema being built 8180 * @node: a subtree containing XML Schema informations 8181 * 8182 * Parses a XML Schema identity-contraint definition's 8183 * <selector> and <field> elements. 8184 * 8185 * Returns the parsed identity-constraint definition. 8186 */ 8187static xmlSchemaIDCSelectPtr 8188xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8189 xmlSchemaIDCPtr idc, 8190 xmlNodePtr node, 8191 int isField) 8192{ 8193 xmlSchemaIDCSelectPtr item; 8194 xmlNodePtr child = NULL; 8195 xmlAttrPtr attr; 8196 8197 /* 8198 * Check for illegal attributes. 8199 */ 8200 attr = node->properties; 8201 while (attr != NULL) { 8202 if (attr->ns == NULL) { 8203 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8204 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8205 xmlSchemaPIllegalAttrErr(ctxt, 8206 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8207 } 8208 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8209 xmlSchemaPIllegalAttrErr(ctxt, 8210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8211 } 8212 attr = attr->next; 8213 } 8214 /* 8215 * Create the item. 8216 */ 8217 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8218 if (item == NULL) { 8219 xmlSchemaPErrMemory(ctxt, 8220 "allocating a 'selector' of an identity-constraint definition", 8221 NULL); 8222 return (NULL); 8223 } 8224 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8225 /* 8226 * Attribute "xpath" (mandatory). 8227 */ 8228 attr = xmlSchemaGetPropNode(node, "xpath"); 8229 if (attr == NULL) { 8230 xmlSchemaPMissingAttrErr(ctxt, 8231 XML_SCHEMAP_S4S_ATTR_MISSING, 8232 NULL, node, 8233 "name", NULL); 8234 } else { 8235 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8236 /* 8237 * URGENT TODO: "field"s have an other syntax than "selector"s. 8238 */ 8239 8240 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8241 isField) == -1) { 8242 xmlSchemaPErr(ctxt, 8243 (xmlNodePtr) attr, 8244 XML_SCHEMAP_INTERNAL, 8245 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8246 "validating the XPath expression of a IDC selector.\n", 8247 NULL, NULL); 8248 } 8249 8250 } 8251 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8252 /* 8253 * And now for the children... 8254 */ 8255 child = node->children; 8256 if (IS_SCHEMA(child, "annotation")) { 8257 /* 8258 * Add the annotation to the parent IDC. 8259 */ 8260 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8261 xmlSchemaParseAnnotation(ctxt, child, 1)); 8262 child = child->next; 8263 } 8264 if (child != NULL) { 8265 xmlSchemaPContentErr(ctxt, 8266 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8267 NULL, node, child, 8268 NULL, "(annotation?)"); 8269 } 8270 8271 return (item); 8272} 8273 8274/** 8275 * xmlSchemaParseIDC: 8276 * @ctxt: a schema validation context 8277 * @schema: the schema being built 8278 * @node: a subtree containing XML Schema informations 8279 * 8280 * Parses a XML Schema identity-contraint definition. 8281 * 8282 * Returns the parsed identity-constraint definition. 8283 */ 8284static xmlSchemaIDCPtr 8285xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8286 xmlSchemaPtr schema, 8287 xmlNodePtr node, 8288 xmlSchemaTypeType idcCategory, 8289 const xmlChar *targetNamespace) 8290{ 8291 xmlSchemaIDCPtr item = NULL; 8292 xmlNodePtr child = NULL; 8293 xmlAttrPtr attr; 8294 const xmlChar *name = NULL; 8295 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8296 8297 /* 8298 * Check for illegal attributes. 8299 */ 8300 attr = node->properties; 8301 while (attr != NULL) { 8302 if (attr->ns == NULL) { 8303 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8304 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8305 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8306 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8307 xmlSchemaPIllegalAttrErr(ctxt, 8308 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8309 } 8310 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8311 xmlSchemaPIllegalAttrErr(ctxt, 8312 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8313 } 8314 attr = attr->next; 8315 } 8316 /* 8317 * Attribute "name" (mandatory). 8318 */ 8319 attr = xmlSchemaGetPropNode(node, "name"); 8320 if (attr == NULL) { 8321 xmlSchemaPMissingAttrErr(ctxt, 8322 XML_SCHEMAP_S4S_ATTR_MISSING, 8323 NULL, node, 8324 "name", NULL); 8325 return (NULL); 8326 } else if (xmlSchemaPValAttrNode(ctxt, 8327 NULL, attr, 8328 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8329 return (NULL); 8330 } 8331 /* Create the component. */ 8332 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8333 idcCategory, node); 8334 if (item == NULL) 8335 return(NULL); 8336 8337 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8338 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8339 /* 8340 * Attribute "refer" (mandatory). 8341 */ 8342 attr = xmlSchemaGetPropNode(node, "refer"); 8343 if (attr == NULL) { 8344 xmlSchemaPMissingAttrErr(ctxt, 8345 XML_SCHEMAP_S4S_ATTR_MISSING, 8346 NULL, node, 8347 "refer", NULL); 8348 } else { 8349 /* 8350 * Create a reference item. 8351 */ 8352 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8353 NULL, NULL); 8354 if (item->ref == NULL) 8355 return (NULL); 8356 xmlSchemaPValAttrNodeQName(ctxt, schema, 8357 NULL, attr, 8358 &(item->ref->targetNamespace), 8359 &(item->ref->name)); 8360 xmlSchemaCheckReference(ctxt, schema, node, attr, 8361 item->ref->targetNamespace); 8362 } 8363 } 8364 /* 8365 * And now for the children... 8366 */ 8367 child = node->children; 8368 if (IS_SCHEMA(child, "annotation")) { 8369 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8370 child = child->next; 8371 } 8372 if (child == NULL) { 8373 xmlSchemaPContentErr(ctxt, 8374 XML_SCHEMAP_S4S_ELEM_MISSING, 8375 NULL, node, child, 8376 "A child element is missing", 8377 "(annotation?, (selector, field+))"); 8378 } 8379 /* 8380 * Child element <selector>. 8381 */ 8382 if (IS_SCHEMA(child, "selector")) { 8383 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8384 item, child, 0); 8385 child = child->next; 8386 /* 8387 * Child elements <field>. 8388 */ 8389 if (IS_SCHEMA(child, "field")) { 8390 do { 8391 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8392 item, child, 1); 8393 if (field != NULL) { 8394 field->index = item->nbFields; 8395 item->nbFields++; 8396 if (lastField != NULL) 8397 lastField->next = field; 8398 else 8399 item->fields = field; 8400 lastField = field; 8401 } 8402 child = child->next; 8403 } while (IS_SCHEMA(child, "field")); 8404 } else { 8405 xmlSchemaPContentErr(ctxt, 8406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8407 NULL, node, child, 8408 NULL, "(annotation?, (selector, field+))"); 8409 } 8410 } 8411 if (child != NULL) { 8412 xmlSchemaPContentErr(ctxt, 8413 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8414 NULL, node, child, 8415 NULL, "(annotation?, (selector, field+))"); 8416 } 8417 8418 return (item); 8419} 8420 8421/** 8422 * xmlSchemaParseElement: 8423 * @ctxt: a schema validation context 8424 * @schema: the schema being built 8425 * @node: a subtree containing XML Schema informations 8426 * @topLevel: indicates if this is global declaration 8427 * 8428 * Parses a XML schema element declaration. 8429 * *WARNING* this interface is highly subject to change 8430 * 8431 * Returns the element declaration or a particle; NULL in case 8432 * of an error or if the particle has minOccurs==maxOccurs==0. 8433 */ 8434static xmlSchemaBasicItemPtr 8435xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8436 xmlNodePtr node, int *isElemRef, int topLevel) 8437{ 8438 xmlSchemaElementPtr decl = NULL; 8439 xmlSchemaParticlePtr particle = NULL; 8440 xmlSchemaAnnotPtr annot = NULL; 8441 xmlNodePtr child = NULL; 8442 xmlAttrPtr attr, nameAttr; 8443 int min, max, isRef = 0; 8444 xmlChar *des = NULL; 8445 8446 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8447 /* TODO: Complete implementation of 3.3.6 */ 8448 8449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8450 return (NULL); 8451 8452 if (isElemRef != NULL) 8453 *isElemRef = 0; 8454 /* 8455 * If we get a "ref" attribute on a local <element> we will assume it's 8456 * a reference - even if there's a "name" attribute; this seems to be more 8457 * robust. 8458 */ 8459 nameAttr = xmlSchemaGetPropNode(node, "name"); 8460 attr = xmlSchemaGetPropNode(node, "ref"); 8461 if ((topLevel) || (attr == NULL)) { 8462 if (nameAttr == NULL) { 8463 xmlSchemaPMissingAttrErr(ctxt, 8464 XML_SCHEMAP_S4S_ATTR_MISSING, 8465 NULL, node, "name", NULL); 8466 return (NULL); 8467 } 8468 } else 8469 isRef = 1; 8470 8471 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8472 child = node->children; 8473 if (IS_SCHEMA(child, "annotation")) { 8474 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8475 child = child->next; 8476 } 8477 /* 8478 * Skip particle part if a global declaration. 8479 */ 8480 if (topLevel) 8481 goto declaration_part; 8482 /* 8483 * The particle part ================================================== 8484 */ 8485 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8486 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8487 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8488 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8489 if (particle == NULL) 8490 goto return_null; 8491 8492 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8493 8494 if (isRef) { 8495 const xmlChar *refNs = NULL, *ref = NULL; 8496 xmlSchemaQNameRefPtr refer = NULL; 8497 /* 8498 * The reference part ============================================= 8499 */ 8500 if (isElemRef != NULL) 8501 *isElemRef = 1; 8502 8503 xmlSchemaPValAttrNodeQName(ctxt, schema, 8504 NULL, attr, &refNs, &ref); 8505 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8506 /* 8507 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8508 */ 8509 if (nameAttr != NULL) { 8510 xmlSchemaPMutualExclAttrErr(ctxt, 8511 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8512 } 8513 /* 8514 * Check for illegal attributes. 8515 */ 8516 attr = node->properties; 8517 while (attr != NULL) { 8518 if (attr->ns == NULL) { 8519 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8520 xmlStrEqual(attr->name, BAD_CAST "name") || 8521 xmlStrEqual(attr->name, BAD_CAST "id") || 8522 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8523 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8524 { 8525 attr = attr->next; 8526 continue; 8527 } else { 8528 /* SPEC (3.3.3 : 2.2) */ 8529 xmlSchemaPCustomAttrErr(ctxt, 8530 XML_SCHEMAP_SRC_ELEMENT_2_2, 8531 NULL, NULL, attr, 8532 "Only the attributes 'minOccurs', 'maxOccurs' and " 8533 "'id' are allowed in addition to 'ref'"); 8534 break; 8535 } 8536 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8537 xmlSchemaPIllegalAttrErr(ctxt, 8538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8539 } 8540 attr = attr->next; 8541 } 8542 /* 8543 * No children except <annotation> expected. 8544 */ 8545 if (child != NULL) { 8546 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8547 NULL, node, child, NULL, "(annotation?)"); 8548 } 8549 if ((min == 0) && (max == 0)) 8550 goto return_null; 8551 /* 8552 * Create the reference item and attach it to the particle. 8553 */ 8554 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8555 ref, refNs); 8556 if (refer == NULL) 8557 goto return_null; 8558 particle->children = (xmlSchemaTreeItemPtr) refer; 8559 particle->annot = annot; 8560 /* 8561 * Add the particle to pending components, since the reference 8562 * need to be resolved. 8563 */ 8564 WXS_ADD_PENDING(ctxt, particle); 8565 return ((xmlSchemaBasicItemPtr) particle); 8566 } 8567 /* 8568 * The declaration part =============================================== 8569 */ 8570declaration_part: 8571 { 8572 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8573 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8574 8575 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8576 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8577 goto return_null; 8578 /* 8579 * Evaluate the target namespace. 8580 */ 8581 if (topLevel) { 8582 ns = ctxt->targetNamespace; 8583 } else { 8584 attr = xmlSchemaGetPropNode(node, "form"); 8585 if (attr != NULL) { 8586 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8587 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8588 ns = ctxt->targetNamespace; 8589 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8590 xmlSchemaPSimpleTypeErr(ctxt, 8591 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8592 NULL, (xmlNodePtr) attr, 8593 NULL, "(qualified | unqualified)", 8594 attrValue, NULL, NULL, NULL); 8595 } 8596 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8597 ns = ctxt->targetNamespace; 8598 } 8599 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8600 if (decl == NULL) { 8601 goto return_null; 8602 } 8603 /* 8604 * Check for illegal attributes. 8605 */ 8606 attr = node->properties; 8607 while (attr != NULL) { 8608 if (attr->ns == NULL) { 8609 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8610 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8611 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8612 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8613 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8614 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8615 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8616 { 8617 if (topLevel == 0) { 8618 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8619 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8620 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8621 { 8622 xmlSchemaPIllegalAttrErr(ctxt, 8623 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8624 } 8625 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8626 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8627 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8628 8629 xmlSchemaPIllegalAttrErr(ctxt, 8630 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8631 } 8632 } 8633 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8634 8635 xmlSchemaPIllegalAttrErr(ctxt, 8636 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8637 } 8638 attr = attr->next; 8639 } 8640 /* 8641 * Extract/validate attributes. 8642 */ 8643 if (topLevel) { 8644 /* 8645 * Process top attributes of global element declarations here. 8646 */ 8647 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8648 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8649 xmlSchemaPValAttrQName(ctxt, schema, 8650 NULL, node, "substitutionGroup", 8651 &(decl->substGroupNs), &(decl->substGroup)); 8652 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8653 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8654 /* 8655 * Attribute "final". 8656 */ 8657 attr = xmlSchemaGetPropNode(node, "final"); 8658 if (attr == NULL) { 8659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8660 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8661 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8662 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8663 } else { 8664 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8665 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8666 -1, 8667 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8668 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8669 xmlSchemaPSimpleTypeErr(ctxt, 8670 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8671 NULL, (xmlNodePtr) attr, 8672 NULL, "(#all | List of (extension | restriction))", 8673 attrValue, NULL, NULL, NULL); 8674 } 8675 } 8676 } 8677 /* 8678 * Attribute "block". 8679 */ 8680 attr = xmlSchemaGetPropNode(node, "block"); 8681 if (attr == NULL) { 8682 /* 8683 * Apply default "block" values. 8684 */ 8685 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8686 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8687 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8688 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8689 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8690 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8691 } else { 8692 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8693 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8694 -1, 8695 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8696 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8697 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8698 xmlSchemaPSimpleTypeErr(ctxt, 8699 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8700 NULL, (xmlNodePtr) attr, 8701 NULL, "(#all | List of (extension | " 8702 "restriction | substitution))", attrValue, 8703 NULL, NULL, NULL); 8704 } 8705 } 8706 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8707 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8708 8709 attr = xmlSchemaGetPropNode(node, "type"); 8710 if (attr != NULL) { 8711 xmlSchemaPValAttrNodeQName(ctxt, schema, 8712 NULL, attr, 8713 &(decl->namedTypeNs), &(decl->namedType)); 8714 xmlSchemaCheckReference(ctxt, schema, node, 8715 attr, decl->namedTypeNs); 8716 } 8717 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8718 attr = xmlSchemaGetPropNode(node, "fixed"); 8719 if (attr != NULL) { 8720 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8721 if (decl->value != NULL) { 8722 /* 8723 * 3.3.3 : 1 8724 * default and fixed must not both be present. 8725 */ 8726 xmlSchemaPMutualExclAttrErr(ctxt, 8727 XML_SCHEMAP_SRC_ELEMENT_1, 8728 NULL, attr, "default", "fixed"); 8729 } else { 8730 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8731 decl->value = fixed; 8732 } 8733 } 8734 /* 8735 * And now for the children... 8736 */ 8737 if (IS_SCHEMA(child, "complexType")) { 8738 /* 8739 * 3.3.3 : 3 8740 * "type" and either <simpleType> or <complexType> are mutually 8741 * exclusive 8742 */ 8743 if (decl->namedType != NULL) { 8744 xmlSchemaPContentErr(ctxt, 8745 XML_SCHEMAP_SRC_ELEMENT_3, 8746 NULL, node, child, 8747 "The attribute 'type' and the <complexType> child are " 8748 "mutually exclusive", NULL); 8749 } else 8750 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8751 child = child->next; 8752 } else if (IS_SCHEMA(child, "simpleType")) { 8753 /* 8754 * 3.3.3 : 3 8755 * "type" and either <simpleType> or <complexType> are 8756 * mutually exclusive 8757 */ 8758 if (decl->namedType != NULL) { 8759 xmlSchemaPContentErr(ctxt, 8760 XML_SCHEMAP_SRC_ELEMENT_3, 8761 NULL, node, child, 8762 "The attribute 'type' and the <simpleType> child are " 8763 "mutually exclusive", NULL); 8764 } else 8765 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8766 child = child->next; 8767 } 8768 while ((IS_SCHEMA(child, "unique")) || 8769 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8770 if (IS_SCHEMA(child, "unique")) { 8771 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8772 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8773 } else if (IS_SCHEMA(child, "key")) { 8774 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8775 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8776 } else if (IS_SCHEMA(child, "keyref")) { 8777 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8778 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8779 } 8780 if (lastIDC != NULL) 8781 lastIDC->next = curIDC; 8782 else 8783 decl->idcs = (void *) curIDC; 8784 lastIDC = curIDC; 8785 child = child->next; 8786 } 8787 if (child != NULL) { 8788 xmlSchemaPContentErr(ctxt, 8789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8790 NULL, node, child, 8791 NULL, "(annotation?, ((simpleType | complexType)?, " 8792 "(unique | key | keyref)*))"); 8793 } 8794 decl->annot = annot; 8795 } 8796 /* 8797 * NOTE: Element Declaration Representation OK 4. will be checked at a 8798 * different layer. 8799 */ 8800 FREE_AND_NULL(des) 8801 if (topLevel) 8802 return ((xmlSchemaBasicItemPtr) decl); 8803 else { 8804 particle->children = (xmlSchemaTreeItemPtr) decl; 8805 return ((xmlSchemaBasicItemPtr) particle); 8806 } 8807 8808return_null: 8809 FREE_AND_NULL(des); 8810 if (annot != NULL) { 8811 if (particle != NULL) 8812 particle->annot = NULL; 8813 if (decl != NULL) 8814 decl->annot = NULL; 8815 xmlSchemaFreeAnnot(annot); 8816 } 8817 return (NULL); 8818} 8819 8820/** 8821 * xmlSchemaParseUnion: 8822 * @ctxt: a schema validation context 8823 * @schema: the schema being built 8824 * @node: a subtree containing XML Schema informations 8825 * 8826 * parse a XML schema Union definition 8827 * *WARNING* this interface is highly subject to change 8828 * 8829 * Returns -1 in case of internal error, 0 in case of success and a positive 8830 * error code otherwise. 8831 */ 8832static int 8833xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8834 xmlNodePtr node) 8835{ 8836 xmlSchemaTypePtr type; 8837 xmlNodePtr child = NULL; 8838 xmlAttrPtr attr; 8839 const xmlChar *cur = NULL; 8840 8841 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8842 return (-1); 8843 /* Not a component, don't create it. */ 8844 type = ctxt->ctxtType; 8845 /* 8846 * Mark the simple type as being of variety "union". 8847 */ 8848 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8849 /* 8850 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8851 * then the �simple ur-type definition�." 8852 */ 8853 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8854 /* 8855 * Check for illegal attributes. 8856 */ 8857 attr = node->properties; 8858 while (attr != NULL) { 8859 if (attr->ns == NULL) { 8860 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8861 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8862 xmlSchemaPIllegalAttrErr(ctxt, 8863 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8864 } 8865 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8866 xmlSchemaPIllegalAttrErr(ctxt, 8867 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8868 } 8869 attr = attr->next; 8870 } 8871 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8872 /* 8873 * Attribute "memberTypes". This is a list of QNames. 8874 * TODO: Check the value to contain anything. 8875 */ 8876 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8877 if (attr != NULL) { 8878 const xmlChar *end; 8879 xmlChar *tmp; 8880 const xmlChar *localName, *nsName; 8881 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8882 xmlSchemaQNameRefPtr ref; 8883 8884 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8885 type->base = cur; 8886 do { 8887 while (IS_BLANK_CH(*cur)) 8888 cur++; 8889 end = cur; 8890 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8891 end++; 8892 if (end == cur) 8893 break; 8894 tmp = xmlStrndup(cur, end - cur); 8895 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8896 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8897 /* 8898 * Create the member type link. 8899 */ 8900 link = (xmlSchemaTypeLinkPtr) 8901 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8902 if (link == NULL) { 8903 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8904 "allocating a type link", NULL); 8905 return (-1); 8906 } 8907 link->type = NULL; 8908 link->next = NULL; 8909 if (lastLink == NULL) 8910 type->memberTypes = link; 8911 else 8912 lastLink->next = link; 8913 lastLink = link; 8914 /* 8915 * Create a reference item. 8916 */ 8917 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8918 localName, nsName); 8919 if (ref == NULL) { 8920 FREE_AND_NULL(tmp) 8921 return (-1); 8922 } 8923 /* 8924 * Assign the reference to the link, it will be resolved 8925 * later during fixup of the union simple type. 8926 */ 8927 link->type = (xmlSchemaTypePtr) ref; 8928 } 8929 FREE_AND_NULL(tmp) 8930 cur = end; 8931 } while (*cur != 0); 8932 8933 } 8934 /* 8935 * And now for the children... 8936 */ 8937 child = node->children; 8938 if (IS_SCHEMA(child, "annotation")) { 8939 /* 8940 * Add the annotation to the simple type ancestor. 8941 */ 8942 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8943 xmlSchemaParseAnnotation(ctxt, child, 1)); 8944 child = child->next; 8945 } 8946 if (IS_SCHEMA(child, "simpleType")) { 8947 xmlSchemaTypePtr subtype, last = NULL; 8948 8949 /* 8950 * Anchor the member types in the "subtypes" field of the 8951 * simple type. 8952 */ 8953 while (IS_SCHEMA(child, "simpleType")) { 8954 subtype = (xmlSchemaTypePtr) 8955 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8956 if (subtype != NULL) { 8957 if (last == NULL) { 8958 type->subtypes = subtype; 8959 last = subtype; 8960 } else { 8961 last->next = subtype; 8962 last = subtype; 8963 } 8964 last->next = NULL; 8965 } 8966 child = child->next; 8967 } 8968 } 8969 if (child != NULL) { 8970 xmlSchemaPContentErr(ctxt, 8971 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8972 NULL, node, child, NULL, "(annotation?, simpleType*)"); 8973 } 8974 if ((attr == NULL) && (type->subtypes == NULL)) { 8975 /* 8976 * src-union-memberTypes-or-simpleTypes 8977 * Either the memberTypes [attribute] of the <union> element must 8978 * be non-empty or there must be at least one simpleType [child]. 8979 */ 8980 xmlSchemaPCustomErr(ctxt, 8981 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 8982 NULL, node, 8983 "Either the attribute 'memberTypes' or " 8984 "at least one <simpleType> child must be present", NULL); 8985 } 8986 return (0); 8987} 8988 8989/** 8990 * xmlSchemaParseList: 8991 * @ctxt: a schema validation context 8992 * @schema: the schema being built 8993 * @node: a subtree containing XML Schema informations 8994 * 8995 * parse a XML schema List definition 8996 * *WARNING* this interface is highly subject to change 8997 * 8998 * Returns -1 in case of error, 0 if the declaration is improper and 8999 * 1 in case of success. 9000 */ 9001static xmlSchemaTypePtr 9002xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9003 xmlNodePtr node) 9004{ 9005 xmlSchemaTypePtr type; 9006 xmlNodePtr child = NULL; 9007 xmlAttrPtr attr; 9008 9009 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9010 return (NULL); 9011 /* Not a component, don't create it. */ 9012 type = ctxt->ctxtType; 9013 /* 9014 * Mark the type as being of variety "list". 9015 */ 9016 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9017 /* 9018 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9019 * then the �simple ur-type definition�." 9020 */ 9021 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9022 /* 9023 * Check for illegal attributes. 9024 */ 9025 attr = node->properties; 9026 while (attr != NULL) { 9027 if (attr->ns == NULL) { 9028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9029 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9030 xmlSchemaPIllegalAttrErr(ctxt, 9031 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9032 } 9033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9034 xmlSchemaPIllegalAttrErr(ctxt, 9035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9036 } 9037 attr = attr->next; 9038 } 9039 9040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9041 9042 /* 9043 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9044 * fields for holding the reference to the itemType. 9045 * 9046 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9047 * the "ref" fields. 9048 */ 9049 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9050 node, "itemType", &(type->baseNs), &(type->base)); 9051 /* 9052 * And now for the children... 9053 */ 9054 child = node->children; 9055 if (IS_SCHEMA(child, "annotation")) { 9056 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9057 xmlSchemaParseAnnotation(ctxt, child, 1)); 9058 child = child->next; 9059 } 9060 if (IS_SCHEMA(child, "simpleType")) { 9061 /* 9062 * src-list-itemType-or-simpleType 9063 * Either the itemType [attribute] or the <simpleType> [child] of 9064 * the <list> element must be present, but not both. 9065 */ 9066 if (type->base != NULL) { 9067 xmlSchemaPCustomErr(ctxt, 9068 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9069 NULL, node, 9070 "The attribute 'itemType' and the <simpleType> child " 9071 "are mutually exclusive", NULL); 9072 } else { 9073 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9074 } 9075 child = child->next; 9076 } else if (type->base == NULL) { 9077 xmlSchemaPCustomErr(ctxt, 9078 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9079 NULL, node, 9080 "Either the attribute 'itemType' or the <simpleType> child " 9081 "must be present", NULL); 9082 } 9083 if (child != NULL) { 9084 xmlSchemaPContentErr(ctxt, 9085 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9086 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9087 } 9088 if ((type->base == NULL) && 9089 (type->subtypes == NULL) && 9090 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9091 xmlSchemaPCustomErr(ctxt, 9092 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9093 NULL, node, 9094 "Either the attribute 'itemType' or the <simpleType> child " 9095 "must be present", NULL); 9096 } 9097 return (NULL); 9098} 9099 9100/** 9101 * xmlSchemaParseSimpleType: 9102 * @ctxt: a schema validation context 9103 * @schema: the schema being built 9104 * @node: a subtree containing XML Schema informations 9105 * 9106 * parse a XML schema Simple Type definition 9107 * *WARNING* this interface is highly subject to change 9108 * 9109 * Returns -1 in case of error, 0 if the declaration is improper and 9110 * 1 in case of success. 9111 */ 9112static xmlSchemaTypePtr 9113xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9114 xmlNodePtr node, int topLevel) 9115{ 9116 xmlSchemaTypePtr type, oldCtxtType; 9117 xmlNodePtr child = NULL; 9118 const xmlChar *attrValue = NULL; 9119 xmlAttrPtr attr; 9120 int hasRestriction = 0; 9121 9122 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9123 return (NULL); 9124 9125 if (topLevel) { 9126 attr = xmlSchemaGetPropNode(node, "name"); 9127 if (attr == NULL) { 9128 xmlSchemaPMissingAttrErr(ctxt, 9129 XML_SCHEMAP_S4S_ATTR_MISSING, 9130 NULL, node, 9131 "name", NULL); 9132 return (NULL); 9133 } else { 9134 if (xmlSchemaPValAttrNode(ctxt, 9135 NULL, attr, 9136 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9137 return (NULL); 9138 /* 9139 * Skip built-in types. 9140 */ 9141 if (ctxt->isS4S) { 9142 xmlSchemaTypePtr biType; 9143 9144 if (ctxt->isRedefine) { 9145 /* 9146 * REDEFINE: Disallow redefinition of built-in-types. 9147 * TODO: It seems that the spec does not say anything 9148 * about this case. 9149 */ 9150 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9151 NULL, node, 9152 "Redefinition of built-in simple types is not " 9153 "supported", NULL); 9154 return(NULL); 9155 } 9156 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9157 if (biType != NULL) 9158 return (biType); 9159 } 9160 } 9161 } 9162 /* 9163 * TargetNamespace: 9164 * SPEC "The �actual value� of the targetNamespace [attribute] 9165 * of the <schema> ancestor element information item if present, 9166 * otherwise �absent�. 9167 */ 9168 if (topLevel == 0) { 9169#ifdef ENABLE_NAMED_LOCALS 9170 char buf[40]; 9171#endif 9172 /* 9173 * Parse as local simple type definition. 9174 */ 9175#ifdef ENABLE_NAMED_LOCALS 9176 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9177 type = xmlSchemaAddType(ctxt, schema, 9178 XML_SCHEMA_TYPE_SIMPLE, 9179 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9180 ctxt->targetNamespace, node, 0); 9181#else 9182 type = xmlSchemaAddType(ctxt, schema, 9183 XML_SCHEMA_TYPE_SIMPLE, 9184 NULL, ctxt->targetNamespace, node, 0); 9185#endif 9186 if (type == NULL) 9187 return (NULL); 9188 type->type = XML_SCHEMA_TYPE_SIMPLE; 9189 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9190 /* 9191 * Check for illegal attributes. 9192 */ 9193 attr = node->properties; 9194 while (attr != NULL) { 9195 if (attr->ns == NULL) { 9196 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9197 xmlSchemaPIllegalAttrErr(ctxt, 9198 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9199 } 9200 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9201 xmlSchemaPIllegalAttrErr(ctxt, 9202 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9203 } 9204 attr = attr->next; 9205 } 9206 } else { 9207 /* 9208 * Parse as global simple type definition. 9209 * 9210 * Note that attrValue is the value of the attribute "name" here. 9211 */ 9212 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9213 attrValue, ctxt->targetNamespace, node, 1); 9214 if (type == NULL) 9215 return (NULL); 9216 type->type = XML_SCHEMA_TYPE_SIMPLE; 9217 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9218 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9219 /* 9220 * Check for illegal attributes. 9221 */ 9222 attr = node->properties; 9223 while (attr != NULL) { 9224 if (attr->ns == NULL) { 9225 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9226 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9227 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9228 xmlSchemaPIllegalAttrErr(ctxt, 9229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9230 } 9231 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9232 xmlSchemaPIllegalAttrErr(ctxt, 9233 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9234 } 9235 attr = attr->next; 9236 } 9237 /* 9238 * Attribute "final". 9239 */ 9240 attr = xmlSchemaGetPropNode(node, "final"); 9241 if (attr == NULL) { 9242 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9243 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9244 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9245 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9247 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9248 } else { 9249 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9250 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9251 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9252 XML_SCHEMAS_TYPE_FINAL_LIST, 9253 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9254 9255 xmlSchemaPSimpleTypeErr(ctxt, 9256 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9257 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9258 NULL, "(#all | List of (list | union | restriction)", 9259 attrValue, NULL, NULL, NULL); 9260 } 9261 } 9262 } 9263 type->targetNamespace = ctxt->targetNamespace; 9264 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9265 /* 9266 * And now for the children... 9267 */ 9268 oldCtxtType = ctxt->ctxtType; 9269 9270 ctxt->ctxtType = type; 9271 9272 child = node->children; 9273 if (IS_SCHEMA(child, "annotation")) { 9274 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9275 child = child->next; 9276 } 9277 if (child == NULL) { 9278 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9279 NULL, node, child, NULL, 9280 "(annotation?, (restriction | list | union))"); 9281 } else if (IS_SCHEMA(child, "restriction")) { 9282 xmlSchemaParseRestriction(ctxt, schema, child, 9283 XML_SCHEMA_TYPE_SIMPLE); 9284 hasRestriction = 1; 9285 child = child->next; 9286 } else if (IS_SCHEMA(child, "list")) { 9287 xmlSchemaParseList(ctxt, schema, child); 9288 child = child->next; 9289 } else if (IS_SCHEMA(child, "union")) { 9290 xmlSchemaParseUnion(ctxt, schema, child); 9291 child = child->next; 9292 } 9293 if (child != NULL) { 9294 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9295 NULL, node, child, NULL, 9296 "(annotation?, (restriction | list | union))"); 9297 } 9298 /* 9299 * REDEFINE: SPEC src-redefine (5) 9300 * "Within the [children], each <simpleType> must have a 9301 * <restriction> among its [children] ... the �actual value� of whose 9302 * base [attribute] must be the same as the �actual value� of its own 9303 * name attribute plus target namespace;" 9304 */ 9305 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9306 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9307 NULL, node, "This is a redefinition, thus the " 9308 "<simpleType> must have a <restriction> child", NULL); 9309 } 9310 9311 ctxt->ctxtType = oldCtxtType; 9312 return (type); 9313} 9314 9315/** 9316 * xmlSchemaParseModelGroupDefRef: 9317 * @ctxt: the parser context 9318 * @schema: the schema being built 9319 * @node: the node 9320 * 9321 * Parses a reference to a model group definition. 9322 * 9323 * We will return a particle component with a qname-component or 9324 * NULL in case of an error. 9325 */ 9326static xmlSchemaTreeItemPtr 9327xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9328 xmlSchemaPtr schema, 9329 xmlNodePtr node) 9330{ 9331 xmlSchemaParticlePtr item; 9332 xmlNodePtr child = NULL; 9333 xmlAttrPtr attr; 9334 const xmlChar *ref = NULL, *refNs = NULL; 9335 int min, max; 9336 9337 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9338 return (NULL); 9339 9340 attr = xmlSchemaGetPropNode(node, "ref"); 9341 if (attr == NULL) { 9342 xmlSchemaPMissingAttrErr(ctxt, 9343 XML_SCHEMAP_S4S_ATTR_MISSING, 9344 NULL, node, "ref", NULL); 9345 return (NULL); 9346 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9347 attr, &refNs, &ref) != 0) { 9348 return (NULL); 9349 } 9350 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9351 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9352 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9353 "(xs:nonNegativeInteger | unbounded)"); 9354 /* 9355 * Check for illegal attributes. 9356 */ 9357 attr = node->properties; 9358 while (attr != NULL) { 9359 if (attr->ns == NULL) { 9360 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9361 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9362 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9363 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9364 xmlSchemaPIllegalAttrErr(ctxt, 9365 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9366 } 9367 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9368 xmlSchemaPIllegalAttrErr(ctxt, 9369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9370 } 9371 attr = attr->next; 9372 } 9373 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9374 item = xmlSchemaAddParticle(ctxt, node, min, max); 9375 if (item == NULL) 9376 return (NULL); 9377 /* 9378 * Create a qname-reference and set as the term; it will be substituted 9379 * for the model group after the reference has been resolved. 9380 */ 9381 item->children = (xmlSchemaTreeItemPtr) 9382 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9383 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9384 /* 9385 * And now for the children... 9386 */ 9387 child = node->children; 9388 /* TODO: Is annotation even allowed for a model group reference? */ 9389 if (IS_SCHEMA(child, "annotation")) { 9390 /* 9391 * TODO: What to do exactly with the annotation? 9392 */ 9393 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9394 child = child->next; 9395 } 9396 if (child != NULL) { 9397 xmlSchemaPContentErr(ctxt, 9398 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9399 NULL, node, child, NULL, 9400 "(annotation?)"); 9401 } 9402 /* 9403 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9404 */ 9405 if ((min == 0) && (max == 0)) 9406 return (NULL); 9407 9408 return ((xmlSchemaTreeItemPtr) item); 9409} 9410 9411/** 9412 * xmlSchemaParseModelGroupDefinition: 9413 * @ctxt: a schema validation context 9414 * @schema: the schema being built 9415 * @node: a subtree containing XML Schema informations 9416 * 9417 * Parses a XML schema model group definition. 9418 * 9419 * Note that the contraint src-redefine (6.2) can't be applied until 9420 * references have been resolved. So we will do this at the 9421 * component fixup level. 9422 * 9423 * *WARNING* this interface is highly subject to change 9424 * 9425 * Returns -1 in case of error, 0 if the declaration is improper and 9426 * 1 in case of success. 9427 */ 9428static xmlSchemaModelGroupDefPtr 9429xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9430 xmlSchemaPtr schema, 9431 xmlNodePtr node) 9432{ 9433 xmlSchemaModelGroupDefPtr item; 9434 xmlNodePtr child = NULL; 9435 xmlAttrPtr attr; 9436 const xmlChar *name; 9437 9438 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9439 return (NULL); 9440 9441 attr = xmlSchemaGetPropNode(node, "name"); 9442 if (attr == NULL) { 9443 xmlSchemaPMissingAttrErr(ctxt, 9444 XML_SCHEMAP_S4S_ATTR_MISSING, 9445 NULL, node, 9446 "name", NULL); 9447 return (NULL); 9448 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9449 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9450 return (NULL); 9451 } 9452 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9453 ctxt->targetNamespace, node); 9454 if (item == NULL) 9455 return (NULL); 9456 /* 9457 * Check for illegal attributes. 9458 */ 9459 attr = node->properties; 9460 while (attr != NULL) { 9461 if (attr->ns == NULL) { 9462 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9463 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9464 xmlSchemaPIllegalAttrErr(ctxt, 9465 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9466 } 9467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9468 xmlSchemaPIllegalAttrErr(ctxt, 9469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9470 } 9471 attr = attr->next; 9472 } 9473 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9474 /* 9475 * And now for the children... 9476 */ 9477 child = node->children; 9478 if (IS_SCHEMA(child, "annotation")) { 9479 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9480 child = child->next; 9481 } 9482 if (IS_SCHEMA(child, "all")) { 9483 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9484 XML_SCHEMA_TYPE_ALL, 0); 9485 child = child->next; 9486 } else if (IS_SCHEMA(child, "choice")) { 9487 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9488 XML_SCHEMA_TYPE_CHOICE, 0); 9489 child = child->next; 9490 } else if (IS_SCHEMA(child, "sequence")) { 9491 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9492 XML_SCHEMA_TYPE_SEQUENCE, 0); 9493 child = child->next; 9494 } 9495 9496 9497 9498 if (child != NULL) { 9499 xmlSchemaPContentErr(ctxt, 9500 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9501 NULL, node, child, NULL, 9502 "(annotation?, (all | choice | sequence)?)"); 9503 } 9504 return (item); 9505} 9506 9507/** 9508 * xmlSchemaCleanupDoc: 9509 * @ctxt: a schema validation context 9510 * @node: the root of the document. 9511 * 9512 * removes unwanted nodes in a schemas document tree 9513 */ 9514static void 9515xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9516{ 9517 xmlNodePtr delete, cur; 9518 9519 if ((ctxt == NULL) || (root == NULL)) return; 9520 9521 /* 9522 * Remove all the blank text nodes 9523 */ 9524 delete = NULL; 9525 cur = root; 9526 while (cur != NULL) { 9527 if (delete != NULL) { 9528 xmlUnlinkNode(delete); 9529 xmlFreeNode(delete); 9530 delete = NULL; 9531 } 9532 if (cur->type == XML_TEXT_NODE) { 9533 if (IS_BLANK_NODE(cur)) { 9534 if (xmlNodeGetSpacePreserve(cur) != 1) { 9535 delete = cur; 9536 } 9537 } 9538 } else if ((cur->type != XML_ELEMENT_NODE) && 9539 (cur->type != XML_CDATA_SECTION_NODE)) { 9540 delete = cur; 9541 goto skip_children; 9542 } 9543 9544 /* 9545 * Skip to next node 9546 */ 9547 if (cur->children != NULL) { 9548 if ((cur->children->type != XML_ENTITY_DECL) && 9549 (cur->children->type != XML_ENTITY_REF_NODE) && 9550 (cur->children->type != XML_ENTITY_NODE)) { 9551 cur = cur->children; 9552 continue; 9553 } 9554 } 9555 skip_children: 9556 if (cur->next != NULL) { 9557 cur = cur->next; 9558 continue; 9559 } 9560 9561 do { 9562 cur = cur->parent; 9563 if (cur == NULL) 9564 break; 9565 if (cur == root) { 9566 cur = NULL; 9567 break; 9568 } 9569 if (cur->next != NULL) { 9570 cur = cur->next; 9571 break; 9572 } 9573 } while (cur != NULL); 9574 } 9575 if (delete != NULL) { 9576 xmlUnlinkNode(delete); 9577 xmlFreeNode(delete); 9578 delete = NULL; 9579 } 9580} 9581 9582 9583static void 9584xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9585{ 9586 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9587 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9588 9589 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9590 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9591 9592 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9593 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9594 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9595 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9596 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9597 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9598 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9599 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9600 9601 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9602 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9603 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9604 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9605 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9606 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9607} 9608 9609static int 9610xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9611 xmlSchemaPtr schema, 9612 xmlNodePtr node) 9613{ 9614 xmlAttrPtr attr; 9615 const xmlChar *val; 9616 int res = 0, oldErrs = ctxt->nberrors; 9617 9618 /* 9619 * Those flags should be moved to the parser context flags, 9620 * since they are not visible at the component level. I.e. 9621 * they are used if processing schema *documents* only. 9622 */ 9623 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9624 HFAILURE; 9625 9626 /* 9627 * Since the version is of type xs:token, we won't bother to 9628 * check it. 9629 */ 9630 /* REMOVED: 9631 attr = xmlSchemaGetPropNode(node, "version"); 9632 if (attr != NULL) { 9633 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9634 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9635 HFAILURE; 9636 } 9637 */ 9638 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9639 if (attr != NULL) { 9640 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9641 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9642 HFAILURE; 9643 if (res != 0) { 9644 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9645 goto exit; 9646 } 9647 } 9648 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9649 if (attr != NULL) { 9650 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9651 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9652 XML_SCHEMAS_QUALIF_ELEM); 9653 HFAILURE; 9654 if (res != 0) { 9655 xmlSchemaPSimpleTypeErr(ctxt, 9656 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9657 NULL, (xmlNodePtr) attr, NULL, 9658 "(qualified | unqualified)", val, NULL, NULL, NULL); 9659 } 9660 } 9661 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9662 if (attr != NULL) { 9663 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9664 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9665 XML_SCHEMAS_QUALIF_ATTR); 9666 HFAILURE; 9667 if (res != 0) { 9668 xmlSchemaPSimpleTypeErr(ctxt, 9669 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9670 NULL, (xmlNodePtr) attr, NULL, 9671 "(qualified | unqualified)", val, NULL, NULL, NULL); 9672 } 9673 } 9674 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9675 if (attr != NULL) { 9676 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9677 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9678 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9679 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9680 -1, 9681 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9682 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9683 HFAILURE; 9684 if (res != 0) { 9685 xmlSchemaPSimpleTypeErr(ctxt, 9686 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9687 NULL, (xmlNodePtr) attr, NULL, 9688 "(#all | List of (extension | restriction | list | union))", 9689 val, NULL, NULL, NULL); 9690 } 9691 } 9692 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9693 if (attr != NULL) { 9694 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9695 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9696 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9697 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9698 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9699 HFAILURE; 9700 if (res != 0) { 9701 xmlSchemaPSimpleTypeErr(ctxt, 9702 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9703 NULL, (xmlNodePtr) attr, NULL, 9704 "(#all | List of (extension | restriction | substitution))", 9705 val, NULL, NULL, NULL); 9706 } 9707 } 9708 9709exit: 9710 if (oldErrs != ctxt->nberrors) 9711 res = ctxt->err; 9712 return(res); 9713exit_failure: 9714 return(-1); 9715} 9716 9717/** 9718 * xmlSchemaParseSchemaTopLevel: 9719 * @ctxt: a schema validation context 9720 * @schema: the schemas 9721 * @nodes: the list of top level nodes 9722 * 9723 * Returns the internal XML Schema structure built from the resource or 9724 * NULL in case of error 9725 */ 9726static int 9727xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9728 xmlSchemaPtr schema, xmlNodePtr nodes) 9729{ 9730 xmlNodePtr child; 9731 xmlSchemaAnnotPtr annot; 9732 int res = 0, oldErrs, tmpOldErrs; 9733 9734 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9735 return(-1); 9736 9737 oldErrs = ctxt->nberrors; 9738 child = nodes; 9739 while ((IS_SCHEMA(child, "include")) || 9740 (IS_SCHEMA(child, "import")) || 9741 (IS_SCHEMA(child, "redefine")) || 9742 (IS_SCHEMA(child, "annotation"))) { 9743 if (IS_SCHEMA(child, "annotation")) { 9744 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9745 if (schema->annot == NULL) 9746 schema->annot = annot; 9747 else 9748 xmlSchemaFreeAnnot(annot); 9749 } else if (IS_SCHEMA(child, "import")) { 9750 tmpOldErrs = ctxt->nberrors; 9751 res = xmlSchemaParseImport(ctxt, schema, child); 9752 HFAILURE; 9753 HSTOP(ctxt); 9754 if (tmpOldErrs != ctxt->nberrors) 9755 goto exit; 9756 } else if (IS_SCHEMA(child, "include")) { 9757 tmpOldErrs = ctxt->nberrors; 9758 res = xmlSchemaParseInclude(ctxt, schema, child); 9759 HFAILURE; 9760 HSTOP(ctxt); 9761 if (tmpOldErrs != ctxt->nberrors) 9762 goto exit; 9763 } else if (IS_SCHEMA(child, "redefine")) { 9764 tmpOldErrs = ctxt->nberrors; 9765 res = xmlSchemaParseRedefine(ctxt, schema, child); 9766 HFAILURE; 9767 HSTOP(ctxt); 9768 if (tmpOldErrs != ctxt->nberrors) 9769 goto exit; 9770 } 9771 child = child->next; 9772 } 9773 /* 9774 * URGENT TODO: Change the functions to return int results. 9775 * We need especially to catch internal errors. 9776 */ 9777 while (child != NULL) { 9778 if (IS_SCHEMA(child, "complexType")) { 9779 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9780 child = child->next; 9781 } else if (IS_SCHEMA(child, "simpleType")) { 9782 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9783 child = child->next; 9784 } else if (IS_SCHEMA(child, "element")) { 9785 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9786 child = child->next; 9787 } else if (IS_SCHEMA(child, "attribute")) { 9788 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9789 child = child->next; 9790 } else if (IS_SCHEMA(child, "attributeGroup")) { 9791 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9792 child = child->next; 9793 } else if (IS_SCHEMA(child, "group")) { 9794 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9795 child = child->next; 9796 } else if (IS_SCHEMA(child, "notation")) { 9797 xmlSchemaParseNotation(ctxt, schema, child); 9798 child = child->next; 9799 } else { 9800 xmlSchemaPContentErr(ctxt, 9801 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9802 NULL, child->parent, child, 9803 NULL, "((include | import | redefine | annotation)*, " 9804 "(((simpleType | complexType | group | attributeGroup) " 9805 "| element | attribute | notation), annotation*)*)"); 9806 child = child->next; 9807 } 9808 while (IS_SCHEMA(child, "annotation")) { 9809 /* 9810 * TODO: We should add all annotations. 9811 */ 9812 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9813 if (schema->annot == NULL) 9814 schema->annot = annot; 9815 else 9816 xmlSchemaFreeAnnot(annot); 9817 child = child->next; 9818 } 9819 } 9820exit: 9821 ctxt->ctxtType = NULL; 9822 if (oldErrs != ctxt->nberrors) 9823 res = ctxt->err; 9824 return(res); 9825exit_failure: 9826 return(-1); 9827} 9828 9829static xmlSchemaSchemaRelationPtr 9830xmlSchemaSchemaRelationCreate(void) 9831{ 9832 xmlSchemaSchemaRelationPtr ret; 9833 9834 ret = (xmlSchemaSchemaRelationPtr) 9835 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9836 if (ret == NULL) { 9837 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9838 return(NULL); 9839 } 9840 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9841 return(ret); 9842} 9843 9844#if 0 9845static void 9846xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9847{ 9848 xmlFree(rel); 9849} 9850#endif 9851 9852static void 9853xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9854{ 9855 xmlSchemaRedefPtr prev; 9856 9857 while (redef != NULL) { 9858 prev = redef; 9859 redef = redef->next; 9860 xmlFree(prev); 9861 } 9862} 9863 9864static void 9865xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9866{ 9867 /* 9868 * After the construction context has been freed, there will be 9869 * no schema graph available any more. Only the schema buckets 9870 * will stay alive, which are put into the "schemasImports" and 9871 * "includes" slots of the xmlSchema. 9872 */ 9873 if (con->buckets != NULL) 9874 xmlSchemaItemListFree(con->buckets); 9875 if (con->pending != NULL) 9876 xmlSchemaItemListFree(con->pending); 9877 if (con->substGroups != NULL) 9878 xmlHashFree(con->substGroups, 9879 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9880 if (con->redefs != NULL) 9881 xmlSchemaRedefListFree(con->redefs); 9882 if (con->dict != NULL) 9883 xmlDictFree(con->dict); 9884 xmlFree(con); 9885} 9886 9887static xmlSchemaConstructionCtxtPtr 9888xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9889{ 9890 xmlSchemaConstructionCtxtPtr ret; 9891 9892 ret = (xmlSchemaConstructionCtxtPtr) 9893 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9894 if (ret == NULL) { 9895 xmlSchemaPErrMemory(NULL, 9896 "allocating schema construction context", NULL); 9897 return (NULL); 9898 } 9899 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9900 9901 ret->buckets = xmlSchemaItemListCreate(); 9902 if (ret->buckets == NULL) { 9903 xmlSchemaPErrMemory(NULL, 9904 "allocating list of schema buckets", NULL); 9905 xmlFree(ret); 9906 return (NULL); 9907 } 9908 ret->pending = xmlSchemaItemListCreate(); 9909 if (ret->pending == NULL) { 9910 xmlSchemaPErrMemory(NULL, 9911 "allocating list of pending global components", NULL); 9912 xmlSchemaConstructionCtxtFree(ret); 9913 return (NULL); 9914 } 9915 ret->dict = dict; 9916 xmlDictReference(dict); 9917 return(ret); 9918} 9919 9920static xmlSchemaParserCtxtPtr 9921xmlSchemaParserCtxtCreate(void) 9922{ 9923 xmlSchemaParserCtxtPtr ret; 9924 9925 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9926 if (ret == NULL) { 9927 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9928 NULL); 9929 return (NULL); 9930 } 9931 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9932 ret->type = XML_SCHEMA_CTXT_PARSER; 9933 ret->attrProhibs = xmlSchemaItemListCreate(); 9934 if (ret->attrProhibs == NULL) { 9935 xmlFree(ret); 9936 return(NULL); 9937 } 9938 return(ret); 9939} 9940 9941/** 9942 * xmlSchemaNewParserCtxtUseDict: 9943 * @URL: the location of the schema 9944 * @dict: the dictionary to be used 9945 * 9946 * Create an XML Schemas parse context for that file/resource expected 9947 * to contain an XML Schemas file. 9948 * 9949 * Returns the parser context or NULL in case of error 9950 */ 9951static xmlSchemaParserCtxtPtr 9952xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9953{ 9954 xmlSchemaParserCtxtPtr ret; 9955 9956 ret = xmlSchemaParserCtxtCreate(); 9957 if (ret == NULL) 9958 return (NULL); 9959 ret->dict = dict; 9960 xmlDictReference(dict); 9961 if (URL != NULL) 9962 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9963 return (ret); 9964} 9965 9966static int 9967xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 9968{ 9969 if (vctxt->pctxt == NULL) { 9970 if (vctxt->schema != NULL) 9971 vctxt->pctxt = 9972 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 9973 else 9974 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 9975 if (vctxt->pctxt == NULL) { 9976 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 9977 "failed to create a temp. parser context"); 9978 return (-1); 9979 } 9980 /* TODO: Pass user data. */ 9981 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 9982 vctxt->warning, vctxt->errCtxt); 9983 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 9984 vctxt->errCtxt); 9985 } 9986 return (0); 9987} 9988 9989/** 9990 * xmlSchemaGetSchemaBucket: 9991 * @pctxt: the schema parser context 9992 * @schemaLocation: the URI of the schema document 9993 * 9994 * Returns a schema bucket if it was already parsed. 9995 * 9996 * Returns a schema bucket if it was already parsed from 9997 * @schemaLocation, NULL otherwise. 9998 */ 9999static xmlSchemaBucketPtr 10000xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10001 const xmlChar *schemaLocation) 10002{ 10003 xmlSchemaBucketPtr cur; 10004 xmlSchemaItemListPtr list; 10005 10006 list = pctxt->constructor->buckets; 10007 if (list->nbItems == 0) 10008 return(NULL); 10009 else { 10010 int i; 10011 for (i = 0; i < list->nbItems; i++) { 10012 cur = (xmlSchemaBucketPtr) list->items[i]; 10013 /* Pointer comparison! */ 10014 if (cur->schemaLocation == schemaLocation) 10015 return(cur); 10016 } 10017 } 10018 return(NULL); 10019} 10020 10021static xmlSchemaBucketPtr 10022xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10023 const xmlChar *schemaLocation, 10024 const xmlChar *targetNamespace) 10025{ 10026 xmlSchemaBucketPtr cur; 10027 xmlSchemaItemListPtr list; 10028 10029 list = pctxt->constructor->buckets; 10030 if (list->nbItems == 0) 10031 return(NULL); 10032 else { 10033 int i; 10034 for (i = 0; i < list->nbItems; i++) { 10035 cur = (xmlSchemaBucketPtr) list->items[i]; 10036 /* Pointer comparison! */ 10037 if ((cur->origTargetNamespace == NULL) && 10038 (cur->schemaLocation == schemaLocation) && 10039 (cur->targetNamespace == targetNamespace)) 10040 return(cur); 10041 } 10042 } 10043 return(NULL); 10044} 10045 10046 10047#define IS_BAD_SCHEMA_DOC(b) \ 10048 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10049 10050static xmlSchemaBucketPtr 10051xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10052 const xmlChar *targetNamespace, 10053 int imported) 10054{ 10055 xmlSchemaBucketPtr cur; 10056 xmlSchemaItemListPtr list; 10057 10058 list = pctxt->constructor->buckets; 10059 if (list->nbItems == 0) 10060 return(NULL); 10061 else { 10062 int i; 10063 for (i = 0; i < list->nbItems; i++) { 10064 cur = (xmlSchemaBucketPtr) list->items[i]; 10065 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10066 (cur->origTargetNamespace == targetNamespace) && 10067 ((imported && cur->imported) || 10068 ((!imported) && (!cur->imported)))) 10069 return(cur); 10070 } 10071 } 10072 return(NULL); 10073} 10074 10075static int 10076xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10077 xmlSchemaPtr schema, 10078 xmlSchemaBucketPtr bucket) 10079{ 10080 int oldFlags; 10081 xmlDocPtr oldDoc; 10082 xmlNodePtr node; 10083 int ret, oldErrs; 10084 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10085 10086 /* 10087 * Save old values; reset the *main* schema. 10088 * URGENT TODO: This is not good; move the per-document information 10089 * to the parser. Get rid of passing the main schema to the 10090 * parsing functions. 10091 */ 10092 oldFlags = schema->flags; 10093 oldDoc = schema->doc; 10094 if (schema->flags != 0) 10095 xmlSchemaClearSchemaDefaults(schema); 10096 schema->doc = bucket->doc; 10097 pctxt->schema = schema; 10098 /* 10099 * Keep the current target namespace on the parser *not* on the 10100 * main schema. 10101 */ 10102 pctxt->targetNamespace = bucket->targetNamespace; 10103 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10104 10105 if ((bucket->targetNamespace != NULL) && 10106 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10107 /* 10108 * We are parsing the schema for schemas! 10109 */ 10110 pctxt->isS4S = 1; 10111 } 10112 /* Mark it as parsed, even if parsing fails. */ 10113 bucket->parsed++; 10114 /* Compile the schema doc. */ 10115 node = xmlDocGetRootElement(bucket->doc); 10116 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10117 if (ret != 0) 10118 goto exit; 10119 /* An empty schema; just get out. */ 10120 if (node->children == NULL) 10121 goto exit; 10122 oldErrs = pctxt->nberrors; 10123 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10124 if (ret != 0) 10125 goto exit; 10126 /* 10127 * TODO: Not nice, but I'm not 100% sure we will get always an error 10128 * as a result of the obove functions; so better rely on pctxt->err 10129 * as well. 10130 */ 10131 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10132 ret = pctxt->err; 10133 goto exit; 10134 } 10135 10136exit: 10137 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10138 /* Restore schema values. */ 10139 schema->doc = oldDoc; 10140 schema->flags = oldFlags; 10141 return(ret); 10142} 10143 10144static int 10145xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10146 xmlSchemaPtr schema, 10147 xmlSchemaBucketPtr bucket) 10148{ 10149 xmlSchemaParserCtxtPtr newpctxt; 10150 int res = 0; 10151 10152 if (bucket == NULL) 10153 return(0); 10154 if (bucket->parsed) { 10155 PERROR_INT("xmlSchemaParseNewDoc", 10156 "reparsing a schema doc"); 10157 return(-1); 10158 } 10159 if (bucket->doc == NULL) { 10160 PERROR_INT("xmlSchemaParseNewDoc", 10161 "parsing a schema doc, but there's no doc"); 10162 return(-1); 10163 } 10164 if (pctxt->constructor == NULL) { 10165 PERROR_INT("xmlSchemaParseNewDoc", 10166 "no constructor"); 10167 return(-1); 10168 } 10169 /* Create and init the temporary parser context. */ 10170 newpctxt = xmlSchemaNewParserCtxtUseDict( 10171 (const char *) bucket->schemaLocation, pctxt->dict); 10172 if (newpctxt == NULL) 10173 return(-1); 10174 newpctxt->constructor = pctxt->constructor; 10175 /* 10176 * TODO: Can we avoid that the parser knows about the main schema? 10177 * It would be better if he knows about the current schema bucket 10178 * only. 10179 */ 10180 newpctxt->schema = schema; 10181 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10182 pctxt->errCtxt); 10183 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10184 pctxt->errCtxt); 10185 newpctxt->counter = pctxt->counter; 10186 10187 10188 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10189 10190 /* Channel back errors and cleanup the temporary parser context. */ 10191 if (res != 0) 10192 pctxt->err = res; 10193 pctxt->nberrors += newpctxt->nberrors; 10194 pctxt->counter = newpctxt->counter; 10195 newpctxt->constructor = NULL; 10196 /* Free the parser context. */ 10197 xmlSchemaFreeParserCtxt(newpctxt); 10198 return(res); 10199} 10200 10201static void 10202xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10203 xmlSchemaSchemaRelationPtr rel) 10204{ 10205 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10206 10207 if (cur == NULL) { 10208 bucket->relations = rel; 10209 return; 10210 } 10211 while (cur->next != NULL) 10212 cur = cur->next; 10213 cur->next = rel; 10214} 10215 10216 10217static const xmlChar * 10218xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10219 xmlNodePtr ctxtNode) 10220{ 10221 /* 10222 * Build an absolue location URI. 10223 */ 10224 if (location != NULL) { 10225 if (ctxtNode == NULL) 10226 return(location); 10227 else { 10228 xmlChar *base, *URI; 10229 const xmlChar *ret = NULL; 10230 10231 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10232 if (base == NULL) { 10233 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10234 } else { 10235 URI = xmlBuildURI(location, base); 10236 xmlFree(base); 10237 } 10238 if (URI != NULL) { 10239 ret = xmlDictLookup(dict, URI, -1); 10240 xmlFree(URI); 10241 return(ret); 10242 } 10243 } 10244 } 10245 return(NULL); 10246} 10247 10248 10249 10250/** 10251 * xmlSchemaAddSchemaDoc: 10252 * @pctxt: a schema validation context 10253 * @schema: the schema being built 10254 * @node: a subtree containing XML Schema informations 10255 * 10256 * Parse an included (and to-be-redefined) XML schema document. 10257 * 10258 * Returns 0 on success, a positive error code on errors and 10259 * -1 in case of an internal or API error. 10260 */ 10261 10262static int 10263xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10264 int type, /* import or include or redefine */ 10265 const xmlChar *schemaLocation, 10266 xmlDocPtr schemaDoc, 10267 const char *schemaBuffer, 10268 int schemaBufferLen, 10269 xmlNodePtr invokingNode, 10270 const xmlChar *sourceTargetNamespace, 10271 const xmlChar *importNamespace, 10272 xmlSchemaBucketPtr *bucket) 10273{ 10274 const xmlChar *targetNamespace = NULL; 10275 xmlSchemaSchemaRelationPtr relation = NULL; 10276 xmlDocPtr doc = NULL; 10277 int res = 0, err = 0, located = 0, preserveDoc = 0; 10278 xmlSchemaBucketPtr bkt = NULL; 10279 10280 if (bucket != NULL) 10281 *bucket = NULL; 10282 10283 switch (type) { 10284 case XML_SCHEMA_SCHEMA_IMPORT: 10285 case XML_SCHEMA_SCHEMA_MAIN: 10286 err = XML_SCHEMAP_SRC_IMPORT; 10287 break; 10288 case XML_SCHEMA_SCHEMA_INCLUDE: 10289 err = XML_SCHEMAP_SRC_INCLUDE; 10290 break; 10291 case XML_SCHEMA_SCHEMA_REDEFINE: 10292 err = XML_SCHEMAP_SRC_REDEFINE; 10293 break; 10294 } 10295 10296 10297 /* Special handling for the main schema: 10298 * skip the location and relation logic and just parse the doc. 10299 * We need just a bucket to be returned in this case. 10300 */ 10301 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10302 goto doc_load; 10303 10304 /* Note that we expect the location to be an absulute URI. */ 10305 if (schemaLocation != NULL) { 10306 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10307 if ((bkt != NULL) && 10308 (pctxt->constructor->bucket == bkt)) { 10309 /* Report self-imports/inclusions/redefinitions. */ 10310 10311 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10312 invokingNode, NULL, 10313 "The schema must not import/include/redefine itself", 10314 NULL, NULL); 10315 goto exit; 10316 } 10317 } 10318 /* 10319 * Create a relation for the graph of schemas. 10320 */ 10321 relation = xmlSchemaSchemaRelationCreate(); 10322 if (relation == NULL) 10323 return(-1); 10324 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10325 relation); 10326 relation->type = type; 10327 10328 /* 10329 * Save the namespace import information. 10330 */ 10331 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10332 relation->importNamespace = importNamespace; 10333 if (schemaLocation == NULL) { 10334 /* 10335 * No location; this is just an import of the namespace. 10336 * Note that we don't assign a bucket to the relation 10337 * in this case. 10338 */ 10339 goto exit; 10340 } 10341 targetNamespace = importNamespace; 10342 } 10343 10344 /* Did we already fetch the doc? */ 10345 if (bkt != NULL) { 10346 /* TODO: The following nasty cases will produce an error. */ 10347 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10348 /* We included/redefined and then try to import a schema. */ 10349 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10350 invokingNode, NULL, 10351 "The schema document '%s' cannot be imported, since " 10352 "it was already included or redefined", 10353 schemaLocation, NULL); 10354 goto exit; 10355 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10356 /* We imported and then try to include/redefine a schema. */ 10357 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10358 invokingNode, NULL, 10359 "The schema document '%s' cannot be included or " 10360 "redefined, since it was already imported", 10361 schemaLocation, NULL); 10362 goto exit; 10363 } 10364 } 10365 10366 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10367 /* 10368 * Given that the schemaLocation [attribute] is only a hint, it is open 10369 * to applications to ignore all but the first <import> for a given 10370 * namespace, regardless of the �actual value� of schemaLocation, but 10371 * such a strategy risks missing useful information when new 10372 * schemaLocations are offered. 10373 * 10374 * We will use the first <import> that comes with a location. 10375 * Further <import>s *with* a location, will result in an error. 10376 * TODO: Better would be to just report a warning here, but 10377 * we'll try it this way until someone complains. 10378 * 10379 * Schema Document Location Strategy: 10380 * 3 Based on the namespace name, identify an existing schema document, 10381 * either as a resource which is an XML document or a <schema> element 10382 * information item, in some local schema repository; 10383 * 5 Attempt to resolve the namespace name to locate such a resource. 10384 * 10385 * NOTE: (3) and (5) are not supported. 10386 */ 10387 if (bkt != NULL) { 10388 relation->bucket = bkt; 10389 goto exit; 10390 } 10391 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10392 importNamespace, 1); 10393 10394 if (bkt != NULL) { 10395 relation->bucket = bkt; 10396 if (bkt->schemaLocation == NULL) { 10397 /* First given location of the schema; load the doc. */ 10398 bkt->schemaLocation = schemaLocation; 10399 } else { 10400 if (!xmlStrEqual(schemaLocation, 10401 bkt->schemaLocation)) { 10402 /* 10403 * Additional location given; just skip it. 10404 * URGENT TODO: We should report a warning here. 10405 * res = XML_SCHEMAP_SRC_IMPORT; 10406 */ 10407 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10408 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10409 invokingNode, NULL, 10410 "Skipping import of schema located at '%s' for the " 10411 "namespace '%s', since this namespace was already " 10412 "imported with the schema located at '%s'", 10413 schemaLocation, importNamespace, bkt->schemaLocation); 10414 } 10415 goto exit; 10416 } 10417 } 10418 /* 10419 * No bucket + first location: load the doc and create a 10420 * bucket. 10421 */ 10422 } else { 10423 /* <include> and <redefine> */ 10424 if (bkt != NULL) { 10425 10426 if ((bkt->origTargetNamespace == NULL) && 10427 (bkt->targetNamespace != sourceTargetNamespace)) { 10428 xmlSchemaBucketPtr chamel; 10429 10430 /* 10431 * Chameleon include/redefine: skip loading only if it was 10432 * aleady build for the targetNamespace of the including 10433 * schema. 10434 */ 10435 /* 10436 * URGENT TODO: If the schema is a chameleon-include then copy 10437 * the components into the including schema and modify the 10438 * targetNamespace of those components, do nothing otherwise. 10439 * NOTE: This is currently worked-around by compiling the 10440 * chameleon for every destinct including targetNamespace; thus 10441 * not performant at the moment. 10442 * TODO: Check when the namespace in wildcards for chameleons 10443 * needs to be converted: before we built wildcard intersections 10444 * or after. 10445 * Answer: after! 10446 */ 10447 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10448 schemaLocation, sourceTargetNamespace); 10449 if (chamel != NULL) { 10450 /* A fitting chameleon was already parsed; NOP. */ 10451 relation->bucket = chamel; 10452 goto exit; 10453 } 10454 /* 10455 * We need to parse the chameleon again for a different 10456 * targetNamespace. 10457 * CHAMELEON TODO: Optimize this by only parsing the 10458 * chameleon once, and then copying the components to 10459 * the new targetNamespace. 10460 */ 10461 bkt = NULL; 10462 } else { 10463 relation->bucket = bkt; 10464 goto exit; 10465 } 10466 } 10467 } 10468 if ((bkt != NULL) && (bkt->doc != NULL)) { 10469 PERROR_INT("xmlSchemaAddSchemaDoc", 10470 "trying to load a schema doc, but a doc is already " 10471 "assigned to the schema bucket"); 10472 goto exit_failure; 10473 } 10474 10475doc_load: 10476 /* 10477 * Load the document. 10478 */ 10479 if (schemaDoc != NULL) { 10480 doc = schemaDoc; 10481 /* Don' free this one, since it was provided by the caller. */ 10482 preserveDoc = 1; 10483 /* TODO: Does the context or the doc hold the location? */ 10484 if (schemaDoc->URL != NULL) 10485 schemaLocation = xmlDictLookup(pctxt->dict, 10486 schemaDoc->URL, -1); 10487 10488 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10489 xmlParserCtxtPtr parserCtxt; 10490 10491 parserCtxt = xmlNewParserCtxt(); 10492 if (parserCtxt == NULL) { 10493 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10494 "allocating a parser context", NULL); 10495 goto exit_failure; 10496 } 10497 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10498 /* 10499 * TODO: Do we have to burden the schema parser dict with all 10500 * the content of the schema doc? 10501 */ 10502 xmlDictFree(parserCtxt->dict); 10503 parserCtxt->dict = pctxt->dict; 10504 xmlDictReference(parserCtxt->dict); 10505 } 10506 if (schemaLocation != NULL) { 10507 /* Parse from file. */ 10508 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10509 NULL, SCHEMAS_PARSE_OPTIONS); 10510 } else if (schemaBuffer != NULL) { 10511 /* Parse from memory buffer. */ 10512 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10513 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10514 schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer"); 10515 if (doc != NULL) 10516 doc->URL = schemaLocation; 10517 } 10518 /* 10519 * For <import>: 10520 * 2.1 The referent is (a fragment of) a resource which is an 10521 * XML document (see clause 1.1), which in turn corresponds to 10522 * a <schema> element information item in a well-formed information 10523 * set, which in turn corresponds to a valid schema. 10524 * TODO: (2.1) fragments of XML documents are not supported. 10525 * 10526 * 2.2 The referent is a <schema> element information item in 10527 * a well-formed information set, which in turn corresponds 10528 * to a valid schema. 10529 * TODO: (2.2) is not supported. 10530 */ 10531 if (doc == NULL) { 10532 xmlErrorPtr lerr; 10533 lerr = xmlGetLastError(); 10534 /* 10535 * Check if this a parser error, or if the document could 10536 * just not be located. 10537 * TODO: Try to find specific error codes to react only on 10538 * localisation failures. 10539 */ 10540 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10541 /* 10542 * We assume a parser error here. 10543 */ 10544 located = 1; 10545 /* TODO: Error code ?? */ 10546 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10547 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10548 invokingNode, NULL, 10549 "Failed to parse the XML resource '%s'", 10550 schemaLocation, NULL); 10551 } 10552 } 10553 xmlFreeParserCtxt(parserCtxt); 10554 if ((doc == NULL) && located) 10555 goto exit_error; 10556 } else { 10557 xmlSchemaPErr(pctxt, NULL, 10558 XML_SCHEMAP_NOTHING_TO_PARSE, 10559 "No information for parsing was provided with the " 10560 "given schema parser context.\n", 10561 NULL, NULL); 10562 goto exit_failure; 10563 } 10564 /* 10565 * Preprocess the document. 10566 */ 10567 if (doc != NULL) { 10568 xmlNodePtr docElem = NULL; 10569 10570 located = 1; 10571 docElem = xmlDocGetRootElement(doc); 10572 if (docElem == NULL) { 10573 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10574 invokingNode, NULL, 10575 "The document '%s' has no document element", 10576 schemaLocation, NULL); 10577 goto exit_error; 10578 } 10579 /* 10580 * Remove all the blank text nodes. 10581 */ 10582 xmlSchemaCleanupDoc(pctxt, docElem); 10583 /* 10584 * Check the schema's top level element. 10585 */ 10586 if (!IS_SCHEMA(docElem, "schema")) { 10587 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10588 invokingNode, NULL, 10589 "The XML document '%s' is not a schema document", 10590 schemaLocation, NULL); 10591 goto exit_error; 10592 } 10593 /* 10594 * Note that we don't apply a type check for the 10595 * targetNamespace value here. 10596 */ 10597 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10598 "targetNamespace"); 10599 } 10600 10601/* after_doc_loading: */ 10602 if ((bkt == NULL) && located) { 10603 /* Only create a bucket if the schema was located. */ 10604 bkt = xmlSchemaBucketCreate(pctxt, type, 10605 targetNamespace); 10606 if (bkt == NULL) 10607 goto exit_failure; 10608 } 10609 if (bkt != NULL) { 10610 bkt->schemaLocation = schemaLocation; 10611 bkt->located = located; 10612 if (doc != NULL) { 10613 bkt->doc = doc; 10614 bkt->targetNamespace = targetNamespace; 10615 bkt->origTargetNamespace = targetNamespace; 10616 if (preserveDoc) 10617 bkt->preserveDoc = 1; 10618 } 10619 if (WXS_IS_BUCKET_IMPMAIN(type)) 10620 bkt->imported++; 10621 /* 10622 * Add it to the graph of schemas. 10623 */ 10624 if (relation != NULL) 10625 relation->bucket = bkt; 10626 } 10627 10628exit: 10629 /* 10630 * Return the bucket explicitely; this is needed for the 10631 * main schema. 10632 */ 10633 if (bucket != NULL) 10634 *bucket = bkt; 10635 return (0); 10636 10637exit_error: 10638 if ((doc != NULL) && (! preserveDoc)) { 10639 xmlFreeDoc(doc); 10640 if (bkt != NULL) 10641 bkt->doc = NULL; 10642 } 10643 return(pctxt->err); 10644 10645exit_failure: 10646 if ((doc != NULL) && (! preserveDoc)) { 10647 xmlFreeDoc(doc); 10648 if (bkt != NULL) 10649 bkt->doc = NULL; 10650 } 10651 return (-1); 10652} 10653 10654/** 10655 * xmlSchemaParseImport: 10656 * @ctxt: a schema validation context 10657 * @schema: the schema being built 10658 * @node: a subtree containing XML Schema informations 10659 * 10660 * parse a XML schema Import definition 10661 * *WARNING* this interface is highly subject to change 10662 * 10663 * Returns 0 in case of success, a positive error code if 10664 * not valid and -1 in case of an internal error. 10665 */ 10666static int 10667xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10668 xmlNodePtr node) 10669{ 10670 xmlNodePtr child; 10671 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10672 const xmlChar *thisTargetNamespace; 10673 xmlAttrPtr attr; 10674 int ret = 0; 10675 xmlSchemaBucketPtr bucket = NULL; 10676 10677 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10678 return (-1); 10679 10680 /* 10681 * Check for illegal attributes. 10682 */ 10683 attr = node->properties; 10684 while (attr != NULL) { 10685 if (attr->ns == NULL) { 10686 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10687 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10688 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10689 xmlSchemaPIllegalAttrErr(pctxt, 10690 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10691 } 10692 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10693 xmlSchemaPIllegalAttrErr(pctxt, 10694 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10695 } 10696 attr = attr->next; 10697 } 10698 /* 10699 * Extract and validate attributes. 10700 */ 10701 if (xmlSchemaPValAttr(pctxt, NULL, node, 10702 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10703 &namespaceName) != 0) { 10704 xmlSchemaPSimpleTypeErr(pctxt, 10705 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10706 NULL, node, 10707 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10708 NULL, namespaceName, NULL, NULL, NULL); 10709 return (pctxt->err); 10710 } 10711 10712 if (xmlSchemaPValAttr(pctxt, NULL, node, 10713 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10714 &schemaLocation) != 0) { 10715 xmlSchemaPSimpleTypeErr(pctxt, 10716 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10717 NULL, node, 10718 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10719 NULL, namespaceName, NULL, NULL, NULL); 10720 return (pctxt->err); 10721 } 10722 /* 10723 * And now for the children... 10724 */ 10725 child = node->children; 10726 if (IS_SCHEMA(child, "annotation")) { 10727 /* 10728 * the annotation here is simply discarded ... 10729 * TODO: really? 10730 */ 10731 child = child->next; 10732 } 10733 if (child != NULL) { 10734 xmlSchemaPContentErr(pctxt, 10735 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10736 NULL, node, child, NULL, 10737 "(annotation?)"); 10738 } 10739 /* 10740 * Apply additional constraints. 10741 * 10742 * Note that it is important to use the original @targetNamespace 10743 * (or none at all), to rule out imports of schemas _with_ a 10744 * @targetNamespace if the importing schema is a chameleon schema 10745 * (with no @targetNamespace). 10746 */ 10747 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10748 if (namespaceName != NULL) { 10749 /* 10750 * 1.1 If the namespace [attribute] is present, then its �actual value� 10751 * must not match the �actual value� of the enclosing <schema>'s 10752 * targetNamespace [attribute]. 10753 */ 10754 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10755 xmlSchemaPCustomErr(pctxt, 10756 XML_SCHEMAP_SRC_IMPORT_1_1, 10757 NULL, node, 10758 "The value of the attribute 'namespace' must not match " 10759 "the target namespace '%s' of the importing schema", 10760 thisTargetNamespace); 10761 return (pctxt->err); 10762 } 10763 } else { 10764 /* 10765 * 1.2 If the namespace [attribute] is not present, then the enclosing 10766 * <schema> must have a targetNamespace [attribute]. 10767 */ 10768 if (thisTargetNamespace == NULL) { 10769 xmlSchemaPCustomErr(pctxt, 10770 XML_SCHEMAP_SRC_IMPORT_1_2, 10771 NULL, node, 10772 "The attribute 'namespace' must be existent if " 10773 "the importing schema has no target namespace", 10774 NULL); 10775 return (pctxt->err); 10776 } 10777 } 10778 /* 10779 * Locate and acquire the schema document. 10780 */ 10781 if (schemaLocation != NULL) 10782 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10783 schemaLocation, node); 10784 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10785 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10786 namespaceName, &bucket); 10787 10788 if (ret != 0) 10789 return(ret); 10790 10791 /* 10792 * For <import>: "It is *not* an error for the application 10793 * schema reference strategy to fail." 10794 * So just don't parse if no schema document was found. 10795 * Note that we will get no bucket if the schema could not be 10796 * located or if there was no schemaLocation. 10797 */ 10798 if ((bucket == NULL) && (schemaLocation != NULL)) { 10799 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10800 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10801 node, NULL, 10802 "Failed to locate a schema at location '%s'. " 10803 "Skipping the import", schemaLocation, NULL, NULL); 10804 } 10805 10806 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10807 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10808 } 10809 10810 return (ret); 10811} 10812 10813static int 10814xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10815 xmlSchemaPtr schema, 10816 xmlNodePtr node, 10817 xmlChar **schemaLocation, 10818 int type) 10819{ 10820 xmlAttrPtr attr; 10821 10822 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10823 (schemaLocation == NULL)) 10824 return (-1); 10825 10826 *schemaLocation = NULL; 10827 /* 10828 * Check for illegal attributes. 10829 * Applies for both <include> and <redefine>. 10830 */ 10831 attr = node->properties; 10832 while (attr != NULL) { 10833 if (attr->ns == NULL) { 10834 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10835 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10836 xmlSchemaPIllegalAttrErr(pctxt, 10837 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10838 } 10839 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10840 xmlSchemaPIllegalAttrErr(pctxt, 10841 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10842 } 10843 attr = attr->next; 10844 } 10845 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10846 /* 10847 * Preliminary step, extract the URI-Reference and make an URI 10848 * from the base. 10849 */ 10850 /* 10851 * Attribute "schemaLocation" is mandatory. 10852 */ 10853 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10854 if (attr != NULL) { 10855 xmlChar *base = NULL; 10856 xmlChar *uri = NULL; 10857 10858 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10859 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10860 (const xmlChar **) schemaLocation) != 0) 10861 goto exit_error; 10862 base = xmlNodeGetBase(node->doc, node); 10863 if (base == NULL) { 10864 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10865 } else { 10866 uri = xmlBuildURI(*schemaLocation, base); 10867 xmlFree(base); 10868 } 10869 if (uri == NULL) { 10870 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10871 "could not build an URI from the schemaLocation") 10872 goto exit_failure; 10873 } 10874 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10875 xmlFree(uri); 10876 } else { 10877 xmlSchemaPMissingAttrErr(pctxt, 10878 XML_SCHEMAP_S4S_ATTR_MISSING, 10879 NULL, node, "schemaLocation", NULL); 10880 goto exit_error; 10881 } 10882 /* 10883 * Report self-inclusion and self-redefinition. 10884 */ 10885 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10886 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10887 xmlSchemaPCustomErr(pctxt, 10888 XML_SCHEMAP_SRC_REDEFINE, 10889 NULL, node, 10890 "The schema document '%s' cannot redefine itself.", 10891 *schemaLocation); 10892 } else { 10893 xmlSchemaPCustomErr(pctxt, 10894 XML_SCHEMAP_SRC_INCLUDE, 10895 NULL, node, 10896 "The schema document '%s' cannot include itself.", 10897 *schemaLocation); 10898 } 10899 goto exit_error; 10900 } 10901 10902 return(0); 10903exit_error: 10904 return(pctxt->err); 10905exit_failure: 10906 return(-1); 10907} 10908 10909static int 10910xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10911 xmlSchemaPtr schema, 10912 xmlNodePtr node, 10913 int type) 10914{ 10915 xmlNodePtr child = NULL; 10916 const xmlChar *schemaLocation = NULL; 10917 int res = 0; /* hasRedefinitions = 0 */ 10918 int isChameleon = 0, wasChameleon = 0; 10919 xmlSchemaBucketPtr bucket = NULL; 10920 10921 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10922 return (-1); 10923 10924 /* 10925 * Parse attributes. Note that the returned schemaLocation will 10926 * be already converted to an absolute URI. 10927 */ 10928 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10929 node, (xmlChar **) (&schemaLocation), type); 10930 if (res != 0) 10931 return(res); 10932 /* 10933 * Load and add the schema document. 10934 */ 10935 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10936 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10937 if (res != 0) 10938 return(res); 10939 /* 10940 * If we get no schema bucket back, then this means that the schema 10941 * document could not be located or was broken XML or was not 10942 * a schema document. 10943 */ 10944 if ((bucket == NULL) || (bucket->doc == NULL)) { 10945 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 10946 /* 10947 * WARNING for <include>: 10948 * We will raise an error if the schema cannot be located 10949 * for inclusions, since the that was the feedback from the 10950 * schema people. I.e. the following spec piece will *not* be 10951 * satisfied: 10952 * SPEC src-include: "It is not an error for the �actual value� of the 10953 * schemaLocation [attribute] to fail to resolve it all, in which 10954 * case no corresponding inclusion is performed. 10955 * So do we need a warning report here?" 10956 */ 10957 res = XML_SCHEMAP_SRC_INCLUDE; 10958 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10959 node, NULL, 10960 "Failed to load the document '%s' for inclusion", 10961 schemaLocation, NULL); 10962 } else { 10963 /* 10964 * NOTE: This was changed to raise an error even if no redefinitions 10965 * are specified. 10966 * 10967 * SPEC src-redefine (1) 10968 * "If there are any element information items among the [children] 10969 * other than <annotation> then the �actual value� of the 10970 * schemaLocation [attribute] must successfully resolve." 10971 * TODO: Ask the WG if a the location has always to resolve 10972 * here as well! 10973 */ 10974 res = XML_SCHEMAP_SRC_REDEFINE; 10975 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10976 node, NULL, 10977 "Failed to load the document '%s' for redefinition", 10978 schemaLocation, NULL); 10979 } 10980 } else { 10981 /* 10982 * Check targetNamespace sanity before parsing the new schema. 10983 * TODO: Note that we won't check further content if the 10984 * targetNamespace was bad. 10985 */ 10986 if (bucket->origTargetNamespace != NULL) { 10987 /* 10988 * SPEC src-include (2.1) 10989 * "SII has a targetNamespace [attribute], and its �actual 10990 * value� is identical to the �actual value� of the targetNamespace 10991 * [attribute] of SII� (which must have such an [attribute])." 10992 */ 10993 if (pctxt->targetNamespace == NULL) { 10994 xmlSchemaCustomErr(ACTXT_CAST pctxt, 10995 XML_SCHEMAP_SRC_INCLUDE, 10996 node, NULL, 10997 "The target namespace of the included/redefined schema " 10998 "'%s' has to be absent, since the including/redefining " 10999 "schema has no target namespace", 11000 schemaLocation, NULL); 11001 goto exit_error; 11002 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11003 pctxt->targetNamespace)) { 11004 /* TODO: Change error function. */ 11005 xmlSchemaPCustomErrExt(pctxt, 11006 XML_SCHEMAP_SRC_INCLUDE, 11007 NULL, node, 11008 "The target namespace '%s' of the included/redefined " 11009 "schema '%s' differs from '%s' of the " 11010 "including/redefining schema", 11011 bucket->origTargetNamespace, schemaLocation, 11012 pctxt->targetNamespace); 11013 goto exit_error; 11014 } 11015 } else if (pctxt->targetNamespace != NULL) { 11016 /* 11017 * Chameleons: the original target namespace will 11018 * differ from the resulting namespace. 11019 */ 11020 isChameleon = 1; 11021 if (bucket->parsed && 11022 (bucket->targetNamespace != pctxt->targetNamespace)) { 11023 /* 11024 * This is a sanity check, I dunno yet if this can happen. 11025 */ 11026 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 11027 "trying to use an already parsed schema for a " 11028 "different targetNamespace"); 11029 return(-1); 11030 } 11031 bucket->targetNamespace = pctxt->targetNamespace; 11032 } 11033 } 11034 /* 11035 * Parse the schema. 11036 */ 11037 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11038 if (isChameleon) { 11039 /* TODO: Get rid of this flag on the schema itself. */ 11040 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11041 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11042 } else 11043 wasChameleon = 1; 11044 } 11045 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11046 /* Restore chameleon flag. */ 11047 if (isChameleon && (!wasChameleon)) 11048 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11049 } 11050 /* 11051 * And now for the children... 11052 */ 11053 child = node->children; 11054 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11055 /* 11056 * Parse (simpleType | complexType | group | attributeGroup))* 11057 */ 11058 pctxt->redefined = bucket; 11059 /* 11060 * How to proceed if the redefined schema was not located? 11061 */ 11062 pctxt->isRedefine = 1; 11063 while (IS_SCHEMA(child, "annotation") || 11064 IS_SCHEMA(child, "simpleType") || 11065 IS_SCHEMA(child, "complexType") || 11066 IS_SCHEMA(child, "group") || 11067 IS_SCHEMA(child, "attributeGroup")) { 11068 if (IS_SCHEMA(child, "annotation")) { 11069 /* 11070 * TODO: discard or not? 11071 */ 11072 } else if (IS_SCHEMA(child, "simpleType")) { 11073 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11074 } else if (IS_SCHEMA(child, "complexType")) { 11075 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11076 /* hasRedefinitions = 1; */ 11077 } else if (IS_SCHEMA(child, "group")) { 11078 /* hasRedefinitions = 1; */ 11079 xmlSchemaParseModelGroupDefinition(pctxt, 11080 schema, child); 11081 } else if (IS_SCHEMA(child, "attributeGroup")) { 11082 /* hasRedefinitions = 1; */ 11083 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11084 child); 11085 } 11086 child = child->next; 11087 } 11088 pctxt->redefined = NULL; 11089 pctxt->isRedefine = 0; 11090 } else { 11091 if (IS_SCHEMA(child, "annotation")) { 11092 /* 11093 * TODO: discard or not? 11094 */ 11095 child = child->next; 11096 } 11097 } 11098 if (child != NULL) { 11099 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11100 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11101 xmlSchemaPContentErr(pctxt, res, 11102 NULL, node, child, NULL, 11103 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11104 } else { 11105 xmlSchemaPContentErr(pctxt, res, 11106 NULL, node, child, NULL, 11107 "(annotation?)"); 11108 } 11109 } 11110 return(res); 11111 11112exit_error: 11113 return(pctxt->err); 11114} 11115 11116static int 11117xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11118 xmlNodePtr node) 11119{ 11120 int res; 11121#ifndef ENABLE_REDEFINE 11122 TODO 11123 return(0); 11124#endif 11125 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11126 XML_SCHEMA_SCHEMA_REDEFINE); 11127 if (res != 0) 11128 return(res); 11129 return(0); 11130} 11131 11132static int 11133xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11134 xmlNodePtr node) 11135{ 11136 int res; 11137 11138 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11139 XML_SCHEMA_SCHEMA_INCLUDE); 11140 if (res != 0) 11141 return(res); 11142 return(0); 11143} 11144 11145/** 11146 * xmlSchemaParseModelGroup: 11147 * @ctxt: a schema validation context 11148 * @schema: the schema being built 11149 * @node: a subtree containing XML Schema informations 11150 * @type: the "compositor" type 11151 * @particleNeeded: if a a model group with a particle 11152 * 11153 * parse a XML schema Sequence definition. 11154 * Applies parts of: 11155 * Schema Representation Constraint: 11156 * Redefinition Constraints and Semantics (src-redefine) 11157 * (6.1), (6.1.1), (6.1.2) 11158 * 11159 * Schema Component Constraint: 11160 * All Group Limited (cos-all-limited) (2) 11161 * TODO: Actually this should go to component-level checks, 11162 * but is done here due to performance. Move it to an other layer 11163 * is schema construction via an API is implemented. 11164 * 11165 * *WARNING* this interface is highly subject to change 11166 * 11167 * Returns -1 in case of error, 0 if the declaration is improper and 11168 * 1 in case of success. 11169 */ 11170static xmlSchemaTreeItemPtr 11171xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11172 xmlNodePtr node, xmlSchemaTypeType type, 11173 int withParticle) 11174{ 11175 xmlSchemaModelGroupPtr item; 11176 xmlSchemaParticlePtr particle = NULL; 11177 xmlNodePtr child = NULL; 11178 xmlAttrPtr attr; 11179 int min = 1, max = 1, isElemRef, hasRefs = 0; 11180 11181 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11182 return (NULL); 11183 /* 11184 * Create a model group with the given compositor. 11185 */ 11186 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11187 if (item == NULL) 11188 return (NULL); 11189 11190 if (withParticle) { 11191 if (type == XML_SCHEMA_TYPE_ALL) { 11192 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11193 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11194 } else { 11195 /* choice + sequence */ 11196 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11197 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11198 "(xs:nonNegativeInteger | unbounded)"); 11199 } 11200 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11201 /* 11202 * Create a particle 11203 */ 11204 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11205 if (particle == NULL) 11206 return (NULL); 11207 particle->children = (xmlSchemaTreeItemPtr) item; 11208 /* 11209 * Check for illegal attributes. 11210 */ 11211 attr = node->properties; 11212 while (attr != NULL) { 11213 if (attr->ns == NULL) { 11214 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11215 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11216 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11217 xmlSchemaPIllegalAttrErr(ctxt, 11218 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11219 } 11220 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11221 xmlSchemaPIllegalAttrErr(ctxt, 11222 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11223 } 11224 attr = attr->next; 11225 } 11226 } else { 11227 /* 11228 * Check for illegal attributes. 11229 */ 11230 attr = node->properties; 11231 while (attr != NULL) { 11232 if (attr->ns == NULL) { 11233 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11234 xmlSchemaPIllegalAttrErr(ctxt, 11235 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11236 } 11237 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11238 xmlSchemaPIllegalAttrErr(ctxt, 11239 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11240 } 11241 attr = attr->next; 11242 } 11243 } 11244 11245 /* 11246 * Extract and validate attributes. 11247 */ 11248 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11249 /* 11250 * And now for the children... 11251 */ 11252 child = node->children; 11253 if (IS_SCHEMA(child, "annotation")) { 11254 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11255 child = child->next; 11256 } 11257 if (type == XML_SCHEMA_TYPE_ALL) { 11258 xmlSchemaParticlePtr part, last = NULL; 11259 11260 while (IS_SCHEMA(child, "element")) { 11261 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11262 schema, child, &isElemRef, 0); 11263 /* 11264 * SPEC cos-all-limited (2) 11265 * "The {max occurs} of all the particles in the {particles} 11266 * of the ('all') group must be 0 or 1. 11267 */ 11268 if (part != NULL) { 11269 if (isElemRef) 11270 hasRefs++; 11271 if (part->minOccurs > 1) { 11272 xmlSchemaPCustomErr(ctxt, 11273 XML_SCHEMAP_COS_ALL_LIMITED, 11274 NULL, child, 11275 "Invalid value for minOccurs (must be 0 or 1)", 11276 NULL); 11277 /* Reset to 1. */ 11278 part->minOccurs = 1; 11279 } 11280 if (part->maxOccurs > 1) { 11281 xmlSchemaPCustomErr(ctxt, 11282 XML_SCHEMAP_COS_ALL_LIMITED, 11283 NULL, child, 11284 "Invalid value for maxOccurs (must be 0 or 1)", 11285 NULL); 11286 /* Reset to 1. */ 11287 part->maxOccurs = 1; 11288 } 11289 if (last == NULL) 11290 item->children = (xmlSchemaTreeItemPtr) part; 11291 else 11292 last->next = (xmlSchemaTreeItemPtr) part; 11293 last = part; 11294 } 11295 child = child->next; 11296 } 11297 if (child != NULL) { 11298 xmlSchemaPContentErr(ctxt, 11299 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11300 NULL, node, child, NULL, 11301 "(annotation?, (annotation?, element*)"); 11302 } 11303 } else { 11304 /* choice + sequence */ 11305 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11306 11307 while ((IS_SCHEMA(child, "element")) || 11308 (IS_SCHEMA(child, "group")) || 11309 (IS_SCHEMA(child, "any")) || 11310 (IS_SCHEMA(child, "choice")) || 11311 (IS_SCHEMA(child, "sequence"))) { 11312 11313 if (IS_SCHEMA(child, "element")) { 11314 part = (xmlSchemaTreeItemPtr) 11315 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11316 if (part && isElemRef) 11317 hasRefs++; 11318 } else if (IS_SCHEMA(child, "group")) { 11319 part = 11320 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11321 if (part != NULL) 11322 hasRefs++; 11323 /* 11324 * Handle redefinitions. 11325 */ 11326 if (ctxt->isRedefine && ctxt->redef && 11327 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11328 part && part->children) 11329 { 11330 if ((xmlSchemaGetQNameRefName(part->children) == 11331 ctxt->redef->refName) && 11332 (xmlSchemaGetQNameRefTargetNs(part->children) == 11333 ctxt->redef->refTargetNs)) 11334 { 11335 /* 11336 * SPEC src-redefine: 11337 * (6.1) "If it has a <group> among its contents at 11338 * some level the �actual value� of whose ref 11339 * [attribute] is the same as the �actual value� of 11340 * its own name attribute plus target namespace, then 11341 * all of the following must be true:" 11342 * (6.1.1) "It must have exactly one such group." 11343 */ 11344 if (ctxt->redefCounter != 0) { 11345 xmlChar *str = NULL; 11346 11347 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11348 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11349 "The redefining model group definition " 11350 "'%s' must not contain more than one " 11351 "reference to the redefined definition", 11352 xmlSchemaFormatQName(&str, 11353 ctxt->redef->refTargetNs, 11354 ctxt->redef->refName), 11355 NULL); 11356 FREE_AND_NULL(str) 11357 part = NULL; 11358 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11359 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11360 { 11361 xmlChar *str = NULL; 11362 /* 11363 * SPEC src-redefine: 11364 * (6.1.2) "The �actual value� of both that 11365 * group's minOccurs and maxOccurs [attribute] 11366 * must be 1 (or �absent�). 11367 */ 11368 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11369 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11370 "The redefining model group definition " 11371 "'%s' must not contain a reference to the " 11372 "redefined definition with a " 11373 "maxOccurs/minOccurs other than 1", 11374 xmlSchemaFormatQName(&str, 11375 ctxt->redef->refTargetNs, 11376 ctxt->redef->refName), 11377 NULL); 11378 FREE_AND_NULL(str) 11379 part = NULL; 11380 } 11381 ctxt->redef->reference = WXS_BASIC_CAST part; 11382 ctxt->redefCounter++; 11383 } 11384 } 11385 } else if (IS_SCHEMA(child, "any")) { 11386 part = (xmlSchemaTreeItemPtr) 11387 xmlSchemaParseAny(ctxt, schema, child); 11388 } else if (IS_SCHEMA(child, "choice")) { 11389 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11390 XML_SCHEMA_TYPE_CHOICE, 1); 11391 } else if (IS_SCHEMA(child, "sequence")) { 11392 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11393 XML_SCHEMA_TYPE_SEQUENCE, 1); 11394 } 11395 if (part != NULL) { 11396 if (last == NULL) 11397 item->children = part; 11398 else 11399 last->next = part; 11400 last = part; 11401 } 11402 child = child->next; 11403 } 11404 if (child != NULL) { 11405 xmlSchemaPContentErr(ctxt, 11406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11407 NULL, node, child, NULL, 11408 "(annotation?, (element | group | choice | sequence | any)*)"); 11409 } 11410 } 11411 if ((max == 0) && (min == 0)) 11412 return (NULL); 11413 if (hasRefs) { 11414 /* 11415 * We need to resolve references. 11416 */ 11417 WXS_ADD_PENDING(ctxt, item); 11418 } 11419 if (withParticle) 11420 return ((xmlSchemaTreeItemPtr) particle); 11421 else 11422 return ((xmlSchemaTreeItemPtr) item); 11423} 11424 11425/** 11426 * xmlSchemaParseRestriction: 11427 * @ctxt: a schema validation context 11428 * @schema: the schema being built 11429 * @node: a subtree containing XML Schema informations 11430 * 11431 * parse a XML schema Restriction definition 11432 * *WARNING* this interface is highly subject to change 11433 * 11434 * Returns the type definition or NULL in case of error 11435 */ 11436static xmlSchemaTypePtr 11437xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11438 xmlNodePtr node, xmlSchemaTypeType parentType) 11439{ 11440 xmlSchemaTypePtr type; 11441 xmlNodePtr child = NULL; 11442 xmlAttrPtr attr; 11443 11444 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11445 return (NULL); 11446 /* Not a component, don't create it. */ 11447 type = ctxt->ctxtType; 11448 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11449 11450 /* 11451 * Check for illegal attributes. 11452 */ 11453 attr = node->properties; 11454 while (attr != NULL) { 11455 if (attr->ns == NULL) { 11456 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11457 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11458 xmlSchemaPIllegalAttrErr(ctxt, 11459 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11460 } 11461 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11462 xmlSchemaPIllegalAttrErr(ctxt, 11463 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11464 } 11465 attr = attr->next; 11466 } 11467 /* 11468 * Extract and validate attributes. 11469 */ 11470 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11471 /* 11472 * Attribute 11473 */ 11474 /* 11475 * Extract the base type. The "base" attribute is mandatory if inside 11476 * a complex type or if redefining. 11477 * 11478 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11479 * among its [children]), the simple type definition which is 11480 * the {content type} of the type definition �resolved� to by 11481 * the �actual value� of the base [attribute]" 11482 */ 11483 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11484 &(type->baseNs), &(type->base)) == 0) 11485 { 11486 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11487 xmlSchemaPMissingAttrErr(ctxt, 11488 XML_SCHEMAP_S4S_ATTR_MISSING, 11489 NULL, node, "base", NULL); 11490 } else if ((ctxt->isRedefine) && 11491 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11492 { 11493 if (type->base == NULL) { 11494 xmlSchemaPMissingAttrErr(ctxt, 11495 XML_SCHEMAP_S4S_ATTR_MISSING, 11496 NULL, node, "base", NULL); 11497 } else if ((! xmlStrEqual(type->base, type->name)) || 11498 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11499 { 11500 xmlChar *str1 = NULL, *str2 = NULL; 11501 /* 11502 * REDEFINE: SPEC src-redefine (5) 11503 * "Within the [children], each <simpleType> must have a 11504 * <restriction> among its [children] ... the �actual value� of 11505 * whose base [attribute] must be the same as the �actual value� 11506 * of its own name attribute plus target namespace;" 11507 */ 11508 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11509 NULL, node, "This is a redefinition, but the QName " 11510 "value '%s' of the 'base' attribute does not match the " 11511 "type's designation '%s'", 11512 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11513 xmlSchemaFormatQName(&str2, type->targetNamespace, 11514 type->name), NULL); 11515 FREE_AND_NULL(str1); 11516 FREE_AND_NULL(str2); 11517 /* Avoid confusion and erase the values. */ 11518 type->base = NULL; 11519 type->baseNs = NULL; 11520 } 11521 } 11522 } 11523 /* 11524 * And now for the children... 11525 */ 11526 child = node->children; 11527 if (IS_SCHEMA(child, "annotation")) { 11528 /* 11529 * Add the annotation to the simple type ancestor. 11530 */ 11531 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11532 xmlSchemaParseAnnotation(ctxt, child, 1)); 11533 child = child->next; 11534 } 11535 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11536 /* 11537 * Corresponds to <simpleType><restriction><simpleType>. 11538 */ 11539 if (IS_SCHEMA(child, "simpleType")) { 11540 if (type->base != NULL) { 11541 /* 11542 * src-restriction-base-or-simpleType 11543 * Either the base [attribute] or the simpleType [child] of the 11544 * <restriction> element must be present, but not both. 11545 */ 11546 xmlSchemaPContentErr(ctxt, 11547 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11548 NULL, node, child, 11549 "The attribute 'base' and the <simpleType> child are " 11550 "mutually exclusive", NULL); 11551 } else { 11552 type->baseType = (xmlSchemaTypePtr) 11553 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11554 } 11555 child = child->next; 11556 } else if (type->base == NULL) { 11557 xmlSchemaPContentErr(ctxt, 11558 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11559 NULL, node, child, 11560 "Either the attribute 'base' or a <simpleType> child " 11561 "must be present", NULL); 11562 } 11563 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11564 /* 11565 * Corresponds to <complexType><complexContent><restriction>... 11566 * followed by: 11567 * 11568 * Model groups <all>, <choice> and <sequence>. 11569 */ 11570 if (IS_SCHEMA(child, "all")) { 11571 type->subtypes = (xmlSchemaTypePtr) 11572 xmlSchemaParseModelGroup(ctxt, schema, child, 11573 XML_SCHEMA_TYPE_ALL, 1); 11574 child = child->next; 11575 } else if (IS_SCHEMA(child, "choice")) { 11576 type->subtypes = (xmlSchemaTypePtr) 11577 xmlSchemaParseModelGroup(ctxt, 11578 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11579 child = child->next; 11580 } else if (IS_SCHEMA(child, "sequence")) { 11581 type->subtypes = (xmlSchemaTypePtr) 11582 xmlSchemaParseModelGroup(ctxt, schema, child, 11583 XML_SCHEMA_TYPE_SEQUENCE, 1); 11584 child = child->next; 11585 /* 11586 * Model group reference <group>. 11587 */ 11588 } else if (IS_SCHEMA(child, "group")) { 11589 type->subtypes = (xmlSchemaTypePtr) 11590 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11591 /* 11592 * Note that the reference will be resolved in 11593 * xmlSchemaResolveTypeReferences(); 11594 */ 11595 child = child->next; 11596 } 11597 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11598 /* 11599 * Corresponds to <complexType><simpleContent><restriction>... 11600 * 11601 * "1.1 the simple type definition corresponding to the <simpleType> 11602 * among the [children] of <restriction> if there is one;" 11603 */ 11604 if (IS_SCHEMA(child, "simpleType")) { 11605 /* 11606 * We will store the to-be-restricted simple type in 11607 * type->contentTypeDef *temporarily*. 11608 */ 11609 type->contentTypeDef = (xmlSchemaTypePtr) 11610 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11611 if ( type->contentTypeDef == NULL) 11612 return (NULL); 11613 child = child->next; 11614 } 11615 } 11616 11617 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11618 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11619 xmlSchemaFacetPtr facet, lastfacet = NULL; 11620 /* 11621 * Corresponds to <complexType><simpleContent><restriction>... 11622 * <simpleType><restriction>... 11623 */ 11624 11625 /* 11626 * Add the facets to the simple type ancestor. 11627 */ 11628 /* 11629 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11630 * Simple Type Definition Schema Representation Constraint: 11631 * *Single Facet Value* 11632 */ 11633 while ((IS_SCHEMA(child, "minInclusive")) || 11634 (IS_SCHEMA(child, "minExclusive")) || 11635 (IS_SCHEMA(child, "maxInclusive")) || 11636 (IS_SCHEMA(child, "maxExclusive")) || 11637 (IS_SCHEMA(child, "totalDigits")) || 11638 (IS_SCHEMA(child, "fractionDigits")) || 11639 (IS_SCHEMA(child, "pattern")) || 11640 (IS_SCHEMA(child, "enumeration")) || 11641 (IS_SCHEMA(child, "whiteSpace")) || 11642 (IS_SCHEMA(child, "length")) || 11643 (IS_SCHEMA(child, "maxLength")) || 11644 (IS_SCHEMA(child, "minLength"))) { 11645 facet = xmlSchemaParseFacet(ctxt, schema, child); 11646 if (facet != NULL) { 11647 if (lastfacet == NULL) 11648 type->facets = facet; 11649 else 11650 lastfacet->next = facet; 11651 lastfacet = facet; 11652 lastfacet->next = NULL; 11653 } 11654 child = child->next; 11655 } 11656 /* 11657 * Create links for derivation and validation. 11658 */ 11659 if (type->facets != NULL) { 11660 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11661 11662 facet = type->facets; 11663 do { 11664 facetLink = (xmlSchemaFacetLinkPtr) 11665 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11666 if (facetLink == NULL) { 11667 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11668 xmlFree(facetLink); 11669 return (NULL); 11670 } 11671 facetLink->facet = facet; 11672 facetLink->next = NULL; 11673 if (lastFacetLink == NULL) 11674 type->facetSet = facetLink; 11675 else 11676 lastFacetLink->next = facetLink; 11677 lastFacetLink = facetLink; 11678 facet = facet->next; 11679 } while (facet != NULL); 11680 } 11681 } 11682 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11683 /* 11684 * Attribute uses/declarations. 11685 */ 11686 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11687 (xmlSchemaItemListPtr *) &(type->attrUses), 11688 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11689 return(NULL); 11690 /* 11691 * Attribute wildcard. 11692 */ 11693 if (IS_SCHEMA(child, "anyAttribute")) { 11694 type->attributeWildcard = 11695 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11696 child = child->next; 11697 } 11698 } 11699 if (child != NULL) { 11700 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11701 xmlSchemaPContentErr(ctxt, 11702 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11703 NULL, node, child, NULL, 11704 "annotation?, (group | all | choice | sequence)?, " 11705 "((attribute | attributeGroup)*, anyAttribute?))"); 11706 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11707 xmlSchemaPContentErr(ctxt, 11708 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11709 NULL, node, child, NULL, 11710 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11711 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11712 "length | minLength | maxLength | enumeration | whiteSpace | " 11713 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11714 } else { 11715 /* Simple type */ 11716 xmlSchemaPContentErr(ctxt, 11717 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11718 NULL, node, child, NULL, 11719 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11720 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11721 "length | minLength | maxLength | enumeration | whiteSpace | " 11722 "pattern)*))"); 11723 } 11724 } 11725 return (NULL); 11726} 11727 11728/** 11729 * xmlSchemaParseExtension: 11730 * @ctxt: a schema validation context 11731 * @schema: the schema being built 11732 * @node: a subtree containing XML Schema informations 11733 * 11734 * Parses an <extension>, which is found inside a 11735 * <simpleContent> or <complexContent>. 11736 * *WARNING* this interface is highly subject to change. 11737 * 11738 * TODO: Returns the type definition or NULL in case of error 11739 */ 11740static xmlSchemaTypePtr 11741xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11742 xmlNodePtr node, xmlSchemaTypeType parentType) 11743{ 11744 xmlSchemaTypePtr type; 11745 xmlNodePtr child = NULL; 11746 xmlAttrPtr attr; 11747 11748 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11749 return (NULL); 11750 /* Not a component, don't create it. */ 11751 type = ctxt->ctxtType; 11752 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11753 11754 /* 11755 * Check for illegal attributes. 11756 */ 11757 attr = node->properties; 11758 while (attr != NULL) { 11759 if (attr->ns == NULL) { 11760 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11761 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11762 xmlSchemaPIllegalAttrErr(ctxt, 11763 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11764 } 11765 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11766 xmlSchemaPIllegalAttrErr(ctxt, 11767 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11768 } 11769 attr = attr->next; 11770 } 11771 11772 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11773 11774 /* 11775 * Attribute "base" - mandatory. 11776 */ 11777 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11778 "base", &(type->baseNs), &(type->base)) == 0) && 11779 (type->base == NULL)) { 11780 xmlSchemaPMissingAttrErr(ctxt, 11781 XML_SCHEMAP_S4S_ATTR_MISSING, 11782 NULL, node, "base", NULL); 11783 } 11784 /* 11785 * And now for the children... 11786 */ 11787 child = node->children; 11788 if (IS_SCHEMA(child, "annotation")) { 11789 /* 11790 * Add the annotation to the type ancestor. 11791 */ 11792 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11793 xmlSchemaParseAnnotation(ctxt, child, 1)); 11794 child = child->next; 11795 } 11796 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11797 /* 11798 * Corresponds to <complexType><complexContent><extension>... and: 11799 * 11800 * Model groups <all>, <choice>, <sequence> and <group>. 11801 */ 11802 if (IS_SCHEMA(child, "all")) { 11803 type->subtypes = (xmlSchemaTypePtr) 11804 xmlSchemaParseModelGroup(ctxt, schema, 11805 child, XML_SCHEMA_TYPE_ALL, 1); 11806 child = child->next; 11807 } else if (IS_SCHEMA(child, "choice")) { 11808 type->subtypes = (xmlSchemaTypePtr) 11809 xmlSchemaParseModelGroup(ctxt, schema, 11810 child, XML_SCHEMA_TYPE_CHOICE, 1); 11811 child = child->next; 11812 } else if (IS_SCHEMA(child, "sequence")) { 11813 type->subtypes = (xmlSchemaTypePtr) 11814 xmlSchemaParseModelGroup(ctxt, schema, 11815 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11816 child = child->next; 11817 } else if (IS_SCHEMA(child, "group")) { 11818 type->subtypes = (xmlSchemaTypePtr) 11819 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11820 /* 11821 * Note that the reference will be resolved in 11822 * xmlSchemaResolveTypeReferences(); 11823 */ 11824 child = child->next; 11825 } 11826 } 11827 if (child != NULL) { 11828 /* 11829 * Attribute uses/declarations. 11830 */ 11831 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11832 (xmlSchemaItemListPtr *) &(type->attrUses), 11833 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11834 return(NULL); 11835 /* 11836 * Attribute wildcard. 11837 */ 11838 if (IS_SCHEMA(child, "anyAttribute")) { 11839 ctxt->ctxtType->attributeWildcard = 11840 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11841 child = child->next; 11842 } 11843 } 11844 if (child != NULL) { 11845 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11846 /* Complex content extension. */ 11847 xmlSchemaPContentErr(ctxt, 11848 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11849 NULL, node, child, NULL, 11850 "(annotation?, ((group | all | choice | sequence)?, " 11851 "((attribute | attributeGroup)*, anyAttribute?)))"); 11852 } else { 11853 /* Simple content extension. */ 11854 xmlSchemaPContentErr(ctxt, 11855 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11856 NULL, node, child, NULL, 11857 "(annotation?, ((attribute | attributeGroup)*, " 11858 "anyAttribute?))"); 11859 } 11860 } 11861 return (NULL); 11862} 11863 11864/** 11865 * xmlSchemaParseSimpleContent: 11866 * @ctxt: a schema validation context 11867 * @schema: the schema being built 11868 * @node: a subtree containing XML Schema informations 11869 * 11870 * parse a XML schema SimpleContent definition 11871 * *WARNING* this interface is highly subject to change 11872 * 11873 * Returns the type definition or NULL in case of error 11874 */ 11875static int 11876xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11877 xmlSchemaPtr schema, xmlNodePtr node, 11878 int *hasRestrictionOrExtension) 11879{ 11880 xmlSchemaTypePtr type; 11881 xmlNodePtr child = NULL; 11882 xmlAttrPtr attr; 11883 11884 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11885 (hasRestrictionOrExtension == NULL)) 11886 return (-1); 11887 *hasRestrictionOrExtension = 0; 11888 /* Not a component, don't create it. */ 11889 type = ctxt->ctxtType; 11890 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11891 /* 11892 * Check for illegal attributes. 11893 */ 11894 attr = node->properties; 11895 while (attr != NULL) { 11896 if (attr->ns == NULL) { 11897 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11898 xmlSchemaPIllegalAttrErr(ctxt, 11899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11900 } 11901 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11902 xmlSchemaPIllegalAttrErr(ctxt, 11903 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11904 } 11905 attr = attr->next; 11906 } 11907 11908 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11909 11910 /* 11911 * And now for the children... 11912 */ 11913 child = node->children; 11914 if (IS_SCHEMA(child, "annotation")) { 11915 /* 11916 * Add the annotation to the complex type ancestor. 11917 */ 11918 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11919 xmlSchemaParseAnnotation(ctxt, child, 1)); 11920 child = child->next; 11921 } 11922 if (child == NULL) { 11923 xmlSchemaPContentErr(ctxt, 11924 XML_SCHEMAP_S4S_ELEM_MISSING, 11925 NULL, node, NULL, NULL, 11926 "(annotation?, (restriction | extension))"); 11927 } 11928 if (child == NULL) { 11929 xmlSchemaPContentErr(ctxt, 11930 XML_SCHEMAP_S4S_ELEM_MISSING, 11931 NULL, node, NULL, NULL, 11932 "(annotation?, (restriction | extension))"); 11933 } 11934 if (IS_SCHEMA(child, "restriction")) { 11935 xmlSchemaParseRestriction(ctxt, schema, child, 11936 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11937 (*hasRestrictionOrExtension) = 1; 11938 child = child->next; 11939 } else if (IS_SCHEMA(child, "extension")) { 11940 xmlSchemaParseExtension(ctxt, schema, child, 11941 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11942 (*hasRestrictionOrExtension) = 1; 11943 child = child->next; 11944 } 11945 if (child != NULL) { 11946 xmlSchemaPContentErr(ctxt, 11947 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11948 NULL, node, child, NULL, 11949 "(annotation?, (restriction | extension))"); 11950 } 11951 return (0); 11952} 11953 11954/** 11955 * xmlSchemaParseComplexContent: 11956 * @ctxt: a schema validation context 11957 * @schema: the schema being built 11958 * @node: a subtree containing XML Schema informations 11959 * 11960 * parse a XML schema ComplexContent definition 11961 * *WARNING* this interface is highly subject to change 11962 * 11963 * Returns the type definition or NULL in case of error 11964 */ 11965static int 11966xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 11967 xmlSchemaPtr schema, xmlNodePtr node, 11968 int *hasRestrictionOrExtension) 11969{ 11970 xmlSchemaTypePtr type; 11971 xmlNodePtr child = NULL; 11972 xmlAttrPtr attr; 11973 11974 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11975 (hasRestrictionOrExtension == NULL)) 11976 return (-1); 11977 *hasRestrictionOrExtension = 0; 11978 /* Not a component, don't create it. */ 11979 type = ctxt->ctxtType; 11980 /* 11981 * Check for illegal attributes. 11982 */ 11983 attr = node->properties; 11984 while (attr != NULL) { 11985 if (attr->ns == NULL) { 11986 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11987 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 11988 { 11989 xmlSchemaPIllegalAttrErr(ctxt, 11990 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11991 } 11992 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11993 xmlSchemaPIllegalAttrErr(ctxt, 11994 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11995 } 11996 attr = attr->next; 11997 } 11998 11999 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12000 12001 /* 12002 * Set the 'mixed' on the complex type ancestor. 12003 */ 12004 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12005 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12006 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12007 } 12008 child = node->children; 12009 if (IS_SCHEMA(child, "annotation")) { 12010 /* 12011 * Add the annotation to the complex type ancestor. 12012 */ 12013 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12014 xmlSchemaParseAnnotation(ctxt, child, 1)); 12015 child = child->next; 12016 } 12017 if (child == NULL) { 12018 xmlSchemaPContentErr(ctxt, 12019 XML_SCHEMAP_S4S_ELEM_MISSING, 12020 NULL, node, NULL, 12021 NULL, "(annotation?, (restriction | extension))"); 12022 } 12023 if (child == NULL) { 12024 xmlSchemaPContentErr(ctxt, 12025 XML_SCHEMAP_S4S_ELEM_MISSING, 12026 NULL, node, NULL, 12027 NULL, "(annotation?, (restriction | extension))"); 12028 } 12029 if (IS_SCHEMA(child, "restriction")) { 12030 xmlSchemaParseRestriction(ctxt, schema, child, 12031 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12032 (*hasRestrictionOrExtension) = 1; 12033 child = child->next; 12034 } else if (IS_SCHEMA(child, "extension")) { 12035 xmlSchemaParseExtension(ctxt, schema, child, 12036 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12037 (*hasRestrictionOrExtension) = 1; 12038 child = child->next; 12039 } 12040 if (child != NULL) { 12041 xmlSchemaPContentErr(ctxt, 12042 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12043 NULL, node, child, 12044 NULL, "(annotation?, (restriction | extension))"); 12045 } 12046 return (0); 12047} 12048 12049/** 12050 * xmlSchemaParseComplexType: 12051 * @ctxt: a schema validation context 12052 * @schema: the schema being built 12053 * @node: a subtree containing XML Schema informations 12054 * 12055 * parse a XML schema Complex Type definition 12056 * *WARNING* this interface is highly subject to change 12057 * 12058 * Returns the type definition or NULL in case of error 12059 */ 12060static xmlSchemaTypePtr 12061xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12062 xmlNodePtr node, int topLevel) 12063{ 12064 xmlSchemaTypePtr type, ctxtType; 12065 xmlNodePtr child = NULL; 12066 const xmlChar *name = NULL; 12067 xmlAttrPtr attr; 12068 const xmlChar *attrValue; 12069#ifdef ENABLE_NAMED_LOCALS 12070 char buf[40]; 12071#endif 12072 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12073 12074 12075 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12076 return (NULL); 12077 12078 ctxtType = ctxt->ctxtType; 12079 12080 if (topLevel) { 12081 attr = xmlSchemaGetPropNode(node, "name"); 12082 if (attr == NULL) { 12083 xmlSchemaPMissingAttrErr(ctxt, 12084 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12085 return (NULL); 12086 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12087 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12088 return (NULL); 12089 } 12090 } 12091 12092 if (topLevel == 0) { 12093 /* 12094 * Parse as local complex type definition. 12095 */ 12096#ifdef ENABLE_NAMED_LOCALS 12097 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12098 type = xmlSchemaAddType(ctxt, schema, 12099 XML_SCHEMA_TYPE_COMPLEX, 12100 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12101 ctxt->targetNamespace, node, 0); 12102#else 12103 type = xmlSchemaAddType(ctxt, schema, 12104 XML_SCHEMA_TYPE_COMPLEX, 12105 NULL, ctxt->targetNamespace, node, 0); 12106#endif 12107 if (type == NULL) 12108 return (NULL); 12109 name = type->name; 12110 type->node = node; 12111 type->type = XML_SCHEMA_TYPE_COMPLEX; 12112 /* 12113 * TODO: We need the target namespace. 12114 */ 12115 } else { 12116 /* 12117 * Parse as global complex type definition. 12118 */ 12119 type = xmlSchemaAddType(ctxt, schema, 12120 XML_SCHEMA_TYPE_COMPLEX, 12121 name, ctxt->targetNamespace, node, 1); 12122 if (type == NULL) 12123 return (NULL); 12124 type->node = node; 12125 type->type = XML_SCHEMA_TYPE_COMPLEX; 12126 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12127 } 12128 type->targetNamespace = ctxt->targetNamespace; 12129 /* 12130 * Handle attributes. 12131 */ 12132 attr = node->properties; 12133 while (attr != NULL) { 12134 if (attr->ns == NULL) { 12135 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12136 /* 12137 * Attribute "id". 12138 */ 12139 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12140 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12141 /* 12142 * Attribute "mixed". 12143 */ 12144 if (xmlSchemaPGetBoolNodeValue(ctxt, 12145 NULL, (xmlNodePtr) attr)) 12146 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12147 } else if (topLevel) { 12148 /* 12149 * Attributes of global complex type definitions. 12150 */ 12151 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12152 /* Pass. */ 12153 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12154 /* 12155 * Attribute "abstract". 12156 */ 12157 if (xmlSchemaPGetBoolNodeValue(ctxt, 12158 NULL, (xmlNodePtr) attr)) 12159 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12160 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12161 /* 12162 * Attribute "final". 12163 */ 12164 attrValue = xmlSchemaGetNodeContent(ctxt, 12165 (xmlNodePtr) attr); 12166 if (xmlSchemaPValAttrBlockFinal(attrValue, 12167 &(type->flags), 12168 -1, 12169 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12170 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12171 -1, -1, -1) != 0) 12172 { 12173 xmlSchemaPSimpleTypeErr(ctxt, 12174 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12175 NULL, (xmlNodePtr) attr, NULL, 12176 "(#all | List of (extension | restriction))", 12177 attrValue, NULL, NULL, NULL); 12178 } else 12179 final = 1; 12180 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12181 /* 12182 * Attribute "block". 12183 */ 12184 attrValue = xmlSchemaGetNodeContent(ctxt, 12185 (xmlNodePtr) attr); 12186 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12187 -1, 12188 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12189 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12190 -1, -1, -1) != 0) { 12191 xmlSchemaPSimpleTypeErr(ctxt, 12192 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12193 NULL, (xmlNodePtr) attr, NULL, 12194 "(#all | List of (extension | restriction)) ", 12195 attrValue, NULL, NULL, NULL); 12196 } else 12197 block = 1; 12198 } else { 12199 xmlSchemaPIllegalAttrErr(ctxt, 12200 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12201 } 12202 } else { 12203 xmlSchemaPIllegalAttrErr(ctxt, 12204 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12205 } 12206 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12207 xmlSchemaPIllegalAttrErr(ctxt, 12208 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12209 } 12210 attr = attr->next; 12211 } 12212 if (! block) { 12213 /* 12214 * Apply default "block" values. 12215 */ 12216 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12217 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12218 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12219 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12220 } 12221 if (! final) { 12222 /* 12223 * Apply default "block" values. 12224 */ 12225 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12226 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12227 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12228 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12229 } 12230 /* 12231 * And now for the children... 12232 */ 12233 child = node->children; 12234 if (IS_SCHEMA(child, "annotation")) { 12235 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12236 child = child->next; 12237 } 12238 ctxt->ctxtType = type; 12239 if (IS_SCHEMA(child, "simpleContent")) { 12240 /* 12241 * <complexType><simpleContent>... 12242 * 3.4.3 : 2.2 12243 * Specifying mixed='true' when the <simpleContent> 12244 * alternative is chosen has no effect 12245 */ 12246 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12247 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12248 xmlSchemaParseSimpleContent(ctxt, schema, child, 12249 &hasRestrictionOrExtension); 12250 child = child->next; 12251 } else if (IS_SCHEMA(child, "complexContent")) { 12252 /* 12253 * <complexType><complexContent>... 12254 */ 12255 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12256 xmlSchemaParseComplexContent(ctxt, schema, child, 12257 &hasRestrictionOrExtension); 12258 child = child->next; 12259 } else { 12260 /* 12261 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12262 * 12263 * SPEC 12264 * "...the third alternative (neither <simpleContent> nor 12265 * <complexContent>) is chosen. This case is understood as shorthand 12266 * for complex content restricting the �ur-type definition�, and the 12267 * details of the mappings should be modified as necessary. 12268 */ 12269 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12270 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12271 /* 12272 * Parse model groups. 12273 */ 12274 if (IS_SCHEMA(child, "all")) { 12275 type->subtypes = (xmlSchemaTypePtr) 12276 xmlSchemaParseModelGroup(ctxt, schema, child, 12277 XML_SCHEMA_TYPE_ALL, 1); 12278 child = child->next; 12279 } else if (IS_SCHEMA(child, "choice")) { 12280 type->subtypes = (xmlSchemaTypePtr) 12281 xmlSchemaParseModelGroup(ctxt, schema, child, 12282 XML_SCHEMA_TYPE_CHOICE, 1); 12283 child = child->next; 12284 } else if (IS_SCHEMA(child, "sequence")) { 12285 type->subtypes = (xmlSchemaTypePtr) 12286 xmlSchemaParseModelGroup(ctxt, schema, child, 12287 XML_SCHEMA_TYPE_SEQUENCE, 1); 12288 child = child->next; 12289 } else if (IS_SCHEMA(child, "group")) { 12290 type->subtypes = (xmlSchemaTypePtr) 12291 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12292 /* 12293 * Note that the reference will be resolved in 12294 * xmlSchemaResolveTypeReferences(); 12295 */ 12296 child = child->next; 12297 } 12298 /* 12299 * Parse attribute decls/refs. 12300 */ 12301 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12302 (xmlSchemaItemListPtr *) &(type->attrUses), 12303 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12304 return(NULL); 12305 /* 12306 * Parse attribute wildcard. 12307 */ 12308 if (IS_SCHEMA(child, "anyAttribute")) { 12309 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12310 child = child->next; 12311 } 12312 } 12313 if (child != NULL) { 12314 xmlSchemaPContentErr(ctxt, 12315 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12316 NULL, node, child, 12317 NULL, "(annotation?, (simpleContent | complexContent | " 12318 "((group | all | choice | sequence)?, ((attribute | " 12319 "attributeGroup)*, anyAttribute?))))"); 12320 } 12321 /* 12322 * REDEFINE: SPEC src-redefine (5) 12323 */ 12324 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12325 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12326 NULL, node, "This is a redefinition, thus the " 12327 "<complexType> must have a <restriction> or <extension> " 12328 "grand-child", NULL); 12329 } 12330 ctxt->ctxtType = ctxtType; 12331 return (type); 12332} 12333 12334/************************************************************************ 12335 * * 12336 * Validating using Schemas * 12337 * * 12338 ************************************************************************/ 12339 12340/************************************************************************ 12341 * * 12342 * Reading/Writing Schemas * 12343 * * 12344 ************************************************************************/ 12345 12346#if 0 /* Will be enabled if it is clear what options are needed. */ 12347/** 12348 * xmlSchemaParserCtxtSetOptions: 12349 * @ctxt: a schema parser context 12350 * @options: a combination of xmlSchemaParserOption 12351 * 12352 * Sets the options to be used during the parse. 12353 * 12354 * Returns 0 in case of success, -1 in case of an 12355 * API error. 12356 */ 12357static int 12358xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12359 int options) 12360 12361{ 12362 int i; 12363 12364 if (ctxt == NULL) 12365 return (-1); 12366 /* 12367 * WARNING: Change the start value if adding to the 12368 * xmlSchemaParseOption. 12369 */ 12370 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12371 if (options & 1<<i) { 12372 return (-1); 12373 } 12374 } 12375 ctxt->options = options; 12376 return (0); 12377} 12378 12379/** 12380 * xmlSchemaValidCtxtGetOptions: 12381 * @ctxt: a schema parser context 12382 * 12383 * Returns the option combination of the parser context. 12384 */ 12385static int 12386xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12387 12388{ 12389 if (ctxt == NULL) 12390 return (-1); 12391 else 12392 return (ctxt->options); 12393} 12394#endif 12395 12396/** 12397 * xmlSchemaNewParserCtxt: 12398 * @URL: the location of the schema 12399 * 12400 * Create an XML Schemas parse context for that file/resource expected 12401 * to contain an XML Schemas file. 12402 * 12403 * Returns the parser context or NULL in case of error 12404 */ 12405xmlSchemaParserCtxtPtr 12406xmlSchemaNewParserCtxt(const char *URL) 12407{ 12408 xmlSchemaParserCtxtPtr ret; 12409 12410 if (URL == NULL) 12411 return (NULL); 12412 12413 ret = xmlSchemaParserCtxtCreate(); 12414 if (ret == NULL) 12415 return(NULL); 12416 ret->dict = xmlDictCreate(); 12417 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12418 return (ret); 12419} 12420 12421/** 12422 * xmlSchemaNewMemParserCtxt: 12423 * @buffer: a pointer to a char array containing the schemas 12424 * @size: the size of the array 12425 * 12426 * Create an XML Schemas parse context for that memory buffer expected 12427 * to contain an XML Schemas file. 12428 * 12429 * Returns the parser context or NULL in case of error 12430 */ 12431xmlSchemaParserCtxtPtr 12432xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12433{ 12434 xmlSchemaParserCtxtPtr ret; 12435 12436 if ((buffer == NULL) || (size <= 0)) 12437 return (NULL); 12438 ret = xmlSchemaParserCtxtCreate(); 12439 if (ret == NULL) 12440 return(NULL); 12441 ret->buffer = buffer; 12442 ret->size = size; 12443 ret->dict = xmlDictCreate(); 12444 return (ret); 12445} 12446 12447/** 12448 * xmlSchemaNewDocParserCtxt: 12449 * @doc: a preparsed document tree 12450 * 12451 * Create an XML Schemas parse context for that document. 12452 * NB. The document may be modified during the parsing process. 12453 * 12454 * Returns the parser context or NULL in case of error 12455 */ 12456xmlSchemaParserCtxtPtr 12457xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12458{ 12459 xmlSchemaParserCtxtPtr ret; 12460 12461 if (doc == NULL) 12462 return (NULL); 12463 ret = xmlSchemaParserCtxtCreate(); 12464 if (ret == NULL) 12465 return(NULL); 12466 ret->doc = doc; 12467 ret->dict = xmlDictCreate(); 12468 /* The application has responsibility for the document */ 12469 ret->preserve = 1; 12470 12471 return (ret); 12472} 12473 12474/** 12475 * xmlSchemaFreeParserCtxt: 12476 * @ctxt: the schema parser context 12477 * 12478 * Free the resources associated to the schema parser context 12479 */ 12480void 12481xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12482{ 12483 if (ctxt == NULL) 12484 return; 12485 if (ctxt->doc != NULL && !ctxt->preserve) 12486 xmlFreeDoc(ctxt->doc); 12487 if (ctxt->vctxt != NULL) { 12488 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12489 } 12490 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12491 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12492 ctxt->constructor = NULL; 12493 ctxt->ownsConstructor = 0; 12494 } 12495 if (ctxt->attrProhibs != NULL) 12496 xmlSchemaItemListFree(ctxt->attrProhibs); 12497 xmlDictFree(ctxt->dict); 12498 xmlFree(ctxt); 12499} 12500 12501/************************************************************************ 12502 * * 12503 * Building the content models * 12504 * * 12505 ************************************************************************/ 12506 12507static void 12508xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12509 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12510{ 12511 xmlAutomataStatePtr start, tmp; 12512 xmlSchemaElementPtr elemDecl, member; 12513 xmlSchemaSubstGroupPtr substGroup; 12514 int i; 12515 12516 elemDecl = (xmlSchemaElementPtr) particle->children; 12517 /* 12518 * Wrap the substitution group with a CHOICE. 12519 */ 12520 start = pctxt->state; 12521 if (end == NULL) 12522 end = xmlAutomataNewState(pctxt->am); 12523 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12524 if (substGroup == NULL) { 12525 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12526 XML_SCHEMAP_INTERNAL, 12527 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12528 "declaration is marked having a subst. group but none " 12529 "available.\n", elemDecl->name, NULL); 12530 return; 12531 } 12532 if (counter >= 0) { 12533 /* 12534 * NOTE that we put the declaration in, even if it's abstract. 12535 * However, an error will be raised during *validation* if an element 12536 * information item shall be validated against an abstract element 12537 * declaration. 12538 */ 12539 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12540 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12541 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12542 /* 12543 * Add subst. group members. 12544 */ 12545 for (i = 0; i < substGroup->members->nbItems; i++) { 12546 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12547 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12548 member->name, member->targetNamespace, member); 12549 } 12550 } else if (particle->maxOccurs == 1) { 12551 /* 12552 * NOTE that we put the declaration in, even if it's abstract, 12553 */ 12554 xmlAutomataNewEpsilon(pctxt->am, 12555 xmlAutomataNewTransition2(pctxt->am, 12556 start, NULL, 12557 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12558 /* 12559 * Add subst. group members. 12560 */ 12561 for (i = 0; i < substGroup->members->nbItems; i++) { 12562 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12563 /* 12564 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12565 * was incorrectly used instead of xmlAutomataNewTransition2() 12566 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12567 * section in xmlSchemaBuildAContentModel() ). 12568 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12569 * intended for the above "counter" section originally. I.e., 12570 * check xs:all with subst-groups. 12571 * 12572 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12573 * member->name, member->targetNamespace, 12574 * 1, 1, member); 12575 */ 12576 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12577 member->name, member->targetNamespace, member); 12578 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12579 } 12580 } else { 12581 xmlAutomataStatePtr hop; 12582 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12583 UNBOUNDED : particle->maxOccurs - 1; 12584 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12585 12586 counter = 12587 xmlAutomataNewCounter(pctxt->am, minOccurs, 12588 maxOccurs); 12589 hop = xmlAutomataNewState(pctxt->am); 12590 12591 xmlAutomataNewEpsilon(pctxt->am, 12592 xmlAutomataNewTransition2(pctxt->am, 12593 start, NULL, 12594 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12595 hop); 12596 /* 12597 * Add subst. group members. 12598 */ 12599 for (i = 0; i < substGroup->members->nbItems; i++) { 12600 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12601 xmlAutomataNewEpsilon(pctxt->am, 12602 xmlAutomataNewTransition2(pctxt->am, 12603 start, NULL, 12604 member->name, member->targetNamespace, member), 12605 hop); 12606 } 12607 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12608 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12609 } 12610 if (particle->minOccurs == 0) 12611 xmlAutomataNewEpsilon(pctxt->am, start, end); 12612 pctxt->state = end; 12613} 12614 12615static void 12616xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12617 xmlSchemaParticlePtr particle) 12618{ 12619 if (((xmlSchemaElementPtr) particle->children)->flags & 12620 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12621 /* 12622 * Substitution groups. 12623 */ 12624 xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12625 } else { 12626 xmlSchemaElementPtr elemDecl; 12627 xmlAutomataStatePtr start; 12628 12629 elemDecl = (xmlSchemaElementPtr) particle->children; 12630 12631 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12632 return; 12633 if (particle->maxOccurs == 1) { 12634 start = ctxt->state; 12635 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12636 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12637 } else if ((particle->maxOccurs >= UNBOUNDED) && 12638 (particle->minOccurs < 2)) { 12639 /* Special case. */ 12640 start = ctxt->state; 12641 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12642 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12643 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12644 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12645 } else { 12646 int counter; 12647 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12648 UNBOUNDED : particle->maxOccurs - 1; 12649 int minOccurs = particle->minOccurs < 1 ? 12650 0 : particle->minOccurs - 1; 12651 12652 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12653 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12654 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12655 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12656 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12657 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12658 NULL, counter); 12659 } 12660 if (particle->minOccurs == 0) 12661 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12662 } 12663} 12664 12665/** 12666 * xmlSchemaBuildAContentModel: 12667 * @ctxt: the schema parser context 12668 * @particle: the particle component 12669 * @name: the complex type's name whose content is being built 12670 * 12671 * Create the automaton for the {content type} of a complex type. 12672 * 12673 */ 12674static void 12675xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12676 xmlSchemaParticlePtr particle) 12677{ 12678 if (particle == NULL) { 12679 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12680 return; 12681 } 12682 if (particle->children == NULL) { 12683 /* 12684 * Just return in this case. A missing "term" of the particle 12685 * might arise due to an invalid "term" component. 12686 */ 12687 return; 12688 } 12689 12690 switch (particle->children->type) { 12691 case XML_SCHEMA_TYPE_ANY: { 12692 xmlAutomataStatePtr start, end; 12693 xmlSchemaWildcardPtr wild; 12694 xmlSchemaWildcardNsPtr ns; 12695 12696 wild = (xmlSchemaWildcardPtr) particle->children; 12697 12698 start = pctxt->state; 12699 end = xmlAutomataNewState(pctxt->am); 12700 12701 if (particle->maxOccurs == 1) { 12702 if (wild->any == 1) { 12703 /* 12704 * We need to add both transitions: 12705 * 12706 * 1. the {"*", "*"} for elements in a namespace. 12707 */ 12708 pctxt->state = 12709 xmlAutomataNewTransition2(pctxt->am, 12710 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12711 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12712 /* 12713 * 2. the {"*"} for elements in no namespace. 12714 */ 12715 pctxt->state = 12716 xmlAutomataNewTransition2(pctxt->am, 12717 start, NULL, BAD_CAST "*", NULL, wild); 12718 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12719 12720 } else if (wild->nsSet != NULL) { 12721 ns = wild->nsSet; 12722 do { 12723 pctxt->state = start; 12724 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12725 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12726 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12727 ns = ns->next; 12728 } while (ns != NULL); 12729 12730 } else if (wild->negNsSet != NULL) { 12731 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12732 start, end, BAD_CAST "*", wild->negNsSet->value, 12733 wild); 12734 } 12735 } else { 12736 int counter; 12737 xmlAutomataStatePtr hop; 12738 int maxOccurs = 12739 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1; 12740 int minOccurs = 12741 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12742 12743 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12744 hop = xmlAutomataNewState(pctxt->am); 12745 if (wild->any == 1) { 12746 pctxt->state = 12747 xmlAutomataNewTransition2(pctxt->am, 12748 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12749 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12750 pctxt->state = 12751 xmlAutomataNewTransition2(pctxt->am, 12752 start, NULL, BAD_CAST "*", NULL, wild); 12753 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12754 } else if (wild->nsSet != NULL) { 12755 ns = wild->nsSet; 12756 do { 12757 pctxt->state = 12758 xmlAutomataNewTransition2(pctxt->am, 12759 start, NULL, BAD_CAST "*", ns->value, wild); 12760 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12761 ns = ns->next; 12762 } while (ns != NULL); 12763 12764 } else if (wild->negNsSet != NULL) { 12765 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12766 start, hop, BAD_CAST "*", wild->negNsSet->value, 12767 wild); 12768 } 12769 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12770 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12771 } 12772 if (particle->minOccurs == 0) { 12773 xmlAutomataNewEpsilon(pctxt->am, start, end); 12774 } 12775 pctxt->state = end; 12776 break; 12777 } 12778 case XML_SCHEMA_TYPE_ELEMENT: 12779 xmlSchemaBuildContentModelForElement(pctxt, particle); 12780 break; 12781 case XML_SCHEMA_TYPE_SEQUENCE:{ 12782 xmlSchemaTreeItemPtr sub; 12783 12784 /* 12785 * If max and min occurances are default (1) then 12786 * simply iterate over the particles of the <sequence>. 12787 */ 12788 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12789 sub = particle->children->children; 12790 while (sub != NULL) { 12791 xmlSchemaBuildAContentModel(pctxt, 12792 (xmlSchemaParticlePtr) sub); 12793 sub = sub->next; 12794 } 12795 } else { 12796 xmlAutomataStatePtr oldstate = pctxt->state; 12797 12798 if (particle->maxOccurs >= UNBOUNDED) { 12799 if (particle->minOccurs > 1) { 12800 xmlAutomataStatePtr tmp; 12801 int counter; 12802 12803 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12804 oldstate, NULL); 12805 oldstate = pctxt->state; 12806 12807 counter = xmlAutomataNewCounter(pctxt->am, 12808 particle->minOccurs - 1, UNBOUNDED); 12809 12810 sub = particle->children->children; 12811 while (sub != NULL) { 12812 xmlSchemaBuildAContentModel(pctxt, 12813 (xmlSchemaParticlePtr) sub); 12814 sub = sub->next; 12815 } 12816 tmp = pctxt->state; 12817 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12818 oldstate, counter); 12819 pctxt->state = 12820 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12821 NULL, counter); 12822 12823 } else { 12824 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12825 oldstate, NULL); 12826 oldstate = pctxt->state; 12827 12828 sub = particle->children->children; 12829 while (sub != NULL) { 12830 xmlSchemaBuildAContentModel(pctxt, 12831 (xmlSchemaParticlePtr) sub); 12832 sub = sub->next; 12833 } 12834 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12835 oldstate); 12836 /* 12837 * epsilon needed to block previous trans from 12838 * being allowed to enter back from another 12839 * construct 12840 */ 12841 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12842 pctxt->state, NULL); 12843 if (particle->minOccurs == 0) { 12844 xmlAutomataNewEpsilon(pctxt->am, 12845 oldstate, pctxt->state); 12846 } 12847 } 12848 } else if ((particle->maxOccurs > 1) 12849 || (particle->minOccurs > 1)) { 12850 xmlAutomataStatePtr tmp; 12851 int counter; 12852 12853 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12854 oldstate, NULL); 12855 oldstate = pctxt->state; 12856 12857 counter = xmlAutomataNewCounter(pctxt->am, 12858 particle->minOccurs - 1, 12859 particle->maxOccurs - 1); 12860 12861 sub = particle->children->children; 12862 while (sub != NULL) { 12863 xmlSchemaBuildAContentModel(pctxt, 12864 (xmlSchemaParticlePtr) sub); 12865 sub = sub->next; 12866 } 12867 tmp = pctxt->state; 12868 xmlAutomataNewCountedTrans(pctxt->am, 12869 tmp, oldstate, counter); 12870 pctxt->state = 12871 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12872 counter); 12873 if (particle->minOccurs == 0) { 12874 xmlAutomataNewEpsilon(pctxt->am, 12875 oldstate, pctxt->state); 12876 } 12877 } else { 12878 sub = particle->children->children; 12879 while (sub != NULL) { 12880 xmlSchemaBuildAContentModel(pctxt, 12881 (xmlSchemaParticlePtr) sub); 12882 sub = sub->next; 12883 } 12884 if (particle->minOccurs == 0) { 12885 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12886 pctxt->state); 12887 } 12888 } 12889 } 12890 break; 12891 } 12892 case XML_SCHEMA_TYPE_CHOICE:{ 12893 xmlSchemaTreeItemPtr sub; 12894 xmlAutomataStatePtr start, end; 12895 12896 start = pctxt->state; 12897 end = xmlAutomataNewState(pctxt->am); 12898 12899 /* 12900 * iterate over the subtypes and remerge the end with an 12901 * epsilon transition 12902 */ 12903 if (particle->maxOccurs == 1) { 12904 sub = particle->children->children; 12905 while (sub != NULL) { 12906 pctxt->state = start; 12907 xmlSchemaBuildAContentModel(pctxt, 12908 (xmlSchemaParticlePtr) sub); 12909 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12910 sub = sub->next; 12911 } 12912 } else { 12913 int counter; 12914 xmlAutomataStatePtr hop, base; 12915 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12916 UNBOUNDED : particle->maxOccurs - 1; 12917 int minOccurs = 12918 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12919 12920 /* 12921 * use a counter to keep track of the number of transtions 12922 * which went through the choice. 12923 */ 12924 counter = 12925 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12926 hop = xmlAutomataNewState(pctxt->am); 12927 base = xmlAutomataNewState(pctxt->am); 12928 12929 sub = particle->children->children; 12930 while (sub != NULL) { 12931 pctxt->state = base; 12932 xmlSchemaBuildAContentModel(pctxt, 12933 (xmlSchemaParticlePtr) sub); 12934 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12935 sub = sub->next; 12936 } 12937 xmlAutomataNewEpsilon(pctxt->am, start, base); 12938 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 12939 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12940 } 12941 if (particle->minOccurs == 0) { 12942 xmlAutomataNewEpsilon(pctxt->am, start, end); 12943 } 12944 pctxt->state = end; 12945 break; 12946 } 12947 case XML_SCHEMA_TYPE_ALL:{ 12948 xmlAutomataStatePtr start; 12949 xmlSchemaParticlePtr sub; 12950 xmlSchemaElementPtr elemDecl; 12951 int lax; 12952 12953 sub = (xmlSchemaParticlePtr) particle->children->children; 12954 if (sub == NULL) 12955 break; 12956 start = pctxt->state; 12957 while (sub != NULL) { 12958 pctxt->state = start; 12959 12960 elemDecl = (xmlSchemaElementPtr) sub->children; 12961 if (elemDecl == NULL) { 12962 PERROR_INT("xmlSchemaBuildAContentModel", 12963 "<element> particle has no term"); 12964 return; 12965 }; 12966 /* 12967 * NOTE: The {max occurs} of all the particles in the 12968 * {particles} of the group must be 0 or 1; this is 12969 * already ensured during the parse of the content of 12970 * <all>. 12971 */ 12972 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12973 int counter; 12974 12975 /* 12976 * This is an abstract group, we need to share 12977 * the same counter for all the element transitions 12978 * derived from the group 12979 */ 12980 counter = xmlAutomataNewCounter(pctxt->am, 12981 sub->minOccurs, sub->maxOccurs); 12982 xmlSchemaBuildContentModelForSubstGroup(pctxt, 12983 sub, counter, pctxt->state); 12984 } else { 12985 if ((sub->minOccurs == 1) && 12986 (sub->maxOccurs == 1)) { 12987 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 12988 pctxt->state, 12989 elemDecl->name, 12990 elemDecl->targetNamespace, 12991 1, 1, elemDecl); 12992 } else if ((sub->minOccurs == 0) && 12993 (sub->maxOccurs == 1)) { 12994 12995 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 12996 pctxt->state, 12997 elemDecl->name, 12998 elemDecl->targetNamespace, 12999 0, 13000 1, 13001 elemDecl); 13002 } 13003 } 13004 sub = (xmlSchemaParticlePtr) sub->next; 13005 } 13006 lax = particle->minOccurs == 0; 13007 pctxt->state = 13008 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax); 13009 break; 13010 } 13011 case XML_SCHEMA_TYPE_GROUP: 13012 /* 13013 * If we hit a model group definition, then this means that 13014 * it was empty, thus was not substituted for the containing 13015 * model group. Just do nothing in this case. 13016 * TODO: But the group should be substituted and not occur at 13017 * all in the content model at this point. Fix this. 13018 */ 13019 break; 13020 default: 13021 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13022 "xmlSchemaBuildAContentModel", 13023 "found unexpected term of type '%s' in content model", 13024 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13025 return; 13026 } 13027} 13028 13029/** 13030 * xmlSchemaBuildContentModel: 13031 * @ctxt: the schema parser context 13032 * @type: the complex type definition 13033 * @name: the element name 13034 * 13035 * Builds the content model of the complex type. 13036 */ 13037static void 13038xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13039 xmlSchemaParserCtxtPtr ctxt) 13040{ 13041 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13042 (type->contModel != NULL) || 13043 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13044 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13045 return; 13046 13047#ifdef DEBUG_CONTENT 13048 xmlGenericError(xmlGenericErrorContext, 13049 "Building content model for %s\n", name); 13050#endif 13051 ctxt->am = NULL; 13052 ctxt->am = xmlNewAutomata(); 13053 if (ctxt->am == NULL) { 13054 xmlGenericError(xmlGenericErrorContext, 13055 "Cannot create automata for complex type %s\n", type->name); 13056 return; 13057 } 13058 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13059 /* 13060 * Build the automaton. 13061 */ 13062 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13063 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13064 type->contModel = xmlAutomataCompile(ctxt->am); 13065 if (type->contModel == NULL) { 13066 xmlSchemaPCustomErr(ctxt, 13067 XML_SCHEMAP_INTERNAL, 13068 WXS_BASIC_CAST type, type->node, 13069 "Failed to compile the content model", NULL); 13070 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13071 xmlSchemaPCustomErr(ctxt, 13072 XML_SCHEMAP_NOT_DETERMINISTIC, 13073 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13074 WXS_BASIC_CAST type, type->node, 13075 "The content model is not determinist", NULL); 13076 } else { 13077#ifdef DEBUG_CONTENT_REGEXP 13078 xmlGenericError(xmlGenericErrorContext, 13079 "Content model of %s:\n", type->name); 13080 xmlRegexpPrint(stderr, type->contModel); 13081#endif 13082 } 13083 ctxt->state = NULL; 13084 xmlFreeAutomata(ctxt->am); 13085 ctxt->am = NULL; 13086} 13087 13088/** 13089 * xmlSchemaResolveElementReferences: 13090 * @elem: the schema element context 13091 * @ctxt: the schema parser context 13092 * 13093 * Resolves the references of an element declaration 13094 * or particle, which has an element declaration as it's 13095 * term. 13096 */ 13097static void 13098xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13099 xmlSchemaParserCtxtPtr ctxt) 13100{ 13101 if ((ctxt == NULL) || (elemDecl == NULL) || 13102 ((elemDecl != NULL) && 13103 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13104 return; 13105 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13106 13107 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13108 xmlSchemaTypePtr type; 13109 13110 /* (type definition) ... otherwise the type definition �resolved� 13111 * to by the �actual value� of the type [attribute] ... 13112 */ 13113 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13114 elemDecl->namedTypeNs); 13115 if (type == NULL) { 13116 xmlSchemaPResCompAttrErr(ctxt, 13117 XML_SCHEMAP_SRC_RESOLVE, 13118 WXS_BASIC_CAST elemDecl, elemDecl->node, 13119 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13120 XML_SCHEMA_TYPE_BASIC, "type definition"); 13121 } else 13122 elemDecl->subtypes = type; 13123 } 13124 if (elemDecl->substGroup != NULL) { 13125 xmlSchemaElementPtr substHead; 13126 13127 /* 13128 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13129 * substitutionGroup? 13130 */ 13131 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13132 elemDecl->substGroupNs); 13133 if (substHead == NULL) { 13134 xmlSchemaPResCompAttrErr(ctxt, 13135 XML_SCHEMAP_SRC_RESOLVE, 13136 WXS_BASIC_CAST elemDecl, NULL, 13137 "substitutionGroup", elemDecl->substGroup, 13138 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13139 } else { 13140 xmlSchemaResolveElementReferences(substHead, ctxt); 13141 /* 13142 * Set the "substitution group affiliation". 13143 * NOTE that now we use the "refDecl" field for this. 13144 */ 13145 WXS_SUBST_HEAD(elemDecl) = substHead; 13146 /* 13147 * The type definitions is set to: 13148 * SPEC "...the {type definition} of the element 13149 * declaration �resolved� to by the �actual value� 13150 * of the substitutionGroup [attribute], if present" 13151 */ 13152 if (elemDecl->subtypes == NULL) 13153 elemDecl->subtypes = substHead->subtypes; 13154 } 13155 } 13156 /* 13157 * SPEC "The definition of anyType serves as the default type definition 13158 * for element declarations whose XML representation does not specify one." 13159 */ 13160 if ((elemDecl->subtypes == NULL) && 13161 (elemDecl->namedType == NULL) && 13162 (elemDecl->substGroup == NULL)) 13163 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13164} 13165 13166/** 13167 * xmlSchemaResolveUnionMemberTypes: 13168 * @ctxt: the schema parser context 13169 * @type: the schema simple type definition 13170 * 13171 * Checks and builds the "member type definitions" property of the union 13172 * simple type. This handles part (1), part (2) is done in 13173 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13174 * 13175 * Returns -1 in case of an internal error, 0 otherwise. 13176 */ 13177static int 13178xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13179 xmlSchemaTypePtr type) 13180{ 13181 13182 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13183 xmlSchemaTypePtr memberType; 13184 13185 /* 13186 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13187 * define the explicit members as the type definitions �resolved� 13188 * to by the items in the �actual value� of the memberTypes [attribute], 13189 * if any, followed by the type definitions corresponding to the 13190 * <simpleType>s among the [children] of <union>, if any." 13191 */ 13192 /* 13193 * Resolve references. 13194 */ 13195 link = type->memberTypes; 13196 lastLink = NULL; 13197 while (link != NULL) { 13198 const xmlChar *name, *nsName; 13199 13200 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13201 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13202 13203 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13204 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13205 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13206 WXS_BASIC_CAST type, type->node, "memberTypes", 13207 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13208 /* 13209 * Remove the member type link. 13210 */ 13211 if (lastLink == NULL) 13212 type->memberTypes = link->next; 13213 else 13214 lastLink->next = link->next; 13215 newLink = link; 13216 link = link->next; 13217 xmlFree(newLink); 13218 } else { 13219 link->type = memberType; 13220 lastLink = link; 13221 link = link->next; 13222 } 13223 } 13224 /* 13225 * Add local simple types, 13226 */ 13227 memberType = type->subtypes; 13228 while (memberType != NULL) { 13229 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13230 if (link == NULL) { 13231 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13232 return (-1); 13233 } 13234 link->type = memberType; 13235 link->next = NULL; 13236 if (lastLink == NULL) 13237 type->memberTypes = link; 13238 else 13239 lastLink->next = link; 13240 lastLink = link; 13241 memberType = memberType->next; 13242 } 13243 return (0); 13244} 13245 13246/** 13247 * xmlSchemaIsDerivedFromBuiltInType: 13248 * @ctxt: the schema parser context 13249 * @type: the type definition 13250 * @valType: the value type 13251 * 13252 * 13253 * Returns 1 if the type has the given value type, or 13254 * is derived from such a type. 13255 */ 13256static int 13257xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13258{ 13259 if (type == NULL) 13260 return (0); 13261 if (WXS_IS_COMPLEX(type)) 13262 return (0); 13263 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13264 if (type->builtInType == valType) 13265 return(1); 13266 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13267 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13268 return (0); 13269 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13270 } 13271 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13272} 13273 13274#if 0 13275/** 13276 * xmlSchemaIsDerivedFromBuiltInType: 13277 * @ctxt: the schema parser context 13278 * @type: the type definition 13279 * @valType: the value type 13280 * 13281 * 13282 * Returns 1 if the type has the given value type, or 13283 * is derived from such a type. 13284 */ 13285static int 13286xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13287{ 13288 if (type == NULL) 13289 return (0); 13290 if (WXS_IS_COMPLEX(type)) 13291 return (0); 13292 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13293 if (type->builtInType == valType) 13294 return(1); 13295 return (0); 13296 } else 13297 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13298 13299 return (0); 13300} 13301#endif 13302 13303static xmlSchemaTypePtr 13304xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13305{ 13306 if (type == NULL) 13307 return (NULL); 13308 if (WXS_IS_COMPLEX(type)) 13309 return (NULL); 13310 if (type->type == XML_SCHEMA_TYPE_BASIC) 13311 return(type); 13312 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13313} 13314 13315/** 13316 * xmlSchemaGetPrimitiveType: 13317 * @type: the simpleType definition 13318 * 13319 * Returns the primitive type of the given type or 13320 * NULL in case of error. 13321 */ 13322static xmlSchemaTypePtr 13323xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13324{ 13325 13326 while (type != NULL) { 13327 /* 13328 * Note that anySimpleType is actually not a primitive type 13329 * but we need that here. 13330 */ 13331 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13332 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13333 return (type); 13334 type = type->baseType; 13335 } 13336 13337 return (NULL); 13338} 13339 13340#if 0 13341/** 13342 * xmlSchemaGetBuiltInTypeAncestor: 13343 * @type: the simpleType definition 13344 * 13345 * Returns the primitive type of the given type or 13346 * NULL in case of error. 13347 */ 13348static xmlSchemaTypePtr 13349xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13350{ 13351 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13352 return (0); 13353 while (type != NULL) { 13354 if (type->type == XML_SCHEMA_TYPE_BASIC) 13355 return (type); 13356 type = type->baseType; 13357 } 13358 13359 return (NULL); 13360} 13361#endif 13362 13363/** 13364 * xmlSchemaCloneWildcardNsConstraints: 13365 * @ctxt: the schema parser context 13366 * @dest: the destination wildcard 13367 * @source: the source wildcard 13368 * 13369 * Clones the namespace constraints of source 13370 * and assignes them to dest. 13371 * Returns -1 on internal error, 0 otherwise. 13372 */ 13373static int 13374xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13375 xmlSchemaWildcardPtr dest, 13376 xmlSchemaWildcardPtr source) 13377{ 13378 xmlSchemaWildcardNsPtr cur, tmp, last; 13379 13380 if ((source == NULL) || (dest == NULL)) 13381 return(-1); 13382 dest->any = source->any; 13383 cur = source->nsSet; 13384 last = NULL; 13385 while (cur != NULL) { 13386 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13387 if (tmp == NULL) 13388 return(-1); 13389 tmp->value = cur->value; 13390 if (last == NULL) 13391 dest->nsSet = tmp; 13392 else 13393 last->next = tmp; 13394 last = tmp; 13395 cur = cur->next; 13396 } 13397 if (dest->negNsSet != NULL) 13398 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13399 if (source->negNsSet != NULL) { 13400 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13401 if (dest->negNsSet == NULL) 13402 return(-1); 13403 dest->negNsSet->value = source->negNsSet->value; 13404 } else 13405 dest->negNsSet = NULL; 13406 return(0); 13407} 13408 13409/** 13410 * xmlSchemaUnionWildcards: 13411 * @ctxt: the schema parser context 13412 * @completeWild: the first wildcard 13413 * @curWild: the second wildcard 13414 * 13415 * Unions the namespace constraints of the given wildcards. 13416 * @completeWild will hold the resulting union. 13417 * Returns a positive error code on failure, -1 in case of an 13418 * internal error, 0 otherwise. 13419 */ 13420static int 13421xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13422 xmlSchemaWildcardPtr completeWild, 13423 xmlSchemaWildcardPtr curWild) 13424{ 13425 xmlSchemaWildcardNsPtr cur, curB, tmp; 13426 13427 /* 13428 * 1 If O1 and O2 are the same value, then that value must be the 13429 * value. 13430 */ 13431 if ((completeWild->any == curWild->any) && 13432 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13433 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13434 13435 if ((completeWild->negNsSet == NULL) || 13436 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13437 13438 if (completeWild->nsSet != NULL) { 13439 int found = 0; 13440 13441 /* 13442 * Check equality of sets. 13443 */ 13444 cur = completeWild->nsSet; 13445 while (cur != NULL) { 13446 found = 0; 13447 curB = curWild->nsSet; 13448 while (curB != NULL) { 13449 if (cur->value == curB->value) { 13450 found = 1; 13451 break; 13452 } 13453 curB = curB->next; 13454 } 13455 if (!found) 13456 break; 13457 cur = cur->next; 13458 } 13459 if (found) 13460 return(0); 13461 } else 13462 return(0); 13463 } 13464 } 13465 /* 13466 * 2 If either O1 or O2 is any, then any must be the value 13467 */ 13468 if (completeWild->any != curWild->any) { 13469 if (completeWild->any == 0) { 13470 completeWild->any = 1; 13471 if (completeWild->nsSet != NULL) { 13472 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13473 completeWild->nsSet = NULL; 13474 } 13475 if (completeWild->negNsSet != NULL) { 13476 xmlFree(completeWild->negNsSet); 13477 completeWild->negNsSet = NULL; 13478 } 13479 } 13480 return (0); 13481 } 13482 /* 13483 * 3 If both O1 and O2 are sets of (namespace names or �absent�), 13484 * then the union of those sets must be the value. 13485 */ 13486 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13487 int found; 13488 xmlSchemaWildcardNsPtr start; 13489 13490 cur = curWild->nsSet; 13491 start = completeWild->nsSet; 13492 while (cur != NULL) { 13493 found = 0; 13494 curB = start; 13495 while (curB != NULL) { 13496 if (cur->value == curB->value) { 13497 found = 1; 13498 break; 13499 } 13500 curB = curB->next; 13501 } 13502 if (!found) { 13503 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13504 if (tmp == NULL) 13505 return (-1); 13506 tmp->value = cur->value; 13507 tmp->next = completeWild->nsSet; 13508 completeWild->nsSet = tmp; 13509 } 13510 cur = cur->next; 13511 } 13512 13513 return(0); 13514 } 13515 /* 13516 * 4 If the two are negations of different values (namespace names 13517 * or �absent�), then a pair of not and �absent� must be the value. 13518 */ 13519 if ((completeWild->negNsSet != NULL) && 13520 (curWild->negNsSet != NULL) && 13521 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13522 completeWild->negNsSet->value = NULL; 13523 13524 return(0); 13525 } 13526 /* 13527 * 5. 13528 */ 13529 if (((completeWild->negNsSet != NULL) && 13530 (completeWild->negNsSet->value != NULL) && 13531 (curWild->nsSet != NULL)) || 13532 ((curWild->negNsSet != NULL) && 13533 (curWild->negNsSet->value != NULL) && 13534 (completeWild->nsSet != NULL))) { 13535 13536 int nsFound, absentFound = 0; 13537 13538 if (completeWild->nsSet != NULL) { 13539 cur = completeWild->nsSet; 13540 curB = curWild->negNsSet; 13541 } else { 13542 cur = curWild->nsSet; 13543 curB = completeWild->negNsSet; 13544 } 13545 nsFound = 0; 13546 while (cur != NULL) { 13547 if (cur->value == NULL) 13548 absentFound = 1; 13549 else if (cur->value == curB->value) 13550 nsFound = 1; 13551 if (nsFound && absentFound) 13552 break; 13553 cur = cur->next; 13554 } 13555 13556 if (nsFound && absentFound) { 13557 /* 13558 * 5.1 If the set S includes both the negated namespace 13559 * name and �absent�, then any must be the value. 13560 */ 13561 completeWild->any = 1; 13562 if (completeWild->nsSet != NULL) { 13563 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13564 completeWild->nsSet = NULL; 13565 } 13566 if (completeWild->negNsSet != NULL) { 13567 xmlFree(completeWild->negNsSet); 13568 completeWild->negNsSet = NULL; 13569 } 13570 } else if (nsFound && (!absentFound)) { 13571 /* 13572 * 5.2 If the set S includes the negated namespace name 13573 * but not �absent�, then a pair of not and �absent� must 13574 * be the value. 13575 */ 13576 if (completeWild->nsSet != NULL) { 13577 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13578 completeWild->nsSet = NULL; 13579 } 13580 if (completeWild->negNsSet == NULL) { 13581 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13582 if (completeWild->negNsSet == NULL) 13583 return (-1); 13584 } 13585 completeWild->negNsSet->value = NULL; 13586 } else if ((!nsFound) && absentFound) { 13587 /* 13588 * 5.3 If the set S includes �absent� but not the negated 13589 * namespace name, then the union is not expressible. 13590 */ 13591 xmlSchemaPErr(ctxt, completeWild->node, 13592 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13593 "The union of the wilcard is not expressible.\n", 13594 NULL, NULL); 13595 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13596 } else if ((!nsFound) && (!absentFound)) { 13597 /* 13598 * 5.4 If the set S does not include either the negated namespace 13599 * name or �absent�, then whichever of O1 or O2 is a pair of not 13600 * and a namespace name must be the value. 13601 */ 13602 if (completeWild->negNsSet == NULL) { 13603 if (completeWild->nsSet != NULL) { 13604 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13605 completeWild->nsSet = NULL; 13606 } 13607 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13608 if (completeWild->negNsSet == NULL) 13609 return (-1); 13610 completeWild->negNsSet->value = curWild->negNsSet->value; 13611 } 13612 } 13613 return (0); 13614 } 13615 /* 13616 * 6. 13617 */ 13618 if (((completeWild->negNsSet != NULL) && 13619 (completeWild->negNsSet->value == NULL) && 13620 (curWild->nsSet != NULL)) || 13621 ((curWild->negNsSet != NULL) && 13622 (curWild->negNsSet->value == NULL) && 13623 (completeWild->nsSet != NULL))) { 13624 13625 if (completeWild->nsSet != NULL) { 13626 cur = completeWild->nsSet; 13627 } else { 13628 cur = curWild->nsSet; 13629 } 13630 while (cur != NULL) { 13631 if (cur->value == NULL) { 13632 /* 13633 * 6.1 If the set S includes �absent�, then any must be the 13634 * value. 13635 */ 13636 completeWild->any = 1; 13637 if (completeWild->nsSet != NULL) { 13638 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13639 completeWild->nsSet = NULL; 13640 } 13641 if (completeWild->negNsSet != NULL) { 13642 xmlFree(completeWild->negNsSet); 13643 completeWild->negNsSet = NULL; 13644 } 13645 return (0); 13646 } 13647 cur = cur->next; 13648 } 13649 if (completeWild->negNsSet == NULL) { 13650 /* 13651 * 6.2 If the set S does not include �absent�, then a pair of not 13652 * and �absent� must be the value. 13653 */ 13654 if (completeWild->nsSet != NULL) { 13655 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13656 completeWild->nsSet = NULL; 13657 } 13658 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13659 if (completeWild->negNsSet == NULL) 13660 return (-1); 13661 completeWild->negNsSet->value = NULL; 13662 } 13663 return (0); 13664 } 13665 return (0); 13666 13667} 13668 13669/** 13670 * xmlSchemaIntersectWildcards: 13671 * @ctxt: the schema parser context 13672 * @completeWild: the first wildcard 13673 * @curWild: the second wildcard 13674 * 13675 * Intersects the namespace constraints of the given wildcards. 13676 * @completeWild will hold the resulting intersection. 13677 * Returns a positive error code on failure, -1 in case of an 13678 * internal error, 0 otherwise. 13679 */ 13680static int 13681xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13682 xmlSchemaWildcardPtr completeWild, 13683 xmlSchemaWildcardPtr curWild) 13684{ 13685 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13686 13687 /* 13688 * 1 If O1 and O2 are the same value, then that value must be the 13689 * value. 13690 */ 13691 if ((completeWild->any == curWild->any) && 13692 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13693 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13694 13695 if ((completeWild->negNsSet == NULL) || 13696 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13697 13698 if (completeWild->nsSet != NULL) { 13699 int found = 0; 13700 13701 /* 13702 * Check equality of sets. 13703 */ 13704 cur = completeWild->nsSet; 13705 while (cur != NULL) { 13706 found = 0; 13707 curB = curWild->nsSet; 13708 while (curB != NULL) { 13709 if (cur->value == curB->value) { 13710 found = 1; 13711 break; 13712 } 13713 curB = curB->next; 13714 } 13715 if (!found) 13716 break; 13717 cur = cur->next; 13718 } 13719 if (found) 13720 return(0); 13721 } else 13722 return(0); 13723 } 13724 } 13725 /* 13726 * 2 If either O1 or O2 is any, then the other must be the value. 13727 */ 13728 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13729 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13730 return(-1); 13731 return(0); 13732 } 13733 /* 13734 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13735 * name or �absent�) and the other is a set of (namespace names or 13736 * �absent�), then that set, minus the negated value if it was in 13737 * the set, minus �absent� if it was in the set, must be the value. 13738 */ 13739 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13740 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13741 const xmlChar *neg; 13742 13743 if (completeWild->nsSet == NULL) { 13744 neg = completeWild->negNsSet->value; 13745 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13746 return(-1); 13747 } else 13748 neg = curWild->negNsSet->value; 13749 /* 13750 * Remove absent and negated. 13751 */ 13752 prev = NULL; 13753 cur = completeWild->nsSet; 13754 while (cur != NULL) { 13755 if (cur->value == NULL) { 13756 if (prev == NULL) 13757 completeWild->nsSet = cur->next; 13758 else 13759 prev->next = cur->next; 13760 xmlFree(cur); 13761 break; 13762 } 13763 prev = cur; 13764 cur = cur->next; 13765 } 13766 if (neg != NULL) { 13767 prev = NULL; 13768 cur = completeWild->nsSet; 13769 while (cur != NULL) { 13770 if (cur->value == neg) { 13771 if (prev == NULL) 13772 completeWild->nsSet = cur->next; 13773 else 13774 prev->next = cur->next; 13775 xmlFree(cur); 13776 break; 13777 } 13778 prev = cur; 13779 cur = cur->next; 13780 } 13781 } 13782 13783 return(0); 13784 } 13785 /* 13786 * 4 If both O1 and O2 are sets of (namespace names or �absent�), 13787 * then the intersection of those sets must be the value. 13788 */ 13789 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13790 int found; 13791 13792 cur = completeWild->nsSet; 13793 prev = NULL; 13794 while (cur != NULL) { 13795 found = 0; 13796 curB = curWild->nsSet; 13797 while (curB != NULL) { 13798 if (cur->value == curB->value) { 13799 found = 1; 13800 break; 13801 } 13802 curB = curB->next; 13803 } 13804 if (!found) { 13805 if (prev == NULL) 13806 completeWild->nsSet = cur->next; 13807 else 13808 prev->next = cur->next; 13809 tmp = cur->next; 13810 xmlFree(cur); 13811 cur = tmp; 13812 continue; 13813 } 13814 prev = cur; 13815 cur = cur->next; 13816 } 13817 13818 return(0); 13819 } 13820 /* 5 If the two are negations of different namespace names, 13821 * then the intersection is not expressible 13822 */ 13823 if ((completeWild->negNsSet != NULL) && 13824 (curWild->negNsSet != NULL) && 13825 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13826 (completeWild->negNsSet->value != NULL) && 13827 (curWild->negNsSet->value != NULL)) { 13828 13829 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13830 "The intersection of the wilcard is not expressible.\n", 13831 NULL, NULL); 13832 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13833 } 13834 /* 13835 * 6 If the one is a negation of a namespace name and the other 13836 * is a negation of �absent�, then the one which is the negation 13837 * of a namespace name must be the value. 13838 */ 13839 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13840 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13841 (completeWild->negNsSet->value == NULL)) { 13842 completeWild->negNsSet->value = curWild->negNsSet->value; 13843 } 13844 return(0); 13845} 13846 13847/** 13848 * xmlSchemaIsWildcardNsConstraintSubset: 13849 * @ctxt: the schema parser context 13850 * @sub: the first wildcard 13851 * @super: the second wildcard 13852 * 13853 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13854 * 13855 * Returns 0 if the namespace constraint of @sub is an intensional 13856 * subset of @super, 1 otherwise. 13857 */ 13858static int 13859xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13860 xmlSchemaWildcardPtr super) 13861{ 13862 /* 13863 * 1 super must be any. 13864 */ 13865 if (super->any) 13866 return (0); 13867 /* 13868 * 2.1 sub must be a pair of not and a namespace name or �absent�. 13869 * 2.2 super must be a pair of not and the same value. 13870 */ 13871 if ((sub->negNsSet != NULL) && 13872 (super->negNsSet != NULL) && 13873 (sub->negNsSet->value == sub->negNsSet->value)) 13874 return (0); 13875 /* 13876 * 3.1 sub must be a set whose members are either namespace names or �absent�. 13877 */ 13878 if (sub->nsSet != NULL) { 13879 /* 13880 * 3.2.1 super must be the same set or a superset thereof. 13881 */ 13882 if (super->nsSet != NULL) { 13883 xmlSchemaWildcardNsPtr cur, curB; 13884 int found = 0; 13885 13886 cur = sub->nsSet; 13887 while (cur != NULL) { 13888 found = 0; 13889 curB = super->nsSet; 13890 while (curB != NULL) { 13891 if (cur->value == curB->value) { 13892 found = 1; 13893 break; 13894 } 13895 curB = curB->next; 13896 } 13897 if (!found) 13898 return (1); 13899 cur = cur->next; 13900 } 13901 if (found) 13902 return (0); 13903 } else if (super->negNsSet != NULL) { 13904 xmlSchemaWildcardNsPtr cur; 13905 /* 13906 * 3.2.2 super must be a pair of not and a namespace name or 13907 * �absent� and that value must not be in sub's set. 13908 */ 13909 cur = sub->nsSet; 13910 while (cur != NULL) { 13911 if (cur->value == super->negNsSet->value) 13912 return (1); 13913 cur = cur->next; 13914 } 13915 return (0); 13916 } 13917 } 13918 return (1); 13919} 13920 13921static int 13922xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 13923 int *fixed, 13924 const xmlChar **value, 13925 xmlSchemaValPtr *val) 13926{ 13927 *fixed = 0; 13928 *value = NULL; 13929 if (val != 0) 13930 *val = NULL; 13931 13932 if (attruse->defValue != NULL) { 13933 *value = attruse->defValue; 13934 if (val != NULL) 13935 *val = attruse->defVal; 13936 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 13937 *fixed = 1; 13938 return(1); 13939 } else if ((attruse->attrDecl != NULL) && 13940 (attruse->attrDecl->defValue != NULL)) { 13941 *value = attruse->attrDecl->defValue; 13942 if (val != NULL) 13943 *val = attruse->attrDecl->defVal; 13944 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 13945 *fixed = 1; 13946 return(1); 13947 } 13948 return(0); 13949} 13950/** 13951 * xmlSchemaCheckCVCWildcardNamespace: 13952 * @wild: the wildcard 13953 * @ns: the namespace 13954 * 13955 * Validation Rule: Wildcard allows Namespace Name 13956 * (cvc-wildcard-namespace) 13957 * 13958 * Returns 0 if the given namespace matches the wildcard, 13959 * 1 otherwise and -1 on API errors. 13960 */ 13961static int 13962xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 13963 const xmlChar* ns) 13964{ 13965 if (wild == NULL) 13966 return(-1); 13967 13968 if (wild->any) 13969 return(0); 13970 else if (wild->nsSet != NULL) { 13971 xmlSchemaWildcardNsPtr cur; 13972 13973 cur = wild->nsSet; 13974 while (cur != NULL) { 13975 if (xmlStrEqual(cur->value, ns)) 13976 return(0); 13977 cur = cur->next; 13978 } 13979 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 13980 (!xmlStrEqual(wild->negNsSet->value, ns))) 13981 return(0); 13982 13983 return(1); 13984} 13985 13986#define XML_SCHEMA_ACTION_DERIVE 0 13987#define XML_SCHEMA_ACTION_REDEFINE 1 13988 13989#define WXS_ACTION_STR(a) \ 13990((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 13991 13992/* 13993* Schema Component Constraint: 13994* Derivation Valid (Restriction, Complex) 13995* derivation-ok-restriction (2) - (4) 13996* 13997* ATTENTION: 13998* In XML Schema 1.1 this will be: 13999* Validation Rule: 14000* Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14001* 14002*/ 14003static int 14004xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14005 int action, 14006 xmlSchemaBasicItemPtr item, 14007 xmlSchemaBasicItemPtr baseItem, 14008 xmlSchemaItemListPtr uses, 14009 xmlSchemaItemListPtr baseUses, 14010 xmlSchemaWildcardPtr wild, 14011 xmlSchemaWildcardPtr baseWild) 14012{ 14013 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14014 int i, j, found; /* err = 0; */ 14015 const xmlChar *bEffValue; 14016 int effFixed; 14017 14018 if (uses != NULL) { 14019 for (i = 0; i < uses->nbItems; i++) { 14020 cur = uses->items[i]; 14021 found = 0; 14022 if (baseUses == NULL) 14023 goto not_found; 14024 for (j = 0; j < baseUses->nbItems; j++) { 14025 bcur = baseUses->items[j]; 14026 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14027 WXS_ATTRUSE_DECL_NAME(bcur)) && 14028 (WXS_ATTRUSE_DECL_TNS(cur) == 14029 WXS_ATTRUSE_DECL_TNS(bcur))) 14030 { 14031 /* 14032 * (2.1) "If there is an attribute use in the {attribute 14033 * uses} of the {base type definition} (call this B) whose 14034 * {attribute declaration} has the same {name} and {target 14035 * namespace}, then all of the following must be true:" 14036 */ 14037 found = 1; 14038 14039 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14040 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14041 { 14042 xmlChar *str = NULL; 14043 /* 14044 * (2.1.1) "one of the following must be true:" 14045 * (2.1.1.1) "B's {required} is false." 14046 * (2.1.1.2) "R's {required} is true." 14047 */ 14048 xmlSchemaPAttrUseErr4(pctxt, 14049 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14050 WXS_ITEM_NODE(item), item, cur, 14051 "The 'optional' attribute use is inconsistent " 14052 "with the corresponding 'required' attribute use of " 14053 "the %s %s", 14054 WXS_ACTION_STR(action), 14055 xmlSchemaGetComponentDesignation(&str, baseItem), 14056 NULL, NULL); 14057 FREE_AND_NULL(str); 14058 /* err = pctxt->err; */ 14059 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14060 WXS_ATTRUSE_TYPEDEF(cur), 14061 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14062 { 14063 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14064 14065 /* 14066 * SPEC (2.1.2) "R's {attribute declaration}'s 14067 * {type definition} must be validly derived from 14068 * B's {type definition} given the empty set as 14069 * defined in Type Derivation OK (Simple) (�3.14.6)." 14070 */ 14071 xmlSchemaPAttrUseErr4(pctxt, 14072 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14073 WXS_ITEM_NODE(item), item, cur, 14074 "The attribute declaration's %s " 14075 "is not validly derived from " 14076 "the corresponding %s of the " 14077 "attribute declaration in the %s %s", 14078 xmlSchemaGetComponentDesignation(&strA, 14079 WXS_ATTRUSE_TYPEDEF(cur)), 14080 xmlSchemaGetComponentDesignation(&strB, 14081 WXS_ATTRUSE_TYPEDEF(bcur)), 14082 WXS_ACTION_STR(action), 14083 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14084 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14085 FREE_AND_NULL(strA); 14086 FREE_AND_NULL(strB); 14087 FREE_AND_NULL(strC); 14088 /* err = pctxt->err; */ 14089 } else { 14090 /* 14091 * 2.1.3 [Definition:] Let the effective value 14092 * constraint of an attribute use be its {value 14093 * constraint}, if present, otherwise its {attribute 14094 * declaration}'s {value constraint} . 14095 */ 14096 xmlSchemaGetEffectiveValueConstraint(bcur, 14097 &effFixed, &bEffValue, NULL); 14098 /* 14099 * 2.1.3 ... one of the following must be true 14100 * 14101 * 2.1.3.1 B's �effective value constraint� is 14102 * �absent� or default. 14103 */ 14104 if ((bEffValue != NULL) && 14105 (effFixed == 1)) { 14106 const xmlChar *rEffValue = NULL; 14107 14108 xmlSchemaGetEffectiveValueConstraint(bcur, 14109 &effFixed, &rEffValue, NULL); 14110 /* 14111 * 2.1.3.2 R's �effective value constraint� is 14112 * fixed with the same string as B's. 14113 * MAYBE TODO: Compare the computed values. 14114 * Hmm, it says "same string" so 14115 * string-equality might really be sufficient. 14116 */ 14117 if ((effFixed == 0) || 14118 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14119 { 14120 xmlChar *str = NULL; 14121 14122 xmlSchemaPAttrUseErr4(pctxt, 14123 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14124 WXS_ITEM_NODE(item), item, cur, 14125 "The effective value constraint of the " 14126 "attribute use is inconsistent with " 14127 "its correspondent in the %s %s", 14128 WXS_ACTION_STR(action), 14129 xmlSchemaGetComponentDesignation(&str, 14130 baseItem), 14131 NULL, NULL); 14132 FREE_AND_NULL(str); 14133 /* err = pctxt->err; */ 14134 } 14135 } 14136 } 14137 break; 14138 } 14139 } 14140not_found: 14141 if (!found) { 14142 /* 14143 * (2.2) "otherwise the {base type definition} must have an 14144 * {attribute wildcard} and the {target namespace} of the 14145 * R's {attribute declaration} must be �valid� with respect 14146 * to that wildcard, as defined in Wildcard allows Namespace 14147 * Name (�3.10.4)." 14148 */ 14149 if ((baseWild == NULL) || 14150 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14151 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14152 { 14153 xmlChar *str = NULL; 14154 14155 xmlSchemaPAttrUseErr4(pctxt, 14156 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14157 WXS_ITEM_NODE(item), item, cur, 14158 "Neither a matching attribute use, " 14159 "nor a matching wildcard exists in the %s %s", 14160 WXS_ACTION_STR(action), 14161 xmlSchemaGetComponentDesignation(&str, baseItem), 14162 NULL, NULL); 14163 FREE_AND_NULL(str); 14164 /* err = pctxt->err; */ 14165 } 14166 } 14167 } 14168 } 14169 /* 14170 * SPEC derivation-ok-restriction (3): 14171 * (3) "For each attribute use in the {attribute uses} of the {base type 14172 * definition} whose {required} is true, there must be an attribute 14173 * use with an {attribute declaration} with the same {name} and 14174 * {target namespace} as its {attribute declaration} in the {attribute 14175 * uses} of the complex type definition itself whose {required} is true. 14176 */ 14177 if (baseUses != NULL) { 14178 for (j = 0; j < baseUses->nbItems; j++) { 14179 bcur = baseUses->items[j]; 14180 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14181 continue; 14182 found = 0; 14183 if (uses != NULL) { 14184 for (i = 0; i < uses->nbItems; i++) { 14185 cur = uses->items[i]; 14186 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14187 WXS_ATTRUSE_DECL_NAME(bcur)) && 14188 (WXS_ATTRUSE_DECL_TNS(cur) == 14189 WXS_ATTRUSE_DECL_TNS(bcur))) { 14190 found = 1; 14191 break; 14192 } 14193 } 14194 } 14195 if (!found) { 14196 xmlChar *strA = NULL, *strB = NULL; 14197 14198 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14199 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14200 NULL, item, 14201 "A matching attribute use for the " 14202 "'required' %s of the %s %s is missing", 14203 xmlSchemaGetComponentDesignation(&strA, bcur), 14204 WXS_ACTION_STR(action), 14205 xmlSchemaGetComponentDesignation(&strB, baseItem), 14206 NULL); 14207 FREE_AND_NULL(strA); 14208 FREE_AND_NULL(strB); 14209 } 14210 } 14211 } 14212 /* 14213 * derivation-ok-restriction (4) 14214 */ 14215 if (wild != NULL) { 14216 /* 14217 * (4) "If there is an {attribute wildcard}, all of the 14218 * following must be true:" 14219 */ 14220 if (baseWild == NULL) { 14221 xmlChar *str = NULL; 14222 14223 /* 14224 * (4.1) "The {base type definition} must also have one." 14225 */ 14226 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14227 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14228 NULL, item, 14229 "The %s has an attribute wildcard, " 14230 "but the %s %s '%s' does not have one", 14231 WXS_ITEM_TYPE_NAME(item), 14232 WXS_ACTION_STR(action), 14233 WXS_ITEM_TYPE_NAME(baseItem), 14234 xmlSchemaGetComponentQName(&str, baseItem)); 14235 FREE_AND_NULL(str); 14236 return(pctxt->err); 14237 } else if ((baseWild->any == 0) && 14238 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14239 { 14240 xmlChar *str = NULL; 14241 /* 14242 * (4.2) "The complex type definition's {attribute wildcard}'s 14243 * {namespace constraint} must be a subset of the {base type 14244 * definition}'s {attribute wildcard}'s {namespace constraint}, 14245 * as defined by Wildcard Subset (�3.10.6)." 14246 */ 14247 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14248 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14249 NULL, item, 14250 "The attribute wildcard is not a valid " 14251 "subset of the wildcard in the %s %s '%s'", 14252 WXS_ACTION_STR(action), 14253 WXS_ITEM_TYPE_NAME(baseItem), 14254 xmlSchemaGetComponentQName(&str, baseItem), 14255 NULL); 14256 FREE_AND_NULL(str); 14257 return(pctxt->err); 14258 } 14259 /* 4.3 Unless the {base type definition} is the �ur-type 14260 * definition�, the complex type definition's {attribute 14261 * wildcard}'s {process contents} must be identical to or 14262 * stronger than the {base type definition}'s {attribute 14263 * wildcard}'s {process contents}, where strict is stronger 14264 * than lax is stronger than skip. 14265 */ 14266 if ((! WXS_IS_ANYTYPE(baseItem)) && 14267 (wild->processContents < baseWild->processContents)) { 14268 xmlChar *str = NULL; 14269 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14270 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14271 NULL, baseItem, 14272 "The {process contents} of the attribute wildcard is " 14273 "weaker than the one in the %s %s '%s'", 14274 WXS_ACTION_STR(action), 14275 WXS_ITEM_TYPE_NAME(baseItem), 14276 xmlSchemaGetComponentQName(&str, baseItem), 14277 NULL); 14278 FREE_AND_NULL(str) 14279 return(pctxt->err); 14280 } 14281 } 14282 return(0); 14283} 14284 14285 14286static int 14287xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14288 xmlSchemaBasicItemPtr item, 14289 xmlSchemaWildcardPtr *completeWild, 14290 xmlSchemaItemListPtr list, 14291 xmlSchemaItemListPtr prohibs); 14292/** 14293 * xmlSchemaFixupTypeAttributeUses: 14294 * @ctxt: the schema parser context 14295 * @type: the complex type definition 14296 * 14297 * 14298 * Builds the wildcard and the attribute uses on the given complex type. 14299 * Returns -1 if an internal error occurs, 0 otherwise. 14300 * 14301 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14302 * strings, so recheck this if we start to hardcode some schemata, since 14303 * they might not be in the same dict. 14304 * NOTE: It is allowed to "extend" the xs:anyType type. 14305 */ 14306static int 14307xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14308 xmlSchemaTypePtr type) 14309{ 14310 xmlSchemaTypePtr baseType = NULL; 14311 xmlSchemaAttributeUsePtr use; 14312 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14313 14314 if (type->baseType == NULL) { 14315 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14316 "no base type"); 14317 return (-1); 14318 } 14319 baseType = type->baseType; 14320 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14321 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14322 return(-1); 14323 14324 uses = type->attrUses; 14325 baseUses = baseType->attrUses; 14326 /* 14327 * Expand attribute group references. And build the 'complete' 14328 * wildcard, i.e. intersect multiple wildcards. 14329 * Move attribute prohibitions into a separate list. 14330 */ 14331 if (uses != NULL) { 14332 if (WXS_IS_RESTRICTION(type)) { 14333 /* 14334 * This one will transfer all attr. prohibitions 14335 * into pctxt->attrProhibs. 14336 */ 14337 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14338 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14339 pctxt->attrProhibs) == -1) 14340 { 14341 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14342 "failed to expand attributes"); 14343 } 14344 if (pctxt->attrProhibs->nbItems != 0) 14345 prohibs = pctxt->attrProhibs; 14346 } else { 14347 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14348 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14349 NULL) == -1) 14350 { 14351 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14352 "failed to expand attributes"); 14353 } 14354 } 14355 } 14356 /* 14357 * Inherit the attribute uses of the base type. 14358 */ 14359 if (baseUses != NULL) { 14360 int i, j; 14361 xmlSchemaAttributeUseProhibPtr pro; 14362 14363 if (WXS_IS_RESTRICTION(type)) { 14364 int usesCount; 14365 xmlSchemaAttributeUsePtr tmp; 14366 14367 if (uses != NULL) 14368 usesCount = uses->nbItems; 14369 else 14370 usesCount = 0; 14371 14372 /* Restriction. */ 14373 for (i = 0; i < baseUses->nbItems; i++) { 14374 use = baseUses->items[i]; 14375 if (prohibs) { 14376 /* 14377 * Filter out prohibited uses. 14378 */ 14379 for (j = 0; j < prohibs->nbItems; j++) { 14380 pro = prohibs->items[j]; 14381 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14382 (WXS_ATTRUSE_DECL_TNS(use) == 14383 pro->targetNamespace)) 14384 { 14385 goto inherit_next; 14386 } 14387 } 14388 } 14389 if (usesCount) { 14390 /* 14391 * Filter out existing uses. 14392 */ 14393 for (j = 0; j < usesCount; j++) { 14394 tmp = uses->items[j]; 14395 if ((WXS_ATTRUSE_DECL_NAME(use) == 14396 WXS_ATTRUSE_DECL_NAME(tmp)) && 14397 (WXS_ATTRUSE_DECL_TNS(use) == 14398 WXS_ATTRUSE_DECL_TNS(tmp))) 14399 { 14400 goto inherit_next; 14401 } 14402 } 14403 } 14404 if (uses == NULL) { 14405 type->attrUses = xmlSchemaItemListCreate(); 14406 if (type->attrUses == NULL) 14407 goto exit_failure; 14408 uses = type->attrUses; 14409 } 14410 xmlSchemaItemListAddSize(uses, 2, use); 14411inherit_next: {} 14412 } 14413 } else { 14414 /* Extension. */ 14415 for (i = 0; i < baseUses->nbItems; i++) { 14416 use = baseUses->items[i]; 14417 if (uses == NULL) { 14418 type->attrUses = xmlSchemaItemListCreate(); 14419 if (type->attrUses == NULL) 14420 goto exit_failure; 14421 uses = type->attrUses; 14422 } 14423 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14424 } 14425 } 14426 } 14427 /* 14428 * Shrink attr. uses. 14429 */ 14430 if (uses) { 14431 if (uses->nbItems == 0) { 14432 xmlSchemaItemListFree(uses); 14433 type->attrUses = NULL; 14434 } 14435 /* 14436 * TODO: We could shrink the size of the array 14437 * to fit the actual number of items. 14438 */ 14439 } 14440 /* 14441 * Compute the complete wildcard. 14442 */ 14443 if (WXS_IS_EXTENSION(type)) { 14444 if (baseType->attributeWildcard != NULL) { 14445 /* 14446 * (3.2.2.1) "If the �base wildcard� is non-�absent�, then 14447 * the appropriate case among the following:" 14448 */ 14449 if (type->attributeWildcard != NULL) { 14450 /* 14451 * Union the complete wildcard with the base wildcard. 14452 * SPEC {attribute wildcard} 14453 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14454 * and {annotation} are those of the �complete wildcard�, 14455 * and whose {namespace constraint} is the intensional union 14456 * of the {namespace constraint} of the �complete wildcard� 14457 * and of the �base wildcard�, as defined in Attribute 14458 * Wildcard Union (�3.10.6)." 14459 */ 14460 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14461 baseType->attributeWildcard) == -1) 14462 goto exit_failure; 14463 } else { 14464 /* 14465 * (3.2.2.1.1) "If the �complete wildcard� is �absent�, 14466 * then the �base wildcard�." 14467 */ 14468 type->attributeWildcard = baseType->attributeWildcard; 14469 } 14470 } else { 14471 /* 14472 * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the 14473 * �complete wildcard" 14474 * NOOP 14475 */ 14476 } 14477 } else { 14478 /* 14479 * SPEC {attribute wildcard} 14480 * (3.1) "If the <restriction> alternative is chosen, then the 14481 * �complete wildcard�;" 14482 * NOOP 14483 */ 14484 } 14485 14486 return (0); 14487 14488exit_failure: 14489 return(-1); 14490} 14491 14492/** 14493 * xmlSchemaTypeFinalContains: 14494 * @schema: the schema 14495 * @type: the type definition 14496 * @final: the final 14497 * 14498 * Evaluates if a type definition contains the given "final". 14499 * This does take "finalDefault" into account as well. 14500 * 14501 * Returns 1 if the type does containt the given "final", 14502 * 0 otherwise. 14503 */ 14504static int 14505xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14506{ 14507 if (type == NULL) 14508 return (0); 14509 if (type->flags & final) 14510 return (1); 14511 else 14512 return (0); 14513} 14514 14515/** 14516 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14517 * @type: the Union Simple Type 14518 * 14519 * Returns a list of member types of @type if existing, 14520 * returns NULL otherwise. 14521 */ 14522static xmlSchemaTypeLinkPtr 14523xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14524{ 14525 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14526 if (type->memberTypes != NULL) 14527 return (type->memberTypes); 14528 else 14529 type = type->baseType; 14530 } 14531 return (NULL); 14532} 14533 14534/** 14535 * xmlSchemaGetParticleTotalRangeMin: 14536 * @particle: the particle 14537 * 14538 * Schema Component Constraint: Effective Total Range 14539 * (all and sequence) + (choice) 14540 * 14541 * Returns the minimun Effective Total Range. 14542 */ 14543static int 14544xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14545{ 14546 if ((particle->children == NULL) || 14547 (particle->minOccurs == 0)) 14548 return (0); 14549 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14550 int min = -1, cur; 14551 xmlSchemaParticlePtr part = 14552 (xmlSchemaParticlePtr) particle->children->children; 14553 14554 if (part == NULL) 14555 return (0); 14556 while (part != NULL) { 14557 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14558 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14559 cur = part->minOccurs; 14560 else 14561 cur = xmlSchemaGetParticleTotalRangeMin(part); 14562 if (cur == 0) 14563 return (0); 14564 if ((min > cur) || (min == -1)) 14565 min = cur; 14566 part = (xmlSchemaParticlePtr) part->next; 14567 } 14568 return (particle->minOccurs * min); 14569 } else { 14570 /* <all> and <sequence> */ 14571 int sum = 0; 14572 xmlSchemaParticlePtr part = 14573 (xmlSchemaParticlePtr) particle->children->children; 14574 14575 if (part == NULL) 14576 return (0); 14577 do { 14578 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14579 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14580 sum += part->minOccurs; 14581 else 14582 sum += xmlSchemaGetParticleTotalRangeMin(part); 14583 part = (xmlSchemaParticlePtr) part->next; 14584 } while (part != NULL); 14585 return (particle->minOccurs * sum); 14586 } 14587} 14588 14589/** 14590 * xmlSchemaGetParticleTotalRangeMax: 14591 * @particle: the particle 14592 * 14593 * Schema Component Constraint: Effective Total Range 14594 * (all and sequence) + (choice) 14595 * 14596 * Returns the maximum Effective Total Range. 14597 */ 14598static int 14599xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14600{ 14601 if ((particle->children == NULL) || 14602 (particle->children->children == NULL)) 14603 return (0); 14604 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14605 int max = -1, cur; 14606 xmlSchemaParticlePtr part = 14607 (xmlSchemaParticlePtr) particle->children->children; 14608 14609 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14610 if (part->children == NULL) 14611 continue; 14612 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14613 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14614 cur = part->maxOccurs; 14615 else 14616 cur = xmlSchemaGetParticleTotalRangeMax(part); 14617 if (cur == UNBOUNDED) 14618 return (UNBOUNDED); 14619 if ((max < cur) || (max == -1)) 14620 max = cur; 14621 } 14622 /* TODO: Handle overflows? */ 14623 return (particle->maxOccurs * max); 14624 } else { 14625 /* <all> and <sequence> */ 14626 int sum = 0, cur; 14627 xmlSchemaParticlePtr part = 14628 (xmlSchemaParticlePtr) particle->children->children; 14629 14630 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14631 if (part->children == NULL) 14632 continue; 14633 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14634 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14635 cur = part->maxOccurs; 14636 else 14637 cur = xmlSchemaGetParticleTotalRangeMax(part); 14638 if (cur == UNBOUNDED) 14639 return (UNBOUNDED); 14640 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14641 return (UNBOUNDED); 14642 sum += cur; 14643 } 14644 /* TODO: Handle overflows? */ 14645 return (particle->maxOccurs * sum); 14646 } 14647} 14648 14649/** 14650 * xmlSchemaIsParticleEmptiable: 14651 * @particle: the particle 14652 * 14653 * Schema Component Constraint: Particle Emptiable 14654 * Checks whether the given particle is emptiable. 14655 * 14656 * Returns 1 if emptiable, 0 otherwise. 14657 */ 14658static int 14659xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14660{ 14661 /* 14662 * SPEC (1) "Its {min occurs} is 0." 14663 */ 14664 if ((particle == NULL) || (particle->minOccurs == 0) || 14665 (particle->children == NULL)) 14666 return (1); 14667 /* 14668 * SPEC (2) "Its {term} is a group and the minimum part of the 14669 * effective total range of that group, [...] is 0." 14670 */ 14671 if (WXS_IS_MODEL_GROUP(particle->children)) { 14672 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14673 return (1); 14674 } 14675 return (0); 14676} 14677 14678/** 14679 * xmlSchemaCheckCOSSTDerivedOK: 14680 * @actxt: a context 14681 * @type: the derived simple type definition 14682 * @baseType: the base type definition 14683 * @subset: the subset of ('restriction', ect.) 14684 * 14685 * Schema Component Constraint: 14686 * Type Derivation OK (Simple) (cos-st-derived-OK) 14687 * 14688 * Checks wheter @type can be validly 14689 * derived from @baseType. 14690 * 14691 * Returns 0 on success, an positive error code otherwise. 14692 */ 14693static int 14694xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14695 xmlSchemaTypePtr type, 14696 xmlSchemaTypePtr baseType, 14697 int subset) 14698{ 14699 /* 14700 * 1 They are the same type definition. 14701 * TODO: The identy check might have to be more complex than this. 14702 */ 14703 if (type == baseType) 14704 return (0); 14705 /* 14706 * 2.1 restriction is not in the subset, or in the {final} 14707 * of its own {base type definition}; 14708 * 14709 * NOTE that this will be used also via "xsi:type". 14710 * 14711 * TODO: Revise this, it looks strange. How can the "type" 14712 * not be fixed or *in* fixing? 14713 */ 14714 if (WXS_IS_TYPE_NOT_FIXED(type)) 14715 if (xmlSchemaTypeFixup(type, actxt) == -1) 14716 return(-1); 14717 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14718 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14719 return(-1); 14720 if ((subset & SUBSET_RESTRICTION) || 14721 (xmlSchemaTypeFinalContains(type->baseType, 14722 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14723 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14724 } 14725 /* 2.2 */ 14726 if (type->baseType == baseType) { 14727 /* 14728 * 2.2.1 D's �base type definition� is B. 14729 */ 14730 return (0); 14731 } 14732 /* 14733 * 2.2.2 D's �base type definition� is not the �ur-type definition� 14734 * and is validly derived from B given the subset, as defined by this 14735 * constraint. 14736 */ 14737 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14738 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14739 baseType, subset) == 0)) { 14740 return (0); 14741 } 14742 /* 14743 * 2.2.3 D's {variety} is list or union and B is the �simple ur-type 14744 * definition�. 14745 */ 14746 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14747 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14748 return (0); 14749 } 14750 /* 14751 * 2.2.4 B's {variety} is union and D is validly derived from a type 14752 * definition in B's {member type definitions} given the subset, as 14753 * defined by this constraint. 14754 * 14755 * NOTE: This seems not to involve built-in types, since there is no 14756 * built-in Union Simple Type. 14757 */ 14758 if (WXS_IS_UNION(baseType)) { 14759 xmlSchemaTypeLinkPtr cur; 14760 14761 cur = baseType->memberTypes; 14762 while (cur != NULL) { 14763 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14764 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14765 return(-1); 14766 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14767 type, cur->type, subset) == 0) 14768 { 14769 /* 14770 * It just has to be validly derived from at least one 14771 * member-type. 14772 */ 14773 return (0); 14774 } 14775 cur = cur->next; 14776 } 14777 } 14778 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14779} 14780 14781/** 14782 * xmlSchemaCheckTypeDefCircularInternal: 14783 * @pctxt: the schema parser context 14784 * @ctxtType: the type definition 14785 * @ancestor: an ancestor of @ctxtType 14786 * 14787 * Checks st-props-correct (2) + ct-props-correct (3). 14788 * Circular type definitions are not allowed. 14789 * 14790 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14791 * circular, 0 otherwise. 14792 */ 14793static int 14794xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14795 xmlSchemaTypePtr ctxtType, 14796 xmlSchemaTypePtr ancestor) 14797{ 14798 int ret; 14799 14800 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14801 return (0); 14802 14803 if (ctxtType == ancestor) { 14804 xmlSchemaPCustomErr(pctxt, 14805 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14806 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14807 "The definition is circular", NULL); 14808 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14809 } 14810 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14811 /* 14812 * Avoid inifinite recursion on circular types not yet checked. 14813 */ 14814 return (0); 14815 } 14816 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14817 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14818 ancestor->baseType); 14819 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14820 return (ret); 14821} 14822 14823/** 14824 * xmlSchemaCheckTypeDefCircular: 14825 * @item: the complex/simple type definition 14826 * @ctxt: the parser context 14827 * @name: the name 14828 * 14829 * Checks for circular type definitions. 14830 */ 14831static void 14832xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14833 xmlSchemaParserCtxtPtr ctxt) 14834{ 14835 if ((item == NULL) || 14836 (item->type == XML_SCHEMA_TYPE_BASIC) || 14837 (item->baseType == NULL)) 14838 return; 14839 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14840 item->baseType); 14841} 14842 14843/* 14844* Simple Type Definition Representation OK (src-simple-type) 4 14845* 14846* "4 Circular union type definition is disallowed. That is, if the 14847* <union> alternative is chosen, there must not be any entries in the 14848* memberTypes [attribute] at any depth which resolve to the component 14849* corresponding to the <simpleType>." 14850* 14851* Note that this should work on the *representation* of a component, 14852* thus assumes any union types in the member types not being yet 14853* substituted. At this stage we need the variety of the types 14854* to be already computed. 14855*/ 14856static int 14857xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14858 xmlSchemaTypePtr ctxType, 14859 xmlSchemaTypeLinkPtr members) 14860{ 14861 xmlSchemaTypeLinkPtr member; 14862 xmlSchemaTypePtr memberType; 14863 14864 member = members; 14865 while (member != NULL) { 14866 memberType = member->type; 14867 while ((memberType != NULL) && 14868 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14869 if (memberType == ctxType) { 14870 xmlSchemaPCustomErr(pctxt, 14871 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14872 WXS_BASIC_CAST ctxType, NULL, 14873 "The union type definition is circular", NULL); 14874 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14875 } 14876 if ((WXS_IS_UNION(memberType)) && 14877 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14878 { 14879 int res; 14880 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 14881 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 14882 ctxType, 14883 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 14884 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 14885 if (res != 0) 14886 return(res); 14887 } 14888 memberType = memberType->baseType; 14889 } 14890 member = member->next; 14891 } 14892 return(0); 14893} 14894 14895static int 14896xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 14897 xmlSchemaTypePtr type) 14898{ 14899 if (! WXS_IS_UNION(type)) 14900 return(0); 14901 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 14902 type->memberTypes)); 14903} 14904 14905/** 14906 * xmlSchemaResolveTypeReferences: 14907 * @item: the complex/simple type definition 14908 * @ctxt: the parser context 14909 * @name: the name 14910 * 14911 * Resolvese type definition references 14912 */ 14913static void 14914xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 14915 xmlSchemaParserCtxtPtr ctxt) 14916{ 14917 if (typeDef == NULL) 14918 return; 14919 14920 /* 14921 * Resolve the base type. 14922 */ 14923 if (typeDef->baseType == NULL) { 14924 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 14925 typeDef->base, typeDef->baseNs); 14926 if (typeDef->baseType == NULL) { 14927 xmlSchemaPResCompAttrErr(ctxt, 14928 XML_SCHEMAP_SRC_RESOLVE, 14929 WXS_BASIC_CAST typeDef, typeDef->node, 14930 "base", typeDef->base, typeDef->baseNs, 14931 XML_SCHEMA_TYPE_SIMPLE, NULL); 14932 return; 14933 } 14934 } 14935 if (WXS_IS_SIMPLE(typeDef)) { 14936 if (WXS_IS_UNION(typeDef)) { 14937 /* 14938 * Resolve the memberTypes. 14939 */ 14940 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 14941 return; 14942 } else if (WXS_IS_LIST(typeDef)) { 14943 /* 14944 * Resolve the itemType. 14945 */ 14946 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 14947 14948 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 14949 typeDef->base, typeDef->baseNs); 14950 14951 if ((typeDef->subtypes == NULL) || 14952 (! WXS_IS_SIMPLE(typeDef->subtypes))) 14953 { 14954 typeDef->subtypes = NULL; 14955 xmlSchemaPResCompAttrErr(ctxt, 14956 XML_SCHEMAP_SRC_RESOLVE, 14957 WXS_BASIC_CAST typeDef, typeDef->node, 14958 "itemType", typeDef->base, typeDef->baseNs, 14959 XML_SCHEMA_TYPE_SIMPLE, NULL); 14960 } 14961 } 14962 return; 14963 } 14964 } 14965 /* 14966 * The ball of letters below means, that if we have a particle 14967 * which has a QName-helper component as its {term}, we want 14968 * to resolve it... 14969 */ 14970 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 14971 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 14972 XML_SCHEMA_TYPE_PARTICLE) && 14973 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 14974 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 14975 XML_SCHEMA_EXTRA_QNAMEREF)) 14976 { 14977 xmlSchemaQNameRefPtr ref = 14978 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 14979 xmlSchemaModelGroupDefPtr groupDef; 14980 14981 /* 14982 * URGENT TODO: Test this. 14983 */ 14984 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 14985 /* 14986 * Resolve the MG definition reference. 14987 */ 14988 groupDef = 14989 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 14990 ref->itemType, ref->name, ref->targetNamespace); 14991 if (groupDef == NULL) { 14992 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 14993 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 14994 "ref", ref->name, ref->targetNamespace, ref->itemType, 14995 NULL); 14996 /* Remove the particle. */ 14997 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 14998 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 14999 /* Remove the particle. */ 15000 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15001 else { 15002 /* 15003 * Assign the MG definition's {model group} to the 15004 * particle's {term}. 15005 */ 15006 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15007 15008 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15009 /* 15010 * SPEC cos-all-limited (1.2) 15011 * "1.2 the {term} property of a particle with 15012 * {max occurs}=1 which is part of a pair which constitutes 15013 * the {content type} of a complex type definition." 15014 */ 15015 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15016 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15017 /* TODO: error code */ 15018 XML_SCHEMAP_COS_ALL_LIMITED, 15019 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15020 "The particle's {max occurs} must be 1, since the " 15021 "reference resolves to an 'all' model group", 15022 NULL, NULL); 15023 } 15024 } 15025 } 15026 } 15027} 15028 15029 15030 15031/** 15032 * xmlSchemaCheckSTPropsCorrect: 15033 * @ctxt: the schema parser context 15034 * @type: the simple type definition 15035 * 15036 * Checks st-props-correct. 15037 * 15038 * Returns 0 if the properties are correct, 15039 * if not, a positive error code and -1 on internal 15040 * errors. 15041 */ 15042static int 15043xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15044 xmlSchemaTypePtr type) 15045{ 15046 xmlSchemaTypePtr baseType = type->baseType; 15047 xmlChar *str = NULL; 15048 15049 /* STATE: error funcs converted. */ 15050 /* 15051 * Schema Component Constraint: Simple Type Definition Properties Correct 15052 * 15053 * NOTE: This is somehow redundant, since we actually built a simple type 15054 * to have all the needed information; this acts as an self test. 15055 */ 15056 /* Base type: If the datatype has been �derived� by �restriction� 15057 * then the Simple Type Definition component from which it is �derived�, 15058 * otherwise the Simple Type Definition for anySimpleType (�4.1.6). 15059 */ 15060 if (baseType == NULL) { 15061 /* 15062 * TODO: Think about: "modulo the impact of Missing 15063 * Sub-components (�5.3)." 15064 */ 15065 xmlSchemaPCustomErr(ctxt, 15066 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15067 WXS_BASIC_CAST type, NULL, 15068 "No base type existent", NULL); 15069 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15070 15071 } 15072 if (! WXS_IS_SIMPLE(baseType)) { 15073 xmlSchemaPCustomErr(ctxt, 15074 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15075 WXS_BASIC_CAST type, NULL, 15076 "The base type '%s' is not a simple type", 15077 xmlSchemaGetComponentQName(&str, baseType)); 15078 FREE_AND_NULL(str) 15079 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15080 } 15081 if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15082 (WXS_IS_RESTRICTION(type) == 0) && 15083 (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) { 15084 xmlSchemaPCustomErr(ctxt, 15085 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15086 WXS_BASIC_CAST type, NULL, 15087 "A type, derived by list or union, must have" 15088 "the simple ur-type definition as base type, not '%s'", 15089 xmlSchemaGetComponentQName(&str, baseType)); 15090 FREE_AND_NULL(str) 15091 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15092 } 15093 /* 15094 * Variety: One of {atomic, list, union}. 15095 */ 15096 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15097 (! WXS_IS_LIST(type))) { 15098 xmlSchemaPCustomErr(ctxt, 15099 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15100 WXS_BASIC_CAST type, NULL, 15101 "The variety is absent", NULL); 15102 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15103 } 15104 /* TODO: Finish this. Hmm, is this finished? */ 15105 15106 /* 15107 * 3 The {final} of the {base type definition} must not contain restriction. 15108 */ 15109 if (xmlSchemaTypeFinalContains(baseType, 15110 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15111 xmlSchemaPCustomErr(ctxt, 15112 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15113 WXS_BASIC_CAST type, NULL, 15114 "The 'final' of its base type '%s' must not contain " 15115 "'restriction'", 15116 xmlSchemaGetComponentQName(&str, baseType)); 15117 FREE_AND_NULL(str) 15118 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15119 } 15120 15121 /* 15122 * 2 All simple type definitions must be derived ultimately from the �simple 15123 * ur-type definition (so� circular definitions are disallowed). That is, it 15124 * must be possible to reach a built-in primitive datatype or the �simple 15125 * ur-type definition� by repeatedly following the {base type definition}. 15126 * 15127 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15128 */ 15129 return (0); 15130} 15131 15132/** 15133 * xmlSchemaCheckCOSSTRestricts: 15134 * @ctxt: the schema parser context 15135 * @type: the simple type definition 15136 * 15137 * Schema Component Constraint: 15138 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15139 15140 * Checks if the given @type (simpleType) is derived validly by restriction. 15141 * STATUS: 15142 * 15143 * Returns -1 on internal errors, 0 if the type is validly derived, 15144 * a positive error code otherwise. 15145 */ 15146static int 15147xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15148 xmlSchemaTypePtr type) 15149{ 15150 xmlChar *str = NULL; 15151 15152 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15153 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15154 "given type is not a user-derived simpleType"); 15155 return (-1); 15156 } 15157 15158 if (WXS_IS_ATOMIC(type)) { 15159 xmlSchemaTypePtr primitive; 15160 /* 15161 * 1.1 The {base type definition} must be an atomic simple 15162 * type definition or a built-in primitive datatype. 15163 */ 15164 if (! WXS_IS_ATOMIC(type->baseType)) { 15165 xmlSchemaPCustomErr(pctxt, 15166 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15167 WXS_BASIC_CAST type, NULL, 15168 "The base type '%s' is not an atomic simple type", 15169 xmlSchemaGetComponentQName(&str, type->baseType)); 15170 FREE_AND_NULL(str) 15171 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15172 } 15173 /* 1.2 The {final} of the {base type definition} must not contain 15174 * restriction. 15175 */ 15176 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15177 if (xmlSchemaTypeFinalContains(type->baseType, 15178 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15179 xmlSchemaPCustomErr(pctxt, 15180 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15181 WXS_BASIC_CAST type, NULL, 15182 "The final of its base type '%s' must not contain 'restriction'", 15183 xmlSchemaGetComponentQName(&str, type->baseType)); 15184 FREE_AND_NULL(str) 15185 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15186 } 15187 15188 /* 15189 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15190 * type definition}, as specified in the appropriate subsection of 3.2 15191 * Primitive datatypes. 15192 */ 15193 if (type->facets != NULL) { 15194 xmlSchemaFacetPtr facet; 15195 int ok = 1; 15196 15197 primitive = xmlSchemaGetPrimitiveType(type); 15198 if (primitive == NULL) { 15199 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15200 "failed to get primitive type"); 15201 return (-1); 15202 } 15203 facet = type->facets; 15204 do { 15205 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15206 ok = 0; 15207 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15208 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15209 type, primitive, facet); 15210 } 15211 facet = facet->next; 15212 } while (facet != NULL); 15213 if (ok == 0) 15214 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15215 } 15216 /* 15217 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15218 * of the {base type definition} (call this BF),then the DF's {value} 15219 * must be a valid restriction of BF's {value} as defined in 15220 * [XML Schemas: Datatypes]." 15221 * 15222 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15223 * xmlSchemaDeriveAndValidateFacets() 15224 */ 15225 } else if (WXS_IS_LIST(type)) { 15226 xmlSchemaTypePtr itemType = NULL; 15227 15228 itemType = type->subtypes; 15229 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15230 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15231 "failed to evaluate the item type"); 15232 return (-1); 15233 } 15234 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15235 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15236 /* 15237 * 2.1 The {item type definition} must have a {variety} of atomic or 15238 * union (in which case all the {member type definitions} 15239 * must be atomic). 15240 */ 15241 if ((! WXS_IS_ATOMIC(itemType)) && 15242 (! WXS_IS_UNION(itemType))) { 15243 xmlSchemaPCustomErr(pctxt, 15244 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15245 WXS_BASIC_CAST type, NULL, 15246 "The item type '%s' does not have a variety of atomic or union", 15247 xmlSchemaGetComponentQName(&str, itemType)); 15248 FREE_AND_NULL(str) 15249 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15250 } else if (WXS_IS_UNION(itemType)) { 15251 xmlSchemaTypeLinkPtr member; 15252 15253 member = itemType->memberTypes; 15254 while (member != NULL) { 15255 if (! WXS_IS_ATOMIC(member->type)) { 15256 xmlSchemaPCustomErr(pctxt, 15257 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15258 WXS_BASIC_CAST type, NULL, 15259 "The item type is a union type, but the " 15260 "member type '%s' of this item type is not atomic", 15261 xmlSchemaGetComponentQName(&str, member->type)); 15262 FREE_AND_NULL(str) 15263 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15264 } 15265 member = member->next; 15266 } 15267 } 15268 15269 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15270 xmlSchemaFacetPtr facet; 15271 /* 15272 * This is the case if we have: <simpleType><list .. 15273 */ 15274 /* 15275 * 2.3.1 15276 * 2.3.1.1 The {final} of the {item type definition} must not 15277 * contain list. 15278 */ 15279 if (xmlSchemaTypeFinalContains(itemType, 15280 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15281 xmlSchemaPCustomErr(pctxt, 15282 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15283 WXS_BASIC_CAST type, NULL, 15284 "The final of its item type '%s' must not contain 'list'", 15285 xmlSchemaGetComponentQName(&str, itemType)); 15286 FREE_AND_NULL(str) 15287 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15288 } 15289 /* 15290 * 2.3.1.2 The {facets} must only contain the whiteSpace 15291 * facet component. 15292 * OPTIMIZE TODO: the S4S already disallows any facet 15293 * to be specified. 15294 */ 15295 if (type->facets != NULL) { 15296 facet = type->facets; 15297 do { 15298 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15299 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15300 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15301 type, facet); 15302 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15303 } 15304 facet = facet->next; 15305 } while (facet != NULL); 15306 } 15307 /* 15308 * MAYBE TODO: (Hmm, not really) Datatypes states: 15309 * A �list� datatype can be �derived� from an �atomic� datatype 15310 * whose �lexical space� allows space (such as string or anyURI)or 15311 * a �union� datatype any of whose {member type definitions}'s 15312 * �lexical space� allows space. 15313 */ 15314 } else { 15315 /* 15316 * This is the case if we have: <simpleType><restriction ... 15317 * I.e. the variety of "list" is inherited. 15318 */ 15319 /* 15320 * 2.3.2 15321 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15322 */ 15323 if (! WXS_IS_LIST(type->baseType)) { 15324 xmlSchemaPCustomErr(pctxt, 15325 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15326 WXS_BASIC_CAST type, NULL, 15327 "The base type '%s' must be a list type", 15328 xmlSchemaGetComponentQName(&str, type->baseType)); 15329 FREE_AND_NULL(str) 15330 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15331 } 15332 /* 15333 * 2.3.2.2 The {final} of the {base type definition} must not 15334 * contain restriction. 15335 */ 15336 if (xmlSchemaTypeFinalContains(type->baseType, 15337 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15338 xmlSchemaPCustomErr(pctxt, 15339 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15340 WXS_BASIC_CAST type, NULL, 15341 "The 'final' of the base type '%s' must not contain 'restriction'", 15342 xmlSchemaGetComponentQName(&str, type->baseType)); 15343 FREE_AND_NULL(str) 15344 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15345 } 15346 /* 15347 * 2.3.2.3 The {item type definition} must be validly derived 15348 * from the {base type definition}'s {item type definition} given 15349 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6). 15350 */ 15351 { 15352 xmlSchemaTypePtr baseItemType; 15353 15354 baseItemType = type->baseType->subtypes; 15355 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15356 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15357 "failed to eval the item type of a base type"); 15358 return (-1); 15359 } 15360 if ((itemType != baseItemType) && 15361 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15362 baseItemType, 0) != 0)) { 15363 xmlChar *strBIT = NULL, *strBT = NULL; 15364 xmlSchemaPCustomErrExt(pctxt, 15365 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15366 WXS_BASIC_CAST type, NULL, 15367 "The item type '%s' is not validly derived from " 15368 "the item type '%s' of the base type '%s'", 15369 xmlSchemaGetComponentQName(&str, itemType), 15370 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15371 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15372 15373 FREE_AND_NULL(str) 15374 FREE_AND_NULL(strBIT) 15375 FREE_AND_NULL(strBT) 15376 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15377 } 15378 } 15379 15380 if (type->facets != NULL) { 15381 xmlSchemaFacetPtr facet; 15382 int ok = 1; 15383 /* 15384 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15385 * and enumeration facet components are allowed among the {facets}. 15386 */ 15387 facet = type->facets; 15388 do { 15389 switch (facet->type) { 15390 case XML_SCHEMA_FACET_LENGTH: 15391 case XML_SCHEMA_FACET_MINLENGTH: 15392 case XML_SCHEMA_FACET_MAXLENGTH: 15393 case XML_SCHEMA_FACET_WHITESPACE: 15394 /* 15395 * TODO: 2.5.1.2 List datatypes 15396 * The value of �whiteSpace� is fixed to the value collapse. 15397 */ 15398 case XML_SCHEMA_FACET_PATTERN: 15399 case XML_SCHEMA_FACET_ENUMERATION: 15400 break; 15401 default: { 15402 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15403 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15404 type, facet); 15405 /* 15406 * We could return, but it's nicer to report all 15407 * invalid facets. 15408 */ 15409 ok = 0; 15410 } 15411 } 15412 facet = facet->next; 15413 } while (facet != NULL); 15414 if (ok == 0) 15415 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15416 /* 15417 * SPEC (2.3.2.5) (same as 1.3.2) 15418 * 15419 * NOTE (2.3.2.5) This is currently done in 15420 * xmlSchemaDeriveAndValidateFacets() 15421 */ 15422 } 15423 } 15424 } else if (WXS_IS_UNION(type)) { 15425 /* 15426 * 3.1 The {member type definitions} must all have {variety} of 15427 * atomic or list. 15428 */ 15429 xmlSchemaTypeLinkPtr member; 15430 15431 member = type->memberTypes; 15432 while (member != NULL) { 15433 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15434 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15435 15436 if ((! WXS_IS_ATOMIC(member->type)) && 15437 (! WXS_IS_LIST(member->type))) { 15438 xmlSchemaPCustomErr(pctxt, 15439 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15440 WXS_BASIC_CAST type, NULL, 15441 "The member type '%s' is neither an atomic, nor a list type", 15442 xmlSchemaGetComponentQName(&str, member->type)); 15443 FREE_AND_NULL(str) 15444 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15445 } 15446 member = member->next; 15447 } 15448 /* 15449 * 3.3.1 If the {base type definition} is the �simple ur-type 15450 * definition� 15451 */ 15452 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15453 /* 15454 * 3.3.1.1 All of the {member type definitions} must have a 15455 * {final} which does not contain union. 15456 */ 15457 member = type->memberTypes; 15458 while (member != NULL) { 15459 if (xmlSchemaTypeFinalContains(member->type, 15460 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15461 xmlSchemaPCustomErr(pctxt, 15462 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15463 WXS_BASIC_CAST type, NULL, 15464 "The 'final' of member type '%s' contains 'union'", 15465 xmlSchemaGetComponentQName(&str, member->type)); 15466 FREE_AND_NULL(str) 15467 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15468 } 15469 member = member->next; 15470 } 15471 /* 15472 * 3.3.1.2 The {facets} must be empty. 15473 */ 15474 if (type->facetSet != NULL) { 15475 xmlSchemaPCustomErr(pctxt, 15476 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15477 WXS_BASIC_CAST type, NULL, 15478 "No facets allowed", NULL); 15479 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15480 } 15481 } else { 15482 /* 15483 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15484 * I.e. the variety of "list" is inherited. 15485 */ 15486 if (! WXS_IS_UNION(type->baseType)) { 15487 xmlSchemaPCustomErr(pctxt, 15488 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15489 WXS_BASIC_CAST type, NULL, 15490 "The base type '%s' is not a union type", 15491 xmlSchemaGetComponentQName(&str, type->baseType)); 15492 FREE_AND_NULL(str) 15493 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15494 } 15495 /* 15496 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15497 */ 15498 if (xmlSchemaTypeFinalContains(type->baseType, 15499 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15500 xmlSchemaPCustomErr(pctxt, 15501 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15502 WXS_BASIC_CAST type, NULL, 15503 "The 'final' of its base type '%s' must not contain 'restriction'", 15504 xmlSchemaGetComponentQName(&str, type->baseType)); 15505 FREE_AND_NULL(str) 15506 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15507 } 15508 /* 15509 * 3.3.2.3 The {member type definitions}, in order, must be validly 15510 * derived from the corresponding type definitions in the {base 15511 * type definition}'s {member type definitions} given the empty set, 15512 * as defined in Type Derivation OK (Simple) (�3.14.6). 15513 */ 15514 { 15515 xmlSchemaTypeLinkPtr baseMember; 15516 15517 /* 15518 * OPTIMIZE: if the type is restricting, it has no local defined 15519 * member types and inherits the member types of the base type; 15520 * thus a check for equality can be skipped. 15521 */ 15522 /* 15523 * Even worse: I cannot see a scenario where a restricting 15524 * union simple type can have other member types as the member 15525 * types of it's base type. This check seems not necessary with 15526 * respect to the derivation process in libxml2. 15527 * But necessary if constructing types with an API. 15528 */ 15529 if (type->memberTypes != NULL) { 15530 member = type->memberTypes; 15531 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15532 if ((member == NULL) && (baseMember != NULL)) { 15533 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15534 "different number of member types in base"); 15535 } 15536 while (member != NULL) { 15537 if (baseMember == NULL) { 15538 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15539 "different number of member types in base"); 15540 } else if ((member->type != baseMember->type) && 15541 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15542 member->type, baseMember->type, 0) != 0)) { 15543 xmlChar *strBMT = NULL, *strBT = NULL; 15544 15545 xmlSchemaPCustomErrExt(pctxt, 15546 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15547 WXS_BASIC_CAST type, NULL, 15548 "The member type %s is not validly " 15549 "derived from its corresponding member " 15550 "type %s of the base type %s", 15551 xmlSchemaGetComponentQName(&str, member->type), 15552 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15553 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15554 FREE_AND_NULL(str) 15555 FREE_AND_NULL(strBMT) 15556 FREE_AND_NULL(strBT) 15557 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15558 } 15559 member = member->next; 15560 baseMember = baseMember->next; 15561 } 15562 } 15563 } 15564 /* 15565 * 3.3.2.4 Only pattern and enumeration facet components are 15566 * allowed among the {facets}. 15567 */ 15568 if (type->facets != NULL) { 15569 xmlSchemaFacetPtr facet; 15570 int ok = 1; 15571 15572 facet = type->facets; 15573 do { 15574 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15575 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15576 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15577 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15578 type, facet); 15579 ok = 0; 15580 } 15581 facet = facet->next; 15582 } while (facet != NULL); 15583 if (ok == 0) 15584 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15585 15586 } 15587 /* 15588 * SPEC (3.3.2.5) (same as 1.3.2) 15589 * 15590 * NOTE (3.3.2.5) This is currently done in 15591 * xmlSchemaDeriveAndValidateFacets() 15592 */ 15593 } 15594 } 15595 15596 return (0); 15597} 15598 15599/** 15600 * xmlSchemaCheckSRCSimpleType: 15601 * @ctxt: the schema parser context 15602 * @type: the simple type definition 15603 * 15604 * Checks crc-simple-type constraints. 15605 * 15606 * Returns 0 if the constraints are satisfied, 15607 * if not a positive error code and -1 on internal 15608 * errors. 15609 */ 15610#if 0 15611static int 15612xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15613 xmlSchemaTypePtr type) 15614{ 15615 /* 15616 * src-simple-type.1 The corresponding simple type definition, if any, 15617 * must satisfy the conditions set out in Constraints on Simple Type 15618 * Definition Schema Components (�3.14.6). 15619 */ 15620 if (WXS_IS_RESTRICTION(type)) { 15621 /* 15622 * src-simple-type.2 "If the <restriction> alternative is chosen, 15623 * either it must have a base [attribute] or a <simpleType> among its 15624 * [children], but not both." 15625 * NOTE: This is checked in the parse function of <restriction>. 15626 */ 15627 /* 15628 * 15629 */ 15630 } else if (WXS_IS_LIST(type)) { 15631 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15632 * an itemType [attribute] or a <simpleType> among its [children], 15633 * but not both." 15634 * 15635 * NOTE: This is checked in the parse function of <list>. 15636 */ 15637 } else if (WXS_IS_UNION(type)) { 15638 /* 15639 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15640 */ 15641 } 15642 return (0); 15643} 15644#endif 15645 15646static int 15647xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15648{ 15649 if (ctxt->vctxt == NULL) { 15650 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15651 if (ctxt->vctxt == NULL) { 15652 xmlSchemaPErr(ctxt, NULL, 15653 XML_SCHEMAP_INTERNAL, 15654 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15655 "failed to create a temp. validation context.\n", 15656 NULL, NULL); 15657 return (-1); 15658 } 15659 /* TODO: Pass user data. */ 15660 xmlSchemaSetValidErrors(ctxt->vctxt, 15661 ctxt->error, ctxt->warning, ctxt->errCtxt); 15662 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15663 ctxt->serror, ctxt->errCtxt); 15664 } 15665 return (0); 15666} 15667 15668static int 15669xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15670 xmlNodePtr node, 15671 xmlSchemaTypePtr type, 15672 const xmlChar *value, 15673 xmlSchemaValPtr *retVal, 15674 int fireErrors, 15675 int normalize, 15676 int isNormalized); 15677 15678/** 15679 * xmlSchemaParseCheckCOSValidDefault: 15680 * @pctxt: the schema parser context 15681 * @type: the simple type definition 15682 * @value: the default value 15683 * @node: an optional node (the holder of the value) 15684 * 15685 * Schema Component Constraint: Element Default Valid (Immediate) 15686 * (cos-valid-default) 15687 * This will be used by the parser only. For the validator there's 15688 * an other version. 15689 * 15690 * Returns 0 if the constraints are satisfied, 15691 * if not, a positive error code and -1 on internal 15692 * errors. 15693 */ 15694static int 15695xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15696 xmlNodePtr node, 15697 xmlSchemaTypePtr type, 15698 const xmlChar *value, 15699 xmlSchemaValPtr *val) 15700{ 15701 int ret = 0; 15702 15703 /* 15704 * cos-valid-default: 15705 * Schema Component Constraint: Element Default Valid (Immediate) 15706 * For a string to be a valid default with respect to a type 15707 * definition the appropriate case among the following must be true: 15708 */ 15709 if WXS_IS_COMPLEX(type) { 15710 /* 15711 * Complex type. 15712 * 15713 * SPEC (2.1) "its {content type} must be a simple type definition 15714 * or mixed." 15715 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15716 * type}'s particle must be �emptiable� as defined by 15717 * Particle Emptiable (�3.9.6)." 15718 */ 15719 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15720 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15721 /* NOTE that this covers (2.2.2) as well. */ 15722 xmlSchemaPCustomErr(pctxt, 15723 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15724 WXS_BASIC_CAST type, type->node, 15725 "For a string to be a valid default, the type definition " 15726 "must be a simple type or a complex type with mixed content " 15727 "and a particle emptiable", NULL); 15728 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15729 } 15730 } 15731 /* 15732 * 1 If the type definition is a simple type definition, then the string 15733 * must be �valid� with respect to that definition as defined by String 15734 * Valid (�3.14.4). 15735 * 15736 * AND 15737 * 15738 * 2.2.1 If the {content type} is a simple type definition, then the 15739 * string must be �valid� with respect to that simple type definition 15740 * as defined by String Valid (�3.14.4). 15741 */ 15742 if (WXS_IS_SIMPLE(type)) 15743 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15744 type, value, val, 1, 1, 0); 15745 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15746 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15747 type->contentTypeDef, value, val, 1, 1, 0); 15748 else 15749 return (ret); 15750 15751 if (ret < 0) { 15752 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15753 "calling xmlSchemaVCheckCVCSimpleType()"); 15754 } 15755 15756 return (ret); 15757} 15758 15759/** 15760 * xmlSchemaCheckCTPropsCorrect: 15761 * @ctxt: the schema parser context 15762 * @type: the complex type definition 15763 * 15764 *.(4.6) Constraints on Complex Type Definition Schema Components 15765 * Schema Component Constraint: 15766 * Complex Type Definition Properties Correct (ct-props-correct) 15767 * STATUS: (seems) complete 15768 * 15769 * Returns 0 if the constraints are satisfied, a positive 15770 * error code if not and -1 if an internal error occured. 15771 */ 15772static int 15773xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15774 xmlSchemaTypePtr type) 15775{ 15776 /* 15777 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15778 * 15779 * SPEC (1) "The values of the properties of a complex type definition must 15780 * be as described in the property tableau in The Complex Type Definition 15781 * Schema Component (�3.4.1), modulo the impact of Missing 15782 * Sub-components (�5.3)." 15783 */ 15784 if ((type->baseType != NULL) && 15785 (WXS_IS_SIMPLE(type->baseType)) && 15786 (WXS_IS_EXTENSION(type) == 0)) { 15787 /* 15788 * SPEC (2) "If the {base type definition} is a simple type definition, 15789 * the {derivation method} must be extension." 15790 */ 15791 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15792 XML_SCHEMAP_SRC_CT_1, 15793 NULL, WXS_BASIC_CAST type, 15794 "If the base type is a simple type, the derivation method must be " 15795 "'extension'", NULL, NULL); 15796 return (XML_SCHEMAP_SRC_CT_1); 15797 } 15798 /* 15799 * SPEC (3) "Circular definitions are disallowed, except for the �ur-type 15800 * definition�. That is, it must be possible to reach the �ur-type 15801 * definition by repeatedly following the {base type definition}." 15802 * 15803 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15804 */ 15805 /* 15806 * NOTE that (4) and (5) need the following: 15807 * - attribute uses need to be already inherited (apply attr. prohibitions) 15808 * - attribute group references need to be expanded already 15809 * - simple types need to be typefixed already 15810 */ 15811 if (type->attrUses && 15812 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15813 { 15814 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15815 xmlSchemaAttributeUsePtr use, tmp; 15816 int i, j, hasId = 0; 15817 15818 for (i = uses->nbItems -1; i >= 0; i--) { 15819 use = uses->items[i]; 15820 15821 /* 15822 * SPEC ct-props-correct 15823 * (4) "Two distinct attribute declarations in the 15824 * {attribute uses} must not have identical {name}s and 15825 * {target namespace}s." 15826 */ 15827 if (i > 0) { 15828 for (j = i -1; j >= 0; j--) { 15829 tmp = uses->items[j]; 15830 if ((WXS_ATTRUSE_DECL_NAME(use) == 15831 WXS_ATTRUSE_DECL_NAME(tmp)) && 15832 (WXS_ATTRUSE_DECL_TNS(use) == 15833 WXS_ATTRUSE_DECL_TNS(tmp))) 15834 { 15835 xmlChar *str = NULL; 15836 15837 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15838 XML_SCHEMAP_AG_PROPS_CORRECT, 15839 NULL, WXS_BASIC_CAST type, 15840 "Duplicate %s", 15841 xmlSchemaGetComponentDesignation(&str, use), 15842 NULL); 15843 FREE_AND_NULL(str); 15844 /* 15845 * Remove the duplicate. 15846 */ 15847 if (xmlSchemaItemListRemove(uses, i) == -1) 15848 goto exit_failure; 15849 goto next_use; 15850 } 15851 } 15852 } 15853 /* 15854 * SPEC ct-props-correct 15855 * (5) "Two distinct attribute declarations in the 15856 * {attribute uses} must not have {type definition}s which 15857 * are or are derived from ID." 15858 */ 15859 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15860 if (xmlSchemaIsDerivedFromBuiltInType( 15861 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15862 { 15863 if (hasId) { 15864 xmlChar *str = NULL; 15865 15866 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15867 XML_SCHEMAP_AG_PROPS_CORRECT, 15868 NULL, WXS_BASIC_CAST type, 15869 "There must not exist more than one attribute " 15870 "declaration of type 'xs:ID' " 15871 "(or derived from 'xs:ID'). The %s violates this " 15872 "constraint", 15873 xmlSchemaGetComponentDesignation(&str, use), 15874 NULL); 15875 FREE_AND_NULL(str); 15876 if (xmlSchemaItemListRemove(uses, i) == -1) 15877 goto exit_failure; 15878 } 15879 15880 hasId = 1; 15881 } 15882 } 15883next_use: {} 15884 } 15885 } 15886 return (0); 15887exit_failure: 15888 return(-1); 15889} 15890 15891static int 15892xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 15893 xmlSchemaTypePtr typeB) 15894{ 15895 /* 15896 * TODO: This should implement component-identity 15897 * in the future. 15898 */ 15899 if ((typeA == NULL) || (typeB == NULL)) 15900 return (0); 15901 return (typeA == typeB); 15902} 15903 15904/** 15905 * xmlSchemaCheckCOSCTDerivedOK: 15906 * @ctxt: the schema parser context 15907 * @type: the to-be derived complex type definition 15908 * @baseType: the base complex type definition 15909 * @set: the given set 15910 * 15911 * Schema Component Constraint: 15912 * Type Derivation OK (Complex) (cos-ct-derived-ok) 15913 * 15914 * STATUS: completed 15915 * 15916 * Returns 0 if the constraints are satisfied, or 1 15917 * if not. 15918 */ 15919static int 15920xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 15921 xmlSchemaTypePtr type, 15922 xmlSchemaTypePtr baseType, 15923 int set) 15924{ 15925 int equal = xmlSchemaAreEqualTypes(type, baseType); 15926 /* TODO: Error codes. */ 15927 /* 15928 * SPEC "For a complex type definition (call it D, for derived) 15929 * to be validly derived from a type definition (call this 15930 * B, for base) given a subset of {extension, restriction} 15931 * all of the following must be true:" 15932 */ 15933 if (! equal) { 15934 /* 15935 * SPEC (1) "If B and D are not the same type definition, then the 15936 * {derivation method} of D must not be in the subset." 15937 */ 15938 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 15939 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 15940 return (1); 15941 } else { 15942 /* 15943 * SPEC (2.1) "B and D must be the same type definition." 15944 */ 15945 return (0); 15946 } 15947 /* 15948 * SPEC (2.2) "B must be D's {base type definition}." 15949 */ 15950 if (type->baseType == baseType) 15951 return (0); 15952 /* 15953 * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type 15954 * definition�." 15955 */ 15956 if (WXS_IS_ANYTYPE(type->baseType)) 15957 return (1); 15958 15959 if (WXS_IS_COMPLEX(type->baseType)) { 15960 /* 15961 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 15962 * must be validly derived from B given the subset as defined by this 15963 * constraint." 15964 */ 15965 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 15966 baseType, set)); 15967 } else { 15968 /* 15969 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 15970 * must be validly derived from B given the subset as defined in Type 15971 * Derivation OK (Simple) (�3.14.6). 15972 */ 15973 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 15974 baseType, set)); 15975 } 15976} 15977 15978/** 15979 * xmlSchemaCheckCOSDerivedOK: 15980 * @type: the derived simple type definition 15981 * @baseType: the base type definition 15982 * 15983 * Calls: 15984 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 15985 * 15986 * Checks wheter @type can be validly derived from @baseType. 15987 * 15988 * Returns 0 on success, an positive error code otherwise. 15989 */ 15990static int 15991xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 15992 xmlSchemaTypePtr type, 15993 xmlSchemaTypePtr baseType, 15994 int set) 15995{ 15996 if (WXS_IS_SIMPLE(type)) 15997 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 15998 else 15999 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16000} 16001 16002/** 16003 * xmlSchemaCheckCOSCTExtends: 16004 * @ctxt: the schema parser context 16005 * @type: the complex type definition 16006 * 16007 * (3.4.6) Constraints on Complex Type Definition Schema Components 16008 * Schema Component Constraint: 16009 * Derivation Valid (Extension) (cos-ct-extends) 16010 * 16011 * STATUS: 16012 * missing: 16013 * (1.5) 16014 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16015 * 16016 * Returns 0 if the constraints are satisfied, a positive 16017 * error code if not and -1 if an internal error occured. 16018 */ 16019static int 16020xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16021 xmlSchemaTypePtr type) 16022{ 16023 xmlSchemaTypePtr base = type->baseType; 16024 /* 16025 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16026 * temporarily only. 16027 */ 16028 /* 16029 * SPEC (1) "If the {base type definition} is a complex type definition, 16030 * then all of the following must be true:" 16031 */ 16032 if (WXS_IS_COMPLEX(base)) { 16033 /* 16034 * SPEC (1.1) "The {final} of the {base type definition} must not 16035 * contain extension." 16036 */ 16037 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16038 xmlSchemaPCustomErr(ctxt, 16039 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16040 WXS_BASIC_CAST type, NULL, 16041 "The 'final' of the base type definition " 16042 "contains 'extension'", NULL); 16043 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16044 } 16045 16046 /* 16047 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16048 * since they are automatically satisfied through the 16049 * inheriting mechanism. 16050 * Note that even if redefining components, the inheriting mechanism 16051 * is used. 16052 */ 16053#if 0 16054 /* 16055 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16056 * uses} 16057 * of the complex type definition itself, that is, for every attribute 16058 * use in the {attribute uses} of the {base type definition}, there 16059 * must be an attribute use in the {attribute uses} of the complex 16060 * type definition itself whose {attribute declaration} has the same 16061 * {name}, {target namespace} and {type definition} as its attribute 16062 * declaration" 16063 */ 16064 if (base->attrUses != NULL) { 16065 int i, j, found; 16066 xmlSchemaAttributeUsePtr use, buse; 16067 16068 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16069 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16070 found = 0; 16071 if (type->attrUses != NULL) { 16072 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16073 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16074 { 16075 if ((WXS_ATTRUSE_DECL_NAME(use) == 16076 WXS_ATTRUSE_DECL_NAME(buse)) && 16077 (WXS_ATTRUSE_DECL_TNS(use) == 16078 WXS_ATTRUSE_DECL_TNS(buse)) && 16079 (WXS_ATTRUSE_TYPEDEF(use) == 16080 WXS_ATTRUSE_TYPEDEF(buse)) 16081 { 16082 found = 1; 16083 break; 16084 } 16085 } 16086 } 16087 if (! found) { 16088 xmlChar *str = NULL; 16089 16090 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16091 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16092 NULL, WXS_BASIC_CAST type, 16093 /* 16094 * TODO: The report does not indicate that also the 16095 * type needs to be the same. 16096 */ 16097 "This type is missing a matching correspondent " 16098 "for its {base type}'s %s in its {attribute uses}", 16099 xmlSchemaGetComponentDesignation(&str, 16100 buse->children), 16101 NULL); 16102 FREE_AND_NULL(str) 16103 } 16104 } 16105 } 16106 /* 16107 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16108 * definition must also have one, and the base type definition's 16109 * {attribute wildcard}'s {namespace constraint} must be a subset 16110 * of the complex type definition's {attribute wildcard}'s {namespace 16111 * constraint}, as defined by Wildcard Subset (�3.10.6)." 16112 */ 16113 16114 /* 16115 * MAYBE TODO: Enable if ever needed. But this will be needed only 16116 * if created the type via a schema construction API. 16117 */ 16118 if (base->attributeWildcard != NULL) { 16119 if (type->attributeWilcard == NULL) { 16120 xmlChar *str = NULL; 16121 16122 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16123 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16124 NULL, type, 16125 "The base %s has an attribute wildcard, " 16126 "but this type is missing an attribute wildcard", 16127 xmlSchemaGetComponentDesignation(&str, base)); 16128 FREE_AND_NULL(str) 16129 16130 } else if (xmlSchemaCheckCOSNSSubset( 16131 base->attributeWildcard, type->attributeWildcard)) 16132 { 16133 xmlChar *str = NULL; 16134 16135 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16136 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16137 NULL, type, 16138 "The attribute wildcard is not a valid " 16139 "superset of the one in the base %s", 16140 xmlSchemaGetComponentDesignation(&str, base)); 16141 FREE_AND_NULL(str) 16142 } 16143 } 16144#endif 16145 /* 16146 * SPEC (1.4) "One of the following must be true:" 16147 */ 16148 if ((type->contentTypeDef != NULL) && 16149 (type->contentTypeDef == base->contentTypeDef)) { 16150 /* 16151 * SPEC (1.4.1) "The {content type} of the {base type definition} 16152 * and the {content type} of the complex type definition itself 16153 * must be the same simple type definition" 16154 * PASS 16155 */ 16156 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16157 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16158 /* 16159 * SPEC (1.4.2) "The {content type} of both the {base type 16160 * definition} and the complex type definition itself must 16161 * be empty." 16162 * PASS 16163 */ 16164 } else { 16165 /* 16166 * SPEC (1.4.3) "All of the following must be true:" 16167 */ 16168 if (type->subtypes == NULL) { 16169 /* 16170 * SPEC 1.4.3.1 The {content type} of the complex type 16171 * definition itself must specify a particle. 16172 */ 16173 xmlSchemaPCustomErr(ctxt, 16174 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16175 WXS_BASIC_CAST type, NULL, 16176 "The content type must specify a particle", NULL); 16177 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16178 } 16179 /* 16180 * SPEC (1.4.3.2) "One of the following must be true:" 16181 */ 16182 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16183 /* 16184 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16185 * definition} must be empty. 16186 * PASS 16187 */ 16188 } else { 16189 /* 16190 * SPEC (1.4.3.2.2) "All of the following must be true:" 16191 */ 16192 if ((type->contentType != base->contentType) || 16193 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16194 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16195 /* 16196 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16197 * or both must be element-only." 16198 */ 16199 xmlSchemaPCustomErr(ctxt, 16200 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16201 WXS_BASIC_CAST type, NULL, 16202 "The content type of both, the type and its base " 16203 "type, must either 'mixed' or 'element-only'", NULL); 16204 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16205 } 16206 /* 16207 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16208 * complex type definition must be a �valid extension� 16209 * of the {base type definition}'s particle, as defined 16210 * in Particle Valid (Extension) (�3.9.6)." 16211 * 16212 * NOTE that we won't check "Particle Valid (Extension)", 16213 * since it is ensured by the derivation process in 16214 * xmlSchemaTypeFixup(). We need to implement this when heading 16215 * for a construction API 16216 * TODO: !! This is needed to be checked if redefining a type !! 16217 */ 16218 } 16219 /* 16220 * URGENT TODO (1.5) 16221 */ 16222 } 16223 } else { 16224 /* 16225 * SPEC (2) "If the {base type definition} is a simple type definition, 16226 * then all of the following must be true:" 16227 */ 16228 if (type->contentTypeDef != base) { 16229 /* 16230 * SPEC (2.1) "The {content type} must be the same simple type 16231 * definition." 16232 */ 16233 xmlSchemaPCustomErr(ctxt, 16234 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16235 WXS_BASIC_CAST type, NULL, 16236 "The content type must be the simple base type", NULL); 16237 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16238 } 16239 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16240 /* 16241 * SPEC (2.2) "The {final} of the {base type definition} must not 16242 * contain extension" 16243 * NOTE that this is the same as (1.1). 16244 */ 16245 xmlSchemaPCustomErr(ctxt, 16246 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16247 WXS_BASIC_CAST type, NULL, 16248 "The 'final' of the base type definition " 16249 "contains 'extension'", NULL); 16250 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16251 } 16252 } 16253 return (0); 16254} 16255 16256/** 16257 * xmlSchemaCheckDerivationOKRestriction: 16258 * @ctxt: the schema parser context 16259 * @type: the complex type definition 16260 * 16261 * (3.4.6) Constraints on Complex Type Definition Schema Components 16262 * Schema Component Constraint: 16263 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16264 * 16265 * STATUS: 16266 * missing: 16267 * (5.4.2) ??? 16268 * 16269 * ATTENTION: 16270 * In XML Schema 1.1 this will be: 16271 * Validation Rule: Checking complex type subsumption 16272 * 16273 * Returns 0 if the constraints are satisfied, a positive 16274 * error code if not and -1 if an internal error occured. 16275 */ 16276static int 16277xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16278 xmlSchemaTypePtr type) 16279{ 16280 xmlSchemaTypePtr base; 16281 16282 /* 16283 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16284 * temporarily only. 16285 */ 16286 base = type->baseType; 16287 if (! WXS_IS_COMPLEX(base)) { 16288 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16289 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16290 type->node, WXS_BASIC_CAST type, 16291 "The base type must be a complex type", NULL, NULL); 16292 return(ctxt->err); 16293 } 16294 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16295 /* 16296 * SPEC (1) "The {base type definition} must be a complex type 16297 * definition whose {final} does not contain restriction." 16298 */ 16299 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16300 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16301 type->node, WXS_BASIC_CAST type, 16302 "The 'final' of the base type definition " 16303 "contains 'restriction'", NULL, NULL); 16304 return (ctxt->err); 16305 } 16306 /* 16307 * SPEC (2), (3) and (4) 16308 * Those are handled in a separate function, since the 16309 * same constraints are needed for redefinition of 16310 * attribute groups as well. 16311 */ 16312 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16313 XML_SCHEMA_ACTION_DERIVE, 16314 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16315 type->attrUses, base->attrUses, 16316 type->attributeWildcard, 16317 base->attributeWildcard) == -1) 16318 { 16319 return(-1); 16320 } 16321 /* 16322 * SPEC (5) "One of the following must be true:" 16323 */ 16324 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16325 /* 16326 * SPEC (5.1) "The {base type definition} must be the 16327 * �ur-type definition�." 16328 * PASS 16329 */ 16330 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16331 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16332 /* 16333 * SPEC (5.2.1) "The {content type} of the complex type definition 16334 * must be a simple type definition" 16335 * 16336 * SPEC (5.2.2) "One of the following must be true:" 16337 */ 16338 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16339 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16340 { 16341 int err; 16342 /* 16343 * SPEC (5.2.2.1) "The {content type} of the {base type 16344 * definition} must be a simple type definition from which 16345 * the {content type} is validly derived given the empty 16346 * set as defined in Type Derivation OK (Simple) (�3.14.6)." 16347 * 16348 * ATTENTION TODO: This seems not needed if the type implicitely 16349 * derived from the base type. 16350 * 16351 */ 16352 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16353 type->contentTypeDef, base->contentTypeDef, 0); 16354 if (err != 0) { 16355 xmlChar *strA = NULL, *strB = NULL; 16356 16357 if (err == -1) 16358 return(-1); 16359 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16360 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16361 NULL, WXS_BASIC_CAST type, 16362 "The {content type} %s is not validly derived from the " 16363 "base type's {content type} %s", 16364 xmlSchemaGetComponentDesignation(&strA, 16365 type->contentTypeDef), 16366 xmlSchemaGetComponentDesignation(&strB, 16367 base->contentTypeDef)); 16368 FREE_AND_NULL(strA); 16369 FREE_AND_NULL(strB); 16370 return(ctxt->err); 16371 } 16372 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16373 (xmlSchemaIsParticleEmptiable( 16374 (xmlSchemaParticlePtr) base->subtypes))) { 16375 /* 16376 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16377 * and have a particle which is �emptiable� as defined in 16378 * Particle Emptiable (�3.9.6)." 16379 * PASS 16380 */ 16381 } else { 16382 xmlSchemaPCustomErr(ctxt, 16383 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16384 WXS_BASIC_CAST type, NULL, 16385 "The content type of the base type must be either " 16386 "a simple type or 'mixed' and an emptiable particle", NULL); 16387 return (ctxt->err); 16388 } 16389 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16390 /* 16391 * SPEC (5.3.1) "The {content type} of the complex type itself must 16392 * be empty" 16393 */ 16394 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16395 /* 16396 * SPEC (5.3.2.1) "The {content type} of the {base type 16397 * definition} must also be empty." 16398 * PASS 16399 */ 16400 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16401 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16402 xmlSchemaIsParticleEmptiable( 16403 (xmlSchemaParticlePtr) base->subtypes)) { 16404 /* 16405 * SPEC (5.3.2.2) "The {content type} of the {base type 16406 * definition} must be elementOnly or mixed and have a particle 16407 * which is �emptiable� as defined in Particle Emptiable (�3.9.6)." 16408 * PASS 16409 */ 16410 } else { 16411 xmlSchemaPCustomErr(ctxt, 16412 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16413 WXS_BASIC_CAST type, NULL, 16414 "The content type of the base type must be either " 16415 "empty or 'mixed' (or 'elements-only') and an emptiable " 16416 "particle", NULL); 16417 return (ctxt->err); 16418 } 16419 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16420 WXS_HAS_MIXED_CONTENT(type)) { 16421 /* 16422 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16423 * itself must be element-only" 16424 */ 16425 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16426 /* 16427 * SPEC (5.4.1.2) "The {content type} of the complex type 16428 * definition itself and of the {base type definition} must be 16429 * mixed" 16430 */ 16431 xmlSchemaPCustomErr(ctxt, 16432 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16433 WXS_BASIC_CAST type, NULL, 16434 "If the content type is 'mixed', then the content type of the " 16435 "base type must also be 'mixed'", NULL); 16436 return (ctxt->err); 16437 } 16438 /* 16439 * SPEC (5.4.2) "The particle of the complex type definition itself 16440 * must be a �valid restriction� of the particle of the {content 16441 * type} of the {base type definition} as defined in Particle Valid 16442 * (Restriction) (�3.9.6). 16443 * 16444 * URGENT TODO: (5.4.2) 16445 */ 16446 } else { 16447 xmlSchemaPCustomErr(ctxt, 16448 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16449 WXS_BASIC_CAST type, NULL, 16450 "The type is not a valid restriction of its base type", NULL); 16451 return (ctxt->err); 16452 } 16453 return (0); 16454} 16455 16456/** 16457 * xmlSchemaCheckCTComponent: 16458 * @ctxt: the schema parser context 16459 * @type: the complex type definition 16460 * 16461 * (3.4.6) Constraints on Complex Type Definition Schema Components 16462 * 16463 * Returns 0 if the constraints are satisfied, a positive 16464 * error code if not and -1 if an internal error occured. 16465 */ 16466static int 16467xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16468 xmlSchemaTypePtr type) 16469{ 16470 int ret; 16471 /* 16472 * Complex Type Definition Properties Correct 16473 */ 16474 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16475 if (ret != 0) 16476 return (ret); 16477 if (WXS_IS_EXTENSION(type)) 16478 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16479 else 16480 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16481 return (ret); 16482} 16483 16484/** 16485 * xmlSchemaCheckSRCCT: 16486 * @ctxt: the schema parser context 16487 * @type: the complex type definition 16488 * 16489 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16490 * Schema Representation Constraint: 16491 * Complex Type Definition Representation OK (src-ct) 16492 * 16493 * Returns 0 if the constraints are satisfied, a positive 16494 * error code if not and -1 if an internal error occured. 16495 */ 16496static int 16497xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16498 xmlSchemaTypePtr type) 16499{ 16500 xmlSchemaTypePtr base; 16501 int ret = 0; 16502 16503 /* 16504 * TODO: Adjust the error codes here, as I used 16505 * XML_SCHEMAP_SRC_CT_1 only yet. 16506 */ 16507 base = type->baseType; 16508 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16509 /* 16510 * 1 If the <complexContent> alternative is chosen, the type definition 16511 * �resolved� to by the �actual value� of the base [attribute] 16512 * must be a complex type definition; 16513 */ 16514 if (! WXS_IS_COMPLEX(base)) { 16515 xmlChar *str = NULL; 16516 xmlSchemaPCustomErr(ctxt, 16517 XML_SCHEMAP_SRC_CT_1, 16518 WXS_BASIC_CAST type, type->node, 16519 "If using <complexContent>, the base type is expected to be " 16520 "a complex type. The base type '%s' is a simple type", 16521 xmlSchemaFormatQName(&str, base->targetNamespace, 16522 base->name)); 16523 FREE_AND_NULL(str) 16524 return (XML_SCHEMAP_SRC_CT_1); 16525 } 16526 } else { 16527 /* 16528 * SPEC 16529 * 2 If the <simpleContent> alternative is chosen, all of the 16530 * following must be true: 16531 * 2.1 The type definition �resolved� to by the �actual value� of the 16532 * base [attribute] must be one of the following: 16533 */ 16534 if (WXS_IS_SIMPLE(base)) { 16535 if (WXS_IS_EXTENSION(type) == 0) { 16536 xmlChar *str = NULL; 16537 /* 16538 * 2.1.3 only if the <extension> alternative is also 16539 * chosen, a simple type definition. 16540 */ 16541 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16542 xmlSchemaPCustomErr(ctxt, 16543 XML_SCHEMAP_SRC_CT_1, 16544 WXS_BASIC_CAST type, NULL, 16545 "If using <simpleContent> and <restriction>, the base " 16546 "type must be a complex type. The base type '%s' is " 16547 "a simple type", 16548 xmlSchemaFormatQName(&str, base->targetNamespace, 16549 base->name)); 16550 FREE_AND_NULL(str) 16551 return (XML_SCHEMAP_SRC_CT_1); 16552 } 16553 } else { 16554 /* Base type is a complex type. */ 16555 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16556 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16557 /* 16558 * 2.1.1 a complex type definition whose {content type} is a 16559 * simple type definition; 16560 * PASS 16561 */ 16562 if (base->contentTypeDef == NULL) { 16563 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16564 WXS_BASIC_CAST type, NULL, 16565 "Internal error: xmlSchemaCheckSRCCT, " 16566 "'%s', base type has no content type", 16567 type->name); 16568 return (-1); 16569 } 16570 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16571 (WXS_IS_RESTRICTION(type))) { 16572 16573 /* 16574 * 2.1.2 only if the <restriction> alternative is also 16575 * chosen, a complex type definition whose {content type} 16576 * is mixed and a particle emptiable. 16577 */ 16578 if (! xmlSchemaIsParticleEmptiable( 16579 (xmlSchemaParticlePtr) base->subtypes)) { 16580 ret = XML_SCHEMAP_SRC_CT_1; 16581 } else 16582 /* 16583 * Attention: at this point the <simpleType> child is in 16584 * ->contentTypeDef (put there during parsing). 16585 */ 16586 if (type->contentTypeDef == NULL) { 16587 xmlChar *str = NULL; 16588 /* 16589 * 2.2 If clause 2.1.2 above is satisfied, then there 16590 * must be a <simpleType> among the [children] of 16591 * <restriction>. 16592 */ 16593 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16594 xmlSchemaPCustomErr(ctxt, 16595 XML_SCHEMAP_SRC_CT_1, 16596 WXS_BASIC_CAST type, NULL, 16597 "A <simpleType> is expected among the children " 16598 "of <restriction>, if <simpleContent> is used and " 16599 "the base type '%s' is a complex type", 16600 xmlSchemaFormatQName(&str, base->targetNamespace, 16601 base->name)); 16602 FREE_AND_NULL(str) 16603 return (XML_SCHEMAP_SRC_CT_1); 16604 } 16605 } else { 16606 ret = XML_SCHEMAP_SRC_CT_1; 16607 } 16608 } 16609 if (ret > 0) { 16610 xmlChar *str = NULL; 16611 if (WXS_IS_RESTRICTION(type)) { 16612 xmlSchemaPCustomErr(ctxt, 16613 XML_SCHEMAP_SRC_CT_1, 16614 WXS_BASIC_CAST type, NULL, 16615 "If <simpleContent> and <restriction> is used, the " 16616 "base type must be a simple type or a complex type with " 16617 "mixed content and particle emptiable. The base type " 16618 "'%s' is none of those", 16619 xmlSchemaFormatQName(&str, base->targetNamespace, 16620 base->name)); 16621 } else { 16622 xmlSchemaPCustomErr(ctxt, 16623 XML_SCHEMAP_SRC_CT_1, 16624 WXS_BASIC_CAST type, NULL, 16625 "If <simpleContent> and <extension> is used, the " 16626 "base type must be a simple type. The base type '%s' " 16627 "is a complex type", 16628 xmlSchemaFormatQName(&str, base->targetNamespace, 16629 base->name)); 16630 } 16631 FREE_AND_NULL(str) 16632 } 16633 } 16634 /* 16635 * SPEC (3) "The corresponding complex type definition component must 16636 * satisfy the conditions set out in Constraints on Complex Type 16637 * Definition Schema Components (�3.4.6);" 16638 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16639 */ 16640 /* 16641 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16642 * above for {attribute wildcard} is satisfied, the intensional 16643 * intersection must be expressible, as defined in Attribute Wildcard 16644 * Intersection (�3.10.6). 16645 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16646 */ 16647 return (ret); 16648} 16649 16650#ifdef ENABLE_PARTICLE_RESTRICTION 16651/** 16652 * xmlSchemaCheckParticleRangeOK: 16653 * @ctxt: the schema parser context 16654 * @type: the complex type definition 16655 * 16656 * (3.9.6) Constraints on Particle Schema Components 16657 * Schema Component Constraint: 16658 * Occurrence Range OK (range-ok) 16659 * 16660 * STATUS: complete 16661 * 16662 * Returns 0 if the constraints are satisfied, a positive 16663 * error code if not and -1 if an internal error occured. 16664 */ 16665static int 16666xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16667 int bmin, int bmax) 16668{ 16669 if (rmin < bmin) 16670 return (1); 16671 if ((bmax != UNBOUNDED) && 16672 (rmax > bmax)) 16673 return (1); 16674 return (0); 16675} 16676 16677/** 16678 * xmlSchemaCheckRCaseNameAndTypeOK: 16679 * @ctxt: the schema parser context 16680 * @r: the restricting element declaration particle 16681 * @b: the base element declaration particle 16682 * 16683 * (3.9.6) Constraints on Particle Schema Components 16684 * Schema Component Constraint: 16685 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16686 * (rcase-NameAndTypeOK) 16687 * 16688 * STATUS: 16689 * MISSING (3.2.3) 16690 * CLARIFY: (3.2.2) 16691 * 16692 * Returns 0 if the constraints are satisfied, a positive 16693 * error code if not and -1 if an internal error occured. 16694 */ 16695static int 16696xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16697 xmlSchemaParticlePtr r, 16698 xmlSchemaParticlePtr b) 16699{ 16700 xmlSchemaElementPtr elemR, elemB; 16701 16702 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16703 elemR = (xmlSchemaElementPtr) r->children; 16704 elemB = (xmlSchemaElementPtr) b->children; 16705 /* 16706 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16707 * the same." 16708 */ 16709 if ((elemR != elemB) && 16710 ((! xmlStrEqual(elemR->name, elemB->name)) || 16711 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16712 return (1); 16713 /* 16714 * SPEC (2) "R's occurrence range is a valid restriction of B's 16715 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16716 */ 16717 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16718 b->minOccurs, b->maxOccurs) != 0) 16719 return (1); 16720 /* 16721 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16722 * {scope} are global." 16723 */ 16724 if (elemR == elemB) 16725 return (0); 16726 /* 16727 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16728 */ 16729 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16730 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16731 return (1); 16732 /* 16733 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16734 * or is not fixed, or R's declaration's {value constraint} is fixed 16735 * with the same value." 16736 */ 16737 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16738 ((elemR->value == NULL) || 16739 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16740 /* TODO: Equality of the initial value or normalized or canonical? */ 16741 (! xmlStrEqual(elemR->value, elemB->value)))) 16742 return (1); 16743 /* 16744 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16745 * definitions} is a subset of B's declaration's {identity-constraint 16746 * definitions}, if any." 16747 */ 16748 if (elemB->idcs != NULL) { 16749 /* TODO */ 16750 } 16751 /* 16752 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16753 * superset of B's declaration's {disallowed substitutions}." 16754 */ 16755 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16756 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16757 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16758 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16759 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16760 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16761 return (1); 16762 /* 16763 * SPEC (3.2.5) "R's {type definition} is validly derived given 16764 * {extension, list, union} from B's {type definition}" 16765 * 16766 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16767 * set, if the corresponding constraints handle "restriction" and 16768 * "extension" only? 16769 * 16770 */ 16771 { 16772 int set = 0; 16773 16774 set |= SUBSET_EXTENSION; 16775 set |= SUBSET_LIST; 16776 set |= SUBSET_UNION; 16777 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16778 elemB->subtypes, set) != 0) 16779 return (1); 16780 } 16781 return (0); 16782} 16783 16784/** 16785 * xmlSchemaCheckRCaseNSCompat: 16786 * @ctxt: the schema parser context 16787 * @r: the restricting element declaration particle 16788 * @b: the base wildcard particle 16789 * 16790 * (3.9.6) Constraints on Particle Schema Components 16791 * Schema Component Constraint: 16792 * Particle Derivation OK (Elt:Any -- NSCompat) 16793 * (rcase-NSCompat) 16794 * 16795 * STATUS: complete 16796 * 16797 * Returns 0 if the constraints are satisfied, a positive 16798 * error code if not and -1 if an internal error occured. 16799 */ 16800static int 16801xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16802 xmlSchemaParticlePtr r, 16803 xmlSchemaParticlePtr b) 16804{ 16805 /* TODO:Error codes (rcase-NSCompat). */ 16806 /* 16807 * SPEC "For an element declaration particle to be a �valid restriction� 16808 * of a wildcard particle all of the following must be true:" 16809 * 16810 * SPEC (1) "The element declaration's {target namespace} is �valid� 16811 * with respect to the wildcard's {namespace constraint} as defined by 16812 * Wildcard allows Namespace Name (�3.10.4)." 16813 */ 16814 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16815 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16816 return (1); 16817 /* 16818 * SPEC (2) "R's occurrence range is a valid restriction of B's 16819 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16820 */ 16821 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16822 b->minOccurs, b->maxOccurs) != 0) 16823 return (1); 16824 16825 return (0); 16826} 16827 16828/** 16829 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16830 * @ctxt: the schema parser context 16831 * @r: the restricting element declaration particle 16832 * @b: the base model group particle 16833 * 16834 * (3.9.6) Constraints on Particle Schema Components 16835 * Schema Component Constraint: 16836 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16837 * (rcase-RecurseAsIfGroup) 16838 * 16839 * STATUS: TODO 16840 * 16841 * Returns 0 if the constraints are satisfied, a positive 16842 * error code if not and -1 if an internal error occured. 16843 */ 16844static int 16845xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16846 xmlSchemaParticlePtr r, 16847 xmlSchemaParticlePtr b) 16848{ 16849 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16850 TODO 16851 return (0); 16852} 16853 16854/** 16855 * xmlSchemaCheckRCaseNSSubset: 16856 * @ctxt: the schema parser context 16857 * @r: the restricting wildcard particle 16858 * @b: the base wildcard particle 16859 * 16860 * (3.9.6) Constraints on Particle Schema Components 16861 * Schema Component Constraint: 16862 * Particle Derivation OK (Any:Any -- NSSubset) 16863 * (rcase-NSSubset) 16864 * 16865 * STATUS: complete 16866 * 16867 * Returns 0 if the constraints are satisfied, a positive 16868 * error code if not and -1 if an internal error occured. 16869 */ 16870static int 16871xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16872 xmlSchemaParticlePtr r, 16873 xmlSchemaParticlePtr b, 16874 int isAnyTypeBase) 16875{ 16876 /* TODO: Error codes (rcase-NSSubset). */ 16877 /* 16878 * SPEC (1) "R's occurrence range is a valid restriction of B's 16879 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16880 */ 16881 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16882 b->minOccurs, b->maxOccurs)) 16883 return (1); 16884 /* 16885 * SPEC (2) "R's {namespace constraint} must be an intensional subset 16886 * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)." 16887 */ 16888 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 16889 (xmlSchemaWildcardPtr) b->children)) 16890 return (1); 16891 /* 16892 * SPEC (3) "Unless B is the content model wildcard of the �ur-type 16893 * definition�, R's {process contents} must be identical to or stronger 16894 * than B's {process contents}, where strict is stronger than lax is 16895 * stronger than skip." 16896 */ 16897 if (! isAnyTypeBase) { 16898 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 16899 ((xmlSchemaWildcardPtr) b->children)->processContents) 16900 return (1); 16901 } 16902 16903 return (0); 16904} 16905 16906/** 16907 * xmlSchemaCheckCOSParticleRestrict: 16908 * @ctxt: the schema parser context 16909 * @type: the complex type definition 16910 * 16911 * (3.9.6) Constraints on Particle Schema Components 16912 * Schema Component Constraint: 16913 * Particle Valid (Restriction) (cos-particle-restrict) 16914 * 16915 * STATUS: TODO 16916 * 16917 * Returns 0 if the constraints are satisfied, a positive 16918 * error code if not and -1 if an internal error occured. 16919 */ 16920static int 16921xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 16922 xmlSchemaParticlePtr r, 16923 xmlSchemaParticlePtr b) 16924{ 16925 int ret = 0; 16926 16927 /*part = WXS_TYPE_PARTICLE(type); 16928 basePart = WXS_TYPE_PARTICLE(base); 16929 */ 16930 16931 TODO 16932 16933 /* 16934 * SPEC (1) "They are the same particle." 16935 */ 16936 if (r == b) 16937 return (0); 16938 16939 16940 return (0); 16941} 16942 16943/** 16944 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 16945 * @ctxt: the schema parser context 16946 * @r: the model group particle 16947 * @b: the base wildcard particle 16948 * 16949 * (3.9.6) Constraints on Particle Schema Components 16950 * Schema Component Constraint: 16951 * Particle Derivation OK (All/Choice/Sequence:Any -- 16952 * NSRecurseCheckCardinality) 16953 * (rcase-NSRecurseCheckCardinality) 16954 * 16955 * STATUS: TODO: subst-groups 16956 * 16957 * Returns 0 if the constraints are satisfied, a positive 16958 * error code if not and -1 if an internal error occured. 16959 */ 16960static int 16961xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 16962 xmlSchemaParticlePtr r, 16963 xmlSchemaParticlePtr b) 16964{ 16965 xmlSchemaParticlePtr part; 16966 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 16967 if ((r->children == NULL) || (r->children->children == NULL)) 16968 return (-1); 16969 /* 16970 * SPEC "For a group particle to be a �valid restriction� of a 16971 * wildcard particle..." 16972 * 16973 * SPEC (1) "Every member of the {particles} of the group is a �valid 16974 * restriction� of the wildcard as defined by 16975 * Particle Valid (Restriction) (�3.9.6)." 16976 */ 16977 part = (xmlSchemaParticlePtr) r->children->children; 16978 do { 16979 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 16980 return (1); 16981 part = (xmlSchemaParticlePtr) part->next; 16982 } while (part != NULL); 16983 /* 16984 * SPEC (2) "The effective total range of the group [...] is a 16985 * valid restriction of B's occurrence range as defined by 16986 * Occurrence Range OK (�3.9.6)." 16987 */ 16988 if (xmlSchemaCheckParticleRangeOK( 16989 xmlSchemaGetParticleTotalRangeMin(r), 16990 xmlSchemaGetParticleTotalRangeMax(r), 16991 b->minOccurs, b->maxOccurs) != 0) 16992 return (1); 16993 return (0); 16994} 16995 16996/** 16997 * xmlSchemaCheckRCaseRecurse: 16998 * @ctxt: the schema parser context 16999 * @r: the <all> or <sequence> model group particle 17000 * @b: the base <all> or <sequence> model group particle 17001 * 17002 * (3.9.6) Constraints on Particle Schema Components 17003 * Schema Component Constraint: 17004 * Particle Derivation OK (All:All,Sequence:Sequence -- 17005 Recurse) 17006 * (rcase-Recurse) 17007 * 17008 * STATUS: ? 17009 * TODO: subst-groups 17010 * 17011 * Returns 0 if the constraints are satisfied, a positive 17012 * error code if not and -1 if an internal error occured. 17013 */ 17014static int 17015xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17016 xmlSchemaParticlePtr r, 17017 xmlSchemaParticlePtr b) 17018{ 17019 /* xmlSchemaParticlePtr part; */ 17020 /* TODO: Error codes (rcase-Recurse). */ 17021 if ((r->children == NULL) || (b->children == NULL) || 17022 (r->children->type != b->children->type)) 17023 return (-1); 17024 /* 17025 * SPEC "For an all or sequence group particle to be a �valid 17026 * restriction� of another group particle with the same {compositor}..." 17027 * 17028 * SPEC (1) "R's occurrence range is a valid restriction of B's 17029 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 17030 */ 17031 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17032 b->minOccurs, b->maxOccurs)) 17033 return (1); 17034 17035 17036 return (0); 17037} 17038 17039#endif 17040 17041#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17042 xmlSchemaPCustomErrExt(pctxt, \ 17043 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17044 WXS_BASIC_CAST fac1, fac1->node, \ 17045 "It is an error for both '%s' and '%s' to be specified on the "\ 17046 "same type definition", \ 17047 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17048 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17049 17050#define FACET_RESTR_ERR(fac1, msg) \ 17051 xmlSchemaPCustomErr(pctxt, \ 17052 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17053 WXS_BASIC_CAST fac1, fac1->node, \ 17054 msg, NULL); 17055 17056#define FACET_RESTR_FIXED_ERR(fac) \ 17057 xmlSchemaPCustomErr(pctxt, \ 17058 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17059 WXS_BASIC_CAST fac, fac->node, \ 17060 "The base type's facet is 'fixed', thus the value must not " \ 17061 "differ", NULL); 17062 17063static void 17064xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17065 xmlSchemaFacetPtr facet1, 17066 xmlSchemaFacetPtr facet2, 17067 int lessGreater, 17068 int orEqual, 17069 int ofBase) 17070{ 17071 xmlChar *msg = NULL; 17072 17073 msg = xmlStrdup(BAD_CAST "'"); 17074 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17075 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17076 if (lessGreater == 0) 17077 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17078 if (lessGreater == 1) 17079 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17080 else 17081 msg = xmlStrcat(msg, BAD_CAST " less than"); 17082 17083 if (orEqual) 17084 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17085 msg = xmlStrcat(msg, BAD_CAST " '"); 17086 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17087 if (ofBase) 17088 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17089 else 17090 msg = xmlStrcat(msg, BAD_CAST "'"); 17091 17092 xmlSchemaPCustomErr(pctxt, 17093 XML_SCHEMAP_INVALID_FACET_VALUE, 17094 WXS_BASIC_CAST facet1, NULL, 17095 (const char *) msg, NULL); 17096 17097 if (msg != NULL) 17098 xmlFree(msg); 17099} 17100 17101/* 17102* xmlSchemaDeriveAndValidateFacets: 17103* 17104* Schema Component Constraint: Simple Type Restriction (Facets) 17105* (st-restrict-facets) 17106*/ 17107static int 17108xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17109 xmlSchemaTypePtr type) 17110{ 17111 xmlSchemaTypePtr base = type->baseType; 17112 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17113 xmlSchemaFacetPtr facet, bfacet, 17114 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17115 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17116 fmininc = NULL, fmaxinc = NULL, 17117 fminexc = NULL, fmaxexc = NULL, 17118 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17119 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17120 bfmininc = NULL, bfmaxinc = NULL, 17121 bfminexc = NULL, bfmaxexc = NULL; 17122 int res; /* err = 0, fixedErr; */ 17123 17124 /* 17125 * SPEC st-restrict-facets 1: 17126 * "The {variety} of R is the same as that of B." 17127 */ 17128 /* 17129 * SPEC st-restrict-facets 2: 17130 * "If {variety} is atomic, the {primitive type definition} 17131 * of R is the same as that of B." 17132 * 17133 * NOTE: we leave 1 & 2 out for now, since this will be 17134 * satisfied by the derivation process. 17135 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17136 */ 17137 /* 17138 * SPEC st-restrict-facets 3: 17139 * "The {facets} of R are the union of S and the {facets} 17140 * of B, eliminating duplicates. To eliminate duplicates, 17141 * when a facet of the same kind occurs in both S and the 17142 * {facets} of B, the one in the {facets} of B is not 17143 * included, with the exception of enumeration and pattern 17144 * facets, for which multiple occurrences with distinct values 17145 * are allowed." 17146 */ 17147 17148 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17149 return (0); 17150 17151 last = type->facetSet; 17152 if (last != NULL) 17153 while (last->next != NULL) 17154 last = last->next; 17155 17156 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17157 facet = cur->facet; 17158 switch (facet->type) { 17159 case XML_SCHEMA_FACET_LENGTH: 17160 flength = facet; break; 17161 case XML_SCHEMA_FACET_MINLENGTH: 17162 fminlen = facet; break; 17163 case XML_SCHEMA_FACET_MININCLUSIVE: 17164 fmininc = facet; break; 17165 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17166 fminexc = facet; break; 17167 case XML_SCHEMA_FACET_MAXLENGTH: 17168 fmaxlen = facet; break; 17169 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17170 fmaxinc = facet; break; 17171 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17172 fmaxexc = facet; break; 17173 case XML_SCHEMA_FACET_TOTALDIGITS: 17174 ftotdig = facet; break; 17175 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17176 ffracdig = facet; break; 17177 default: 17178 break; 17179 } 17180 } 17181 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17182 facet = cur->facet; 17183 switch (facet->type) { 17184 case XML_SCHEMA_FACET_LENGTH: 17185 bflength = facet; break; 17186 case XML_SCHEMA_FACET_MINLENGTH: 17187 bfminlen = facet; break; 17188 case XML_SCHEMA_FACET_MININCLUSIVE: 17189 bfmininc = facet; break; 17190 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17191 bfminexc = facet; break; 17192 case XML_SCHEMA_FACET_MAXLENGTH: 17193 bfmaxlen = facet; break; 17194 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17195 bfmaxinc = facet; break; 17196 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17197 bfmaxexc = facet; break; 17198 case XML_SCHEMA_FACET_TOTALDIGITS: 17199 bftotdig = facet; break; 17200 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17201 bffracdig = facet; break; 17202 default: 17203 break; 17204 } 17205 } 17206 /* 17207 * length and minLength or maxLength (2.2) + (3.2) 17208 */ 17209 if (flength && (fminlen || fmaxlen)) { 17210 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17211 "either of 'minLength' or 'maxLength' to be specified on " 17212 "the same type definition") 17213 } 17214 /* 17215 * Mutual exclusions in the same derivation step. 17216 */ 17217 if ((fmaxinc) && (fmaxexc)) { 17218 /* 17219 * SCC "maxInclusive and maxExclusive" 17220 */ 17221 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17222 } 17223 if ((fmininc) && (fminexc)) { 17224 /* 17225 * SCC "minInclusive and minExclusive" 17226 */ 17227 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17228 } 17229 17230 if (flength && bflength) { 17231 /* 17232 * SCC "length valid restriction" 17233 * The values have to be equal. 17234 */ 17235 res = xmlSchemaCompareValues(flength->val, bflength->val); 17236 if (res == -2) 17237 goto internal_error; 17238 if (res != 0) 17239 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17240 if ((res != 0) && (bflength->fixed)) { 17241 FACET_RESTR_FIXED_ERR(flength) 17242 } 17243 17244 } 17245 if (fminlen && bfminlen) { 17246 /* 17247 * SCC "minLength valid restriction" 17248 * minLength >= BASE minLength 17249 */ 17250 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17251 if (res == -2) 17252 goto internal_error; 17253 if (res == -1) 17254 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17255 if ((res != 0) && (bfminlen->fixed)) { 17256 FACET_RESTR_FIXED_ERR(fminlen) 17257 } 17258 } 17259 if (fmaxlen && bfmaxlen) { 17260 /* 17261 * SCC "maxLength valid restriction" 17262 * maxLength <= BASE minLength 17263 */ 17264 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17265 if (res == -2) 17266 goto internal_error; 17267 if (res == 1) 17268 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17269 if ((res != 0) && (bfmaxlen->fixed)) { 17270 FACET_RESTR_FIXED_ERR(fmaxlen) 17271 } 17272 } 17273 /* 17274 * SCC "length and minLength or maxLength" 17275 */ 17276 if (! flength) 17277 flength = bflength; 17278 if (flength) { 17279 if (! fminlen) 17280 flength = bflength; 17281 if (fminlen) { 17282 /* (1.1) length >= minLength */ 17283 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17284 if (res == -2) 17285 goto internal_error; 17286 if (res == -1) 17287 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17288 } 17289 if (! fmaxlen) 17290 fmaxlen = bfmaxlen; 17291 if (fmaxlen) { 17292 /* (2.1) length <= maxLength */ 17293 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17294 if (res == -2) 17295 goto internal_error; 17296 if (res == 1) 17297 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17298 } 17299 } 17300 if (fmaxinc) { 17301 /* 17302 * "maxInclusive" 17303 */ 17304 if (fmininc) { 17305 /* SCC "maxInclusive >= minInclusive" */ 17306 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17307 if (res == -2) 17308 goto internal_error; 17309 if (res == -1) { 17310 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17311 } 17312 } 17313 /* 17314 * SCC "maxInclusive valid restriction" 17315 */ 17316 if (bfmaxinc) { 17317 /* maxInclusive <= BASE maxInclusive */ 17318 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17319 if (res == -2) 17320 goto internal_error; 17321 if (res == 1) 17322 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17323 if ((res != 0) && (bfmaxinc->fixed)) { 17324 FACET_RESTR_FIXED_ERR(fmaxinc) 17325 } 17326 } 17327 if (bfmaxexc) { 17328 /* maxInclusive < BASE maxExclusive */ 17329 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17330 if (res == -2) 17331 goto internal_error; 17332 if (res != -1) { 17333 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17334 } 17335 } 17336 if (bfmininc) { 17337 /* maxInclusive >= BASE minInclusive */ 17338 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17339 if (res == -2) 17340 goto internal_error; 17341 if (res == -1) { 17342 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17343 } 17344 } 17345 if (bfminexc) { 17346 /* maxInclusive > BASE minExclusive */ 17347 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17348 if (res == -2) 17349 goto internal_error; 17350 if (res != 1) { 17351 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17352 } 17353 } 17354 } 17355 if (fmaxexc) { 17356 /* 17357 * "maxExclusive >= minExclusive" 17358 */ 17359 if (fminexc) { 17360 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17361 if (res == -2) 17362 goto internal_error; 17363 if (res == -1) { 17364 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17365 } 17366 } 17367 /* 17368 * "maxExclusive valid restriction" 17369 */ 17370 if (bfmaxexc) { 17371 /* maxExclusive <= BASE maxExclusive */ 17372 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17373 if (res == -2) 17374 goto internal_error; 17375 if (res == 1) { 17376 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17377 } 17378 if ((res != 0) && (bfmaxexc->fixed)) { 17379 FACET_RESTR_FIXED_ERR(fmaxexc) 17380 } 17381 } 17382 if (bfmaxinc) { 17383 /* maxExclusive <= BASE maxInclusive */ 17384 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17385 if (res == -2) 17386 goto internal_error; 17387 if (res == 1) { 17388 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17389 } 17390 } 17391 if (bfmininc) { 17392 /* maxExclusive > BASE minInclusive */ 17393 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17394 if (res == -2) 17395 goto internal_error; 17396 if (res != 1) { 17397 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17398 } 17399 } 17400 if (bfminexc) { 17401 /* maxExclusive > BASE minExclusive */ 17402 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17403 if (res == -2) 17404 goto internal_error; 17405 if (res != 1) { 17406 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17407 } 17408 } 17409 } 17410 if (fminexc) { 17411 /* 17412 * "minExclusive < maxInclusive" 17413 */ 17414 if (fmaxinc) { 17415 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17416 if (res == -2) 17417 goto internal_error; 17418 if (res != -1) { 17419 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17420 } 17421 } 17422 /* 17423 * "minExclusive valid restriction" 17424 */ 17425 if (bfminexc) { 17426 /* minExclusive >= BASE minExclusive */ 17427 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17428 if (res == -2) 17429 goto internal_error; 17430 if (res == -1) { 17431 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17432 } 17433 if ((res != 0) && (bfminexc->fixed)) { 17434 FACET_RESTR_FIXED_ERR(fminexc) 17435 } 17436 } 17437 if (bfmaxinc) { 17438 /* minExclusive <= BASE maxInclusive */ 17439 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17440 if (res == -2) 17441 goto internal_error; 17442 if (res == 1) { 17443 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17444 } 17445 } 17446 if (bfmininc) { 17447 /* minExclusive >= BASE minInclusive */ 17448 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17449 if (res == -2) 17450 goto internal_error; 17451 if (res == -1) { 17452 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17453 } 17454 } 17455 if (bfmaxexc) { 17456 /* minExclusive < BASE maxExclusive */ 17457 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17458 if (res == -2) 17459 goto internal_error; 17460 if (res != -1) { 17461 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17462 } 17463 } 17464 } 17465 if (fmininc) { 17466 /* 17467 * "minInclusive < maxExclusive" 17468 */ 17469 if (fmaxexc) { 17470 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17471 if (res == -2) 17472 goto internal_error; 17473 if (res != -1) { 17474 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17475 } 17476 } 17477 /* 17478 * "minExclusive valid restriction" 17479 */ 17480 if (bfmininc) { 17481 /* minInclusive >= BASE minInclusive */ 17482 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17483 if (res == -2) 17484 goto internal_error; 17485 if (res == -1) { 17486 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17487 } 17488 if ((res != 0) && (bfmininc->fixed)) { 17489 FACET_RESTR_FIXED_ERR(fmininc) 17490 } 17491 } 17492 if (bfmaxinc) { 17493 /* minInclusive <= BASE maxInclusive */ 17494 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17495 if (res == -2) 17496 goto internal_error; 17497 if (res == 1) { 17498 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17499 } 17500 } 17501 if (bfminexc) { 17502 /* minInclusive > BASE minExclusive */ 17503 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17504 if (res == -2) 17505 goto internal_error; 17506 if (res != 1) 17507 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17508 } 17509 if (bfmaxexc) { 17510 /* minInclusive < BASE maxExclusive */ 17511 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17512 if (res == -2) 17513 goto internal_error; 17514 if (res != -1) 17515 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17516 } 17517 } 17518 if (ftotdig && bftotdig) { 17519 /* 17520 * SCC " totalDigits valid restriction" 17521 * totalDigits <= BASE totalDigits 17522 */ 17523 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17524 if (res == -2) 17525 goto internal_error; 17526 if (res == 1) 17527 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17528 -1, 1, 1); 17529 if ((res != 0) && (bftotdig->fixed)) { 17530 FACET_RESTR_FIXED_ERR(ftotdig) 17531 } 17532 } 17533 if (ffracdig && bffracdig) { 17534 /* 17535 * SCC "fractionDigits valid restriction" 17536 * fractionDigits <= BASE fractionDigits 17537 */ 17538 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17539 if (res == -2) 17540 goto internal_error; 17541 if (res == 1) 17542 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17543 -1, 1, 1); 17544 if ((res != 0) && (bffracdig->fixed)) { 17545 FACET_RESTR_FIXED_ERR(ffracdig) 17546 } 17547 } 17548 /* 17549 * SCC "fractionDigits less than or equal to totalDigits" 17550 */ 17551 if (! ftotdig) 17552 ftotdig = bftotdig; 17553 if (! ffracdig) 17554 ffracdig = bffracdig; 17555 if (ftotdig && ffracdig) { 17556 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17557 if (res == -2) 17558 goto internal_error; 17559 if (res == 1) 17560 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17561 -1, 1, 0); 17562 } 17563 /* 17564 * *Enumerations* won' be added here, since only the first set 17565 * of enumerations in the ancestor-or-self axis is used 17566 * for validation, plus we need to use the base type of those 17567 * enumerations for whitespace. 17568 * 17569 * *Patterns*: won't be add here, since they are ORed at 17570 * type level and ANDed at ancestor level. This will 17571 * happed during validation by walking the base axis 17572 * of the type. 17573 */ 17574 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17575 bfacet = cur->facet; 17576 /* 17577 * Special handling of enumerations and patterns. 17578 * TODO: hmm, they should not appear in the set, so remove this. 17579 */ 17580 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17581 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17582 continue; 17583 /* 17584 * Search for a duplicate facet in the current type. 17585 */ 17586 link = type->facetSet; 17587 /* err = 0; */ 17588 /* fixedErr = 0; */ 17589 while (link != NULL) { 17590 facet = link->facet; 17591 if (facet->type == bfacet->type) { 17592 switch (facet->type) { 17593 case XML_SCHEMA_FACET_WHITESPACE: 17594 /* 17595 * The whitespace must be stronger. 17596 */ 17597 if (facet->whitespace < bfacet->whitespace) { 17598 FACET_RESTR_ERR(flength, 17599 "The 'whitespace' value has to be equal to " 17600 "or stronger than the 'whitespace' value of " 17601 "the base type") 17602 } 17603 if ((bfacet->fixed) && 17604 (facet->whitespace != bfacet->whitespace)) { 17605 FACET_RESTR_FIXED_ERR(facet) 17606 } 17607 break; 17608 default: 17609 break; 17610 } 17611 /* Duplicate found. */ 17612 break; 17613 } 17614 link = link->next; 17615 } 17616 /* 17617 * If no duplicate was found: add the base types's facet 17618 * to the set. 17619 */ 17620 if (link == NULL) { 17621 link = (xmlSchemaFacetLinkPtr) 17622 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17623 if (link == NULL) { 17624 xmlSchemaPErrMemory(pctxt, 17625 "deriving facets, creating a facet link", NULL); 17626 return (-1); 17627 } 17628 link->facet = cur->facet; 17629 link->next = NULL; 17630 if (last == NULL) 17631 type->facetSet = link; 17632 else 17633 last->next = link; 17634 last = link; 17635 } 17636 17637 } 17638 17639 return (0); 17640internal_error: 17641 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17642 "an error occured"); 17643 return (-1); 17644} 17645 17646static int 17647xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17648 xmlSchemaTypePtr type) 17649{ 17650 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17651 /* 17652 * The actual value is then formed by replacing any union type 17653 * definition in the �explicit members� with the members of their 17654 * {member type definitions}, in order. 17655 * 17656 * TODO: There's a bug entry at 17657 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17658 * which indicates that we'll keep the union types the future. 17659 */ 17660 link = type->memberTypes; 17661 while (link != NULL) { 17662 17663 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17664 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17665 17666 if (WXS_IS_UNION(link->type)) { 17667 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17668 if (subLink != NULL) { 17669 link->type = subLink->type; 17670 if (subLink->next != NULL) { 17671 lastLink = link->next; 17672 subLink = subLink->next; 17673 prevLink = link; 17674 while (subLink != NULL) { 17675 newLink = (xmlSchemaTypeLinkPtr) 17676 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17677 if (newLink == NULL) { 17678 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17679 NULL); 17680 return (-1); 17681 } 17682 newLink->type = subLink->type; 17683 prevLink->next = newLink; 17684 prevLink = newLink; 17685 newLink->next = lastLink; 17686 17687 subLink = subLink->next; 17688 } 17689 } 17690 } 17691 } 17692 link = link->next; 17693 } 17694 return (0); 17695} 17696 17697static void 17698xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17699{ 17700 int has = 0, needVal = 0, normVal = 0; 17701 17702 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17703 if (has) { 17704 needVal = (type->baseType->flags & 17705 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17706 normVal = (type->baseType->flags & 17707 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17708 } 17709 if (type->facets != NULL) { 17710 xmlSchemaFacetPtr fac; 17711 17712 for (fac = type->facets; fac != NULL; fac = fac->next) { 17713 switch (fac->type) { 17714 case XML_SCHEMA_FACET_WHITESPACE: 17715 break; 17716 case XML_SCHEMA_FACET_PATTERN: 17717 normVal = 1; 17718 has = 1; 17719 break; 17720 case XML_SCHEMA_FACET_ENUMERATION: 17721 needVal = 1; 17722 normVal = 1; 17723 has = 1; 17724 break; 17725 default: 17726 has = 1; 17727 break; 17728 } 17729 } 17730 } 17731 if (normVal) 17732 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17733 if (needVal) 17734 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17735 if (has) 17736 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17737 17738 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17739 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17740 /* 17741 * OPTIMIZE VAL TODO: Some facets need a computed value. 17742 */ 17743 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17744 (prim->builtInType != XML_SCHEMAS_STRING)) { 17745 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17746 } 17747 } 17748} 17749 17750static int 17751xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17752{ 17753 17754 17755 /* 17756 * Evaluate the whitespace-facet value. 17757 */ 17758 if (WXS_IS_LIST(type)) { 17759 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17760 return (0); 17761 } else if (WXS_IS_UNION(type)) 17762 return (0); 17763 17764 if (type->facetSet != NULL) { 17765 xmlSchemaFacetLinkPtr lin; 17766 17767 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17768 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17769 switch (lin->facet->whitespace) { 17770 case XML_SCHEMAS_FACET_PRESERVE: 17771 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17772 break; 17773 case XML_SCHEMAS_FACET_REPLACE: 17774 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17775 break; 17776 case XML_SCHEMAS_FACET_COLLAPSE: 17777 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17778 break; 17779 default: 17780 return (-1); 17781 } 17782 return (0); 17783 } 17784 } 17785 } 17786 /* 17787 * For all �atomic� datatypes other than string (and types �derived� 17788 * by �restriction� from it) the value of whiteSpace is fixed to 17789 * collapse 17790 */ 17791 { 17792 xmlSchemaTypePtr anc; 17793 17794 for (anc = type->baseType; anc != NULL && 17795 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17796 anc = anc->baseType) { 17797 17798 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17799 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17800 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17801 17802 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17803 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17804 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17805 17806 } else 17807 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17808 break; 17809 } 17810 } 17811 } 17812 return (0); 17813} 17814 17815static int 17816xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17817 xmlSchemaTypePtr type) 17818{ 17819 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17820 return(0); 17821 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17822 return(0); 17823 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17824 17825 if (WXS_IS_LIST(type)) { 17826 /* 17827 * Corresponds to <simpleType><list>... 17828 */ 17829 if (type->subtypes == NULL) { 17830 /* 17831 * This one is really needed, so get out. 17832 */ 17833 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17834 "list type has no item-type assigned"); 17835 return(-1); 17836 } 17837 } else if (WXS_IS_UNION(type)) { 17838 /* 17839 * Corresponds to <simpleType><union>... 17840 */ 17841 if (type->memberTypes == NULL) { 17842 /* 17843 * This one is really needed, so get out. 17844 */ 17845 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17846 "union type has no member-types assigned"); 17847 return(-1); 17848 } 17849 } else { 17850 /* 17851 * Corresponds to <simpleType><restriction>... 17852 */ 17853 if (type->baseType == NULL) { 17854 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17855 "type has no base-type assigned"); 17856 return(-1); 17857 } 17858 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17859 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17860 return(-1); 17861 /* 17862 * Variety 17863 * If the <restriction> alternative is chosen, then the 17864 * {variety} of the {base type definition}. 17865 */ 17866 if (WXS_IS_ATOMIC(type->baseType)) 17867 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17868 else if (WXS_IS_LIST(type->baseType)) { 17869 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17870 /* 17871 * Inherit the itemType. 17872 */ 17873 type->subtypes = type->baseType->subtypes; 17874 } else if (WXS_IS_UNION(type->baseType)) { 17875 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 17876 /* 17877 * NOTE that we won't assign the memberTypes of the base, 17878 * since this will make trouble when freeing them; we will 17879 * use a lookup function to access them instead. 17880 */ 17881 } 17882 } 17883 return(0); 17884} 17885 17886#ifdef DEBUG_TYPE 17887static void 17888xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 17889 xmlSchemaTypePtr type) 17890{ 17891 if (type->node != NULL) { 17892 xmlGenericError(xmlGenericErrorContext, 17893 "Type of %s : %s:%d :", name, 17894 type->node->doc->URL, 17895 xmlGetLineNo(type->node)); 17896 } else { 17897 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 17898 } 17899 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 17900 switch (type->contentType) { 17901 case XML_SCHEMA_CONTENT_SIMPLE: 17902 xmlGenericError(xmlGenericErrorContext, "simple\n"); 17903 break; 17904 case XML_SCHEMA_CONTENT_ELEMENTS: 17905 xmlGenericError(xmlGenericErrorContext, "elements\n"); 17906 break; 17907 case XML_SCHEMA_CONTENT_UNKNOWN: 17908 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 17909 break; 17910 case XML_SCHEMA_CONTENT_EMPTY: 17911 xmlGenericError(xmlGenericErrorContext, "empty\n"); 17912 break; 17913 case XML_SCHEMA_CONTENT_MIXED: 17914 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 17915 type->subtypes)) 17916 xmlGenericError(xmlGenericErrorContext, 17917 "mixed as emptiable particle\n"); 17918 else 17919 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 17920 break; 17921 /* Removed, since not used. */ 17922 /* 17923 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 17924 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 17925 break; 17926 */ 17927 case XML_SCHEMA_CONTENT_BASIC: 17928 xmlGenericError(xmlGenericErrorContext, "basic\n"); 17929 break; 17930 default: 17931 xmlGenericError(xmlGenericErrorContext, 17932 "not registered !!!\n"); 17933 break; 17934 } 17935 } 17936} 17937#endif 17938 17939/* 17940* 3.14.6 Constraints on Simple Type Definition Schema Components 17941*/ 17942static int 17943xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 17944 xmlSchemaTypePtr type) 17945{ 17946 int res, olderrs = pctxt->nberrors; 17947 17948 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17949 return(-1); 17950 17951 if (! WXS_IS_TYPE_NOT_FIXED(type)) 17952 return(0); 17953 17954 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 17955 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 17956 17957 if (type->baseType == NULL) { 17958 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 17959 "missing baseType"); 17960 goto exit_failure; 17961 } 17962 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 17963 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 17964 /* 17965 * If a member type of a union is a union itself, we need to substitute 17966 * that member type for its member types. 17967 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 17968 * types in WXS 1.1. 17969 */ 17970 if ((type->memberTypes != NULL) && 17971 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 17972 return(-1); 17973 /* 17974 * SPEC src-simple-type 1 17975 * "The corresponding simple type definition, if any, must satisfy 17976 * the conditions set out in Constraints on Simple Type Definition 17977 * Schema Components (�3.14.6)." 17978 */ 17979 /* 17980 * Schema Component Constraint: Simple Type Definition Properties Correct 17981 * (st-props-correct) 17982 */ 17983 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 17984 HFAILURE HERROR 17985 /* 17986 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 17987 * (cos-st-restricts) 17988 */ 17989 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 17990 HFAILURE HERROR 17991 /* 17992 * TODO: Removed the error report, since it got annoying to get an 17993 * extra error report, if anything failed until now. 17994 * Enable this if needed. 17995 * 17996 * xmlSchemaPErr(ctxt, type->node, 17997 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 17998 * "Simple type '%s' does not satisfy the constraints " 17999 * "on simple type definitions.\n", 18000 * type->name, NULL); 18001 */ 18002 /* 18003 * Schema Component Constraint: Simple Type Restriction (Facets) 18004 * (st-restrict-facets) 18005 */ 18006 res = xmlSchemaCheckFacetValues(type, pctxt); 18007 HFAILURE HERROR 18008 if ((type->facetSet != NULL) || 18009 (type->baseType->facetSet != NULL)) { 18010 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18011 HFAILURE HERROR 18012 } 18013 /* 18014 * Whitespace value. 18015 */ 18016 res = xmlSchemaTypeFixupWhitespace(type); 18017 HFAILURE HERROR 18018 xmlSchemaTypeFixupOptimFacets(type); 18019 18020exit_error: 18021#ifdef DEBUG_TYPE 18022 xmlSchemaDebugFixedType(pctxt, type); 18023#endif 18024 if (olderrs != pctxt->nberrors) 18025 return(pctxt->err); 18026 return(0); 18027 18028exit_failure: 18029#ifdef DEBUG_TYPE 18030 xmlSchemaDebugFixedType(pctxt, type); 18031#endif 18032 return(-1); 18033} 18034 18035static int 18036xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18037 xmlSchemaTypePtr type) 18038{ 18039 int res = 0, olderrs = pctxt->nberrors; 18040 xmlSchemaTypePtr baseType = type->baseType; 18041 18042 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18043 return(0); 18044 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18045 if (baseType == NULL) { 18046 PERROR_INT("xmlSchemaFixupComplexType", 18047 "missing baseType"); 18048 goto exit_failure; 18049 } 18050 /* 18051 * Fixup the base type. 18052 */ 18053 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18054 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18055 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18056 /* 18057 * Skip fixup if the base type is invalid. 18058 * TODO: Generate a warning! 18059 */ 18060 return(0); 18061 } 18062 /* 18063 * This basically checks if the base type can be derived. 18064 */ 18065 res = xmlSchemaCheckSRCCT(pctxt, type); 18066 HFAILURE HERROR 18067 /* 18068 * Fixup the content type. 18069 */ 18070 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18071 /* 18072 * Corresponds to <complexType><simpleContent>... 18073 */ 18074 if ((WXS_IS_COMPLEX(baseType)) && 18075 (baseType->contentTypeDef != NULL) && 18076 (WXS_IS_RESTRICTION(type))) { 18077 xmlSchemaTypePtr contentBase, content; 18078#ifdef ENABLE_NAMED_LOCALS 18079 char buf[30]; 18080 const xmlChar *tmpname; 18081#endif 18082 /* 18083 * SPEC (1) If <restriction> + base type is <complexType>, 18084 * "whose own {content type} is a simple type..." 18085 */ 18086 if (type->contentTypeDef != NULL) { 18087 /* 18088 * SPEC (1.1) "the simple type definition corresponding to the 18089 * <simpleType> among the [children] of <restriction> if there 18090 * is one;" 18091 * Note that this "<simpleType> among the [children]" was put 18092 * into ->contentTypeDef during parsing. 18093 */ 18094 contentBase = type->contentTypeDef; 18095 type->contentTypeDef = NULL; 18096 } else { 18097 /* 18098 * (1.2) "...otherwise (<restriction> has no <simpleType> 18099 * among its [children]), the simple type definition which 18100 * is the {content type} of the ... base type." 18101 */ 18102 contentBase = baseType->contentTypeDef; 18103 } 18104 /* 18105 * SPEC 18106 * "... a simple type definition which restricts the simple 18107 * type definition identified in clause 1.1 or clause 1.2 18108 * with a set of facet components" 18109 * 18110 * Create the anonymous simple type, which will be the content 18111 * type of the complex type. 18112 */ 18113#ifdef ENABLE_NAMED_LOCALS 18114 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18115 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18116 content = xmlSchemaAddType(pctxt, pctxt->schema, 18117 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18118 type->node, 0); 18119#else 18120 content = xmlSchemaAddType(pctxt, pctxt->schema, 18121 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18122 type->node, 0); 18123#endif 18124 if (content == NULL) 18125 goto exit_failure; 18126 /* 18127 * We will use the same node as for the <complexType> 18128 * to have it somehow anchored in the schema doc. 18129 */ 18130 content->type = XML_SCHEMA_TYPE_SIMPLE; 18131 content->baseType = contentBase; 18132 /* 18133 * Move the facets, previously anchored on the 18134 * complexType during parsing. 18135 */ 18136 content->facets = type->facets; 18137 type->facets = NULL; 18138 content->facetSet = type->facetSet; 18139 type->facetSet = NULL; 18140 18141 type->contentTypeDef = content; 18142 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18143 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18144 /* 18145 * Fixup the newly created type. We don't need to check 18146 * for circularity here. 18147 */ 18148 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18149 HFAILURE HERROR 18150 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18151 HFAILURE HERROR 18152 18153 } else if ((WXS_IS_COMPLEX(baseType)) && 18154 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18155 (WXS_IS_RESTRICTION(type))) { 18156 /* 18157 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18158 * an emptiable particle, then a simple type definition which 18159 * restricts the <restriction>'s <simpleType> child. 18160 */ 18161 if ((type->contentTypeDef == NULL) || 18162 (type->contentTypeDef->baseType == NULL)) { 18163 /* 18164 * TODO: Check if this ever happens. 18165 */ 18166 xmlSchemaPCustomErr(pctxt, 18167 XML_SCHEMAP_INTERNAL, 18168 WXS_BASIC_CAST type, NULL, 18169 "Internal error: xmlSchemaTypeFixup, " 18170 "complex type '%s': the <simpleContent><restriction> " 18171 "is missing a <simpleType> child, but was not catched " 18172 "by xmlSchemaCheckSRCCT()", type->name); 18173 goto exit_failure; 18174 } 18175 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18176 /* 18177 * SPEC (3) If <extension> + base is <complexType> with 18178 * <simpleType> content, "...then the {content type} of that 18179 * complex type definition" 18180 */ 18181 if (baseType->contentTypeDef == NULL) { 18182 /* 18183 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18184 * should have catched this already. 18185 */ 18186 xmlSchemaPCustomErr(pctxt, 18187 XML_SCHEMAP_INTERNAL, 18188 WXS_BASIC_CAST type, NULL, 18189 "Internal error: xmlSchemaTypeFixup, " 18190 "complex type '%s': the <extension>ed base type is " 18191 "a complex type with no simple content type", 18192 type->name); 18193 goto exit_failure; 18194 } 18195 type->contentTypeDef = baseType->contentTypeDef; 18196 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18197 /* 18198 * SPEC (4) <extension> + base is <simpleType> 18199 * "... then that simple type definition" 18200 */ 18201 type->contentTypeDef = baseType; 18202 } else { 18203 /* 18204 * TODO: Check if this ever happens. 18205 */ 18206 xmlSchemaPCustomErr(pctxt, 18207 XML_SCHEMAP_INTERNAL, 18208 WXS_BASIC_CAST type, NULL, 18209 "Internal error: xmlSchemaTypeFixup, " 18210 "complex type '%s' with <simpleContent>: unhandled " 18211 "derivation case", type->name); 18212 goto exit_failure; 18213 } 18214 } else { 18215 int dummySequence = 0; 18216 xmlSchemaParticlePtr particle = 18217 (xmlSchemaParticlePtr) type->subtypes; 18218 /* 18219 * Corresponds to <complexType><complexContent>... 18220 * 18221 * NOTE that the effective mixed was already set during parsing of 18222 * <complexType> and <complexContent>; its flag value is 18223 * XML_SCHEMAS_TYPE_MIXED. 18224 * 18225 * Compute the "effective content": 18226 * (2.1.1) + (2.1.2) + (2.1.3) 18227 */ 18228 if ((particle == NULL) || 18229 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18230 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18231 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18232 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18233 (particle->minOccurs == 0))) && 18234 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18235 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18236 /* 18237 * SPEC (2.1.4) "If the �effective mixed� is true, then 18238 * a particle whose properties are as follows:..." 18239 * 18240 * Empty sequence model group with 18241 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18242 * NOTE that we sill assign it the <complexType> node to 18243 * somehow anchor it in the doc. 18244 */ 18245 if ((particle == NULL) || 18246 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18247 /* 18248 * Create the particle. 18249 */ 18250 particle = xmlSchemaAddParticle(pctxt, 18251 type->node, 1, 1); 18252 if (particle == NULL) 18253 goto exit_failure; 18254 /* 18255 * Create the model group. 18256 */ /* URGENT TODO: avoid adding to pending items. */ 18257 particle->children = (xmlSchemaTreeItemPtr) 18258 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18259 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18260 if (particle->children == NULL) 18261 goto exit_failure; 18262 18263 type->subtypes = (xmlSchemaTypePtr) particle; 18264 } 18265 dummySequence = 1; 18266 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18267 } else { 18268 /* 18269 * SPEC (2.1.5) "otherwise empty" 18270 */ 18271 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18272 } 18273 } else { 18274 /* 18275 * SPEC (2.2) "otherwise the particle corresponding to the 18276 * <all>, <choice>, <group> or <sequence> among the 18277 * [children]." 18278 */ 18279 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18280 } 18281 /* 18282 * Compute the "content type". 18283 */ 18284 if (WXS_IS_RESTRICTION(type)) { 18285 /* 18286 * SPEC (3.1) "If <restriction>..." 18287 * (3.1.1) + (3.1.2) */ 18288 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18289 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18290 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18291 } 18292 } else { 18293 /* 18294 * SPEC (3.2) "If <extension>..." 18295 */ 18296 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18297 /* 18298 * SPEC (3.2.1) 18299 * "If the �effective content� is empty, then the 18300 * {content type} of the [...] base ..." 18301 */ 18302 type->contentType = baseType->contentType; 18303 type->subtypes = baseType->subtypes; 18304 /* 18305 * Fixes bug #347316: 18306 * This is the case when the base type has a simple 18307 * type definition as content. 18308 */ 18309 type->contentTypeDef = baseType->contentTypeDef; 18310 /* 18311 * NOTE that the effective mixed is ignored here. 18312 */ 18313 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18314 /* 18315 * SPEC (3.2.2) 18316 */ 18317 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18318 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18319 } else { 18320 /* 18321 * SPEC (3.2.3) 18322 */ 18323 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18324 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18325 /* 18326 * "A model group whose {compositor} is sequence and whose 18327 * {particles} are..." 18328 */ 18329 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18330 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18331 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18332 XML_SCHEMA_TYPE_ALL)) 18333 { 18334 /* 18335 * SPEC cos-all-limited (1) 18336 */ 18337 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18338 /* TODO: error code */ 18339 XML_SCHEMAP_COS_ALL_LIMITED, 18340 WXS_ITEM_NODE(type), NULL, 18341 "The type has an 'all' model group in its " 18342 "{content type} and thus cannot be derived from " 18343 "a non-empty type, since this would produce a " 18344 "'sequence' model group containing the 'all' " 18345 "model group; 'all' model groups are not " 18346 "allowed to appear inside other model groups", 18347 NULL, NULL); 18348 18349 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18350 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18351 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18352 XML_SCHEMA_TYPE_ALL)) 18353 { 18354 /* 18355 * SPEC cos-all-limited (1) 18356 */ 18357 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18358 /* TODO: error code */ 18359 XML_SCHEMAP_COS_ALL_LIMITED, 18360 WXS_ITEM_NODE(type), NULL, 18361 "A type cannot be derived by extension from a type " 18362 "which has an 'all' model group in its " 18363 "{content type}, since this would produce a " 18364 "'sequence' model group containing the 'all' " 18365 "model group; 'all' model groups are not " 18366 "allowed to appear inside other model groups", 18367 NULL, NULL); 18368 18369 } else if (! dummySequence) { 18370 xmlSchemaTreeItemPtr effectiveContent = 18371 (xmlSchemaTreeItemPtr) type->subtypes; 18372 /* 18373 * Create the particle. 18374 */ 18375 particle = xmlSchemaAddParticle(pctxt, 18376 type->node, 1, 1); 18377 if (particle == NULL) 18378 goto exit_failure; 18379 /* 18380 * Create the "sequence" model group. 18381 */ 18382 particle->children = (xmlSchemaTreeItemPtr) 18383 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18384 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18385 if (particle->children == NULL) 18386 goto exit_failure; 18387 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18388 /* 18389 * SPEC "the particle of the {content type} of 18390 * the ... base ..." 18391 * Create a duplicate of the base type's particle 18392 * and assign its "term" to it. 18393 */ 18394 particle->children->children = 18395 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18396 type->node, 18397 ((xmlSchemaParticlePtr) type->subtypes)->minOccurs, 18398 ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs); 18399 if (particle->children->children == NULL) 18400 goto exit_failure; 18401 particle = (xmlSchemaParticlePtr) 18402 particle->children->children; 18403 particle->children = 18404 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18405 /* 18406 * SPEC "followed by the �effective content�." 18407 */ 18408 particle->next = effectiveContent; 18409 /* 18410 * This all will result in: 18411 * new-particle 18412 * --> new-sequence( 18413 * new-particle 18414 * --> base-model, 18415 * this-particle 18416 * --> this-model 18417 * ) 18418 */ 18419 } else { 18420 /* 18421 * This is the case when there is already an empty 18422 * <sequence> with minOccurs==maxOccurs==1. 18423 * Just add the base types's content type. 18424 * NOTE that, although we miss to add an intermediate 18425 * <sequence>, this should produce no difference to 18426 * neither the regex compilation of the content model, 18427 * nor to the complex type contraints. 18428 */ 18429 particle->children->children = 18430 (xmlSchemaTreeItemPtr) baseType->subtypes; 18431 } 18432 } 18433 } 18434 } 18435 /* 18436 * Now fixup attribute uses: 18437 * - expand attr. group references 18438 * - intersect attribute wildcards 18439 * - inherit attribute uses of the base type 18440 * - inherit or union attr. wildcards if extending 18441 * - apply attr. use prohibitions if restricting 18442 */ 18443 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18444 HFAILURE HERROR 18445 /* 18446 * Apply the complex type component constraints; this will not 18447 * check attributes, since this is done in 18448 * xmlSchemaFixupTypeAttributeUses(). 18449 */ 18450 res = xmlSchemaCheckCTComponent(pctxt, type); 18451 HFAILURE HERROR 18452 18453#ifdef DEBUG_TYPE 18454 xmlSchemaDebugFixedType(pctxt, type); 18455#endif 18456 if (olderrs != pctxt->nberrors) 18457 return(pctxt->err); 18458 else 18459 return(0); 18460 18461exit_error: 18462 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18463#ifdef DEBUG_TYPE 18464 xmlSchemaDebugFixedType(pctxt, type); 18465#endif 18466 return(pctxt->err); 18467 18468exit_failure: 18469 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18470#ifdef DEBUG_TYPE 18471 xmlSchemaDebugFixedType(pctxt, type); 18472#endif 18473 return(-1); 18474} 18475 18476 18477/** 18478 * xmlSchemaTypeFixup: 18479 * @typeDecl: the schema type definition 18480 * @ctxt: the schema parser context 18481 * 18482 * Fixes the content model of the type. 18483 * URGENT TODO: We need an int result! 18484 */ 18485static int 18486xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18487 xmlSchemaAbstractCtxtPtr actxt) 18488{ 18489 if (type == NULL) 18490 return(0); 18491 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18492 AERROR_INT("xmlSchemaTypeFixup", 18493 "this function needs a parser context"); 18494 return(-1); 18495 } 18496 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18497 return(0); 18498 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18499 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18500 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18501 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18502 return(0); 18503} 18504 18505/** 18506 * xmlSchemaCheckFacet: 18507 * @facet: the facet 18508 * @typeDecl: the schema type definition 18509 * @pctxt: the schema parser context or NULL 18510 * @name: the optional name of the type 18511 * 18512 * Checks and computes the values of facets. 18513 * 18514 * Returns 0 if valid, a positive error code if not valid and 18515 * -1 in case of an internal or API error. 18516 */ 18517int 18518xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18519 xmlSchemaTypePtr typeDecl, 18520 xmlSchemaParserCtxtPtr pctxt, 18521 const xmlChar * name ATTRIBUTE_UNUSED) 18522{ 18523 int ret = 0, ctxtGiven; 18524 18525 if ((facet == NULL) || (typeDecl == NULL)) 18526 return(-1); 18527 /* 18528 * TODO: will the parser context be given if used from 18529 * the relaxNG module? 18530 */ 18531 if (pctxt == NULL) 18532 ctxtGiven = 0; 18533 else 18534 ctxtGiven = 1; 18535 18536 switch (facet->type) { 18537 case XML_SCHEMA_FACET_MININCLUSIVE: 18538 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18539 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18540 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18541 case XML_SCHEMA_FACET_ENUMERATION: { 18542 /* 18543 * Okay we need to validate the value 18544 * at that point. 18545 */ 18546 xmlSchemaTypePtr base; 18547 18548 /* 4.3.5.5 Constraints on enumeration Schema Components 18549 * Schema Component Constraint: enumeration valid restriction 18550 * It is an �error� if any member of {value} is not in the 18551 * �value space� of {base type definition}. 18552 * 18553 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18554 * The value �must� be in the 18555 * �value space� of the �base type�. 18556 */ 18557 /* 18558 * This function is intended to deliver a compiled value 18559 * on the facet. In this implementation of XML Schemata the 18560 * type holding a facet, won't be a built-in type. 18561 * Thus to ensure that other API 18562 * calls (relaxng) do work, if the given type is a built-in 18563 * type, we will assume that the given built-in type *is 18564 * already* the base type. 18565 */ 18566 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18567 base = typeDecl->baseType; 18568 if (base == NULL) { 18569 PERROR_INT("xmlSchemaCheckFacet", 18570 "a type user derived type has no base type"); 18571 return (-1); 18572 } 18573 } else 18574 base = typeDecl; 18575 18576 if (! ctxtGiven) { 18577 /* 18578 * A context is needed if called from RelaxNG. 18579 */ 18580 pctxt = xmlSchemaNewParserCtxt("*"); 18581 if (pctxt == NULL) 18582 return (-1); 18583 } 18584 /* 18585 * NOTE: This call does not check the content nodes, 18586 * since they are not available: 18587 * facet->node is just the node holding the facet 18588 * definition, *not* the attribute holding the *value* 18589 * of the facet. 18590 */ 18591 ret = xmlSchemaVCheckCVCSimpleType( 18592 ACTXT_CAST pctxt, facet->node, base, 18593 facet->value, &(facet->val), 1, 1, 0); 18594 if (ret != 0) { 18595 if (ret < 0) { 18596 /* No error message for RelaxNG. */ 18597 if (ctxtGiven) { 18598 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18599 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18600 "Internal error: xmlSchemaCheckFacet, " 18601 "failed to validate the value '%s' of the " 18602 "facet '%s' against the base type", 18603 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18604 } 18605 goto internal_error; 18606 } 18607 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18608 /* No error message for RelaxNG. */ 18609 if (ctxtGiven) { 18610 xmlChar *str = NULL; 18611 18612 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18613 ret, facet->node, WXS_BASIC_CAST facet, 18614 "The value '%s' of the facet does not validate " 18615 "against the base type '%s'", 18616 facet->value, 18617 xmlSchemaFormatQName(&str, 18618 base->targetNamespace, base->name)); 18619 FREE_AND_NULL(str); 18620 } 18621 goto exit; 18622 } else if (facet->val == NULL) { 18623 if (ctxtGiven) { 18624 PERROR_INT("xmlSchemaCheckFacet", 18625 "value was not computed"); 18626 } 18627 TODO 18628 } 18629 break; 18630 } 18631 case XML_SCHEMA_FACET_PATTERN: 18632 facet->regexp = xmlRegexpCompile(facet->value); 18633 if (facet->regexp == NULL) { 18634 ret = XML_SCHEMAP_REGEXP_INVALID; 18635 /* No error message for RelaxNG. */ 18636 if (ctxtGiven) { 18637 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18638 ret, facet->node, WXS_BASIC_CAST typeDecl, 18639 "The value '%s' of the facet 'pattern' is not a " 18640 "valid regular expression", 18641 facet->value, NULL); 18642 } 18643 } 18644 break; 18645 case XML_SCHEMA_FACET_TOTALDIGITS: 18646 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18647 case XML_SCHEMA_FACET_LENGTH: 18648 case XML_SCHEMA_FACET_MAXLENGTH: 18649 case XML_SCHEMA_FACET_MINLENGTH: 18650 18651 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18652 ret = xmlSchemaValidatePredefinedType( 18653 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18654 facet->value, &(facet->val)); 18655 } else { 18656 ret = xmlSchemaValidatePredefinedType( 18657 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18658 facet->value, &(facet->val)); 18659 } 18660 if (ret != 0) { 18661 if (ret < 0) { 18662 /* No error message for RelaxNG. */ 18663 if (ctxtGiven) { 18664 PERROR_INT("xmlSchemaCheckFacet", 18665 "validating facet value"); 18666 } 18667 goto internal_error; 18668 } 18669 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18670 /* No error message for RelaxNG. */ 18671 if (ctxtGiven) { 18672 /* error code */ 18673 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18674 ret, facet->node, WXS_BASIC_CAST typeDecl, 18675 "The value '%s' of the facet '%s' is not a valid '%s'", 18676 facet->value, 18677 xmlSchemaFacetTypeToString(facet->type), 18678 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18679 BAD_CAST "nonNegativeInteger" : 18680 BAD_CAST "positiveInteger", 18681 NULL); 18682 } 18683 } 18684 break; 18685 18686 case XML_SCHEMA_FACET_WHITESPACE:{ 18687 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18688 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18689 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18690 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18691 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18692 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18693 } else { 18694 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18695 /* No error message for RelaxNG. */ 18696 if (ctxtGiven) { 18697 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18698 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18699 ret, facet->node, WXS_BASIC_CAST typeDecl, 18700 "The value '%s' of the facet 'whitespace' is not " 18701 "valid", facet->value, NULL); 18702 } 18703 } 18704 } 18705 default: 18706 break; 18707 } 18708exit: 18709 if ((! ctxtGiven) && (pctxt != NULL)) 18710 xmlSchemaFreeParserCtxt(pctxt); 18711 return (ret); 18712internal_error: 18713 if ((! ctxtGiven) && (pctxt != NULL)) 18714 xmlSchemaFreeParserCtxt(pctxt); 18715 return (-1); 18716} 18717 18718/** 18719 * xmlSchemaCheckFacetValues: 18720 * @typeDecl: the schema type definition 18721 * @ctxt: the schema parser context 18722 * 18723 * Checks the default values types, especially for facets 18724 */ 18725static int 18726xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18727 xmlSchemaParserCtxtPtr pctxt) 18728{ 18729 int res, olderrs = pctxt->nberrors; 18730 const xmlChar *name = typeDecl->name; 18731 /* 18732 * NOTE: It is intended to use the facets list, instead 18733 * of facetSet. 18734 */ 18735 if (typeDecl->facets != NULL) { 18736 xmlSchemaFacetPtr facet = typeDecl->facets; 18737 18738 /* 18739 * Temporarily assign the "schema" to the validation context 18740 * of the parser context. This is needed for NOTATION validation. 18741 */ 18742 if (pctxt->vctxt == NULL) { 18743 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18744 return(-1); 18745 } 18746 pctxt->vctxt->schema = pctxt->schema; 18747 while (facet != NULL) { 18748 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18749 HFAILURE 18750 facet = facet->next; 18751 } 18752 pctxt->vctxt->schema = NULL; 18753 } 18754 if (olderrs != pctxt->nberrors) 18755 return(pctxt->err); 18756 return(0); 18757exit_failure: 18758 return(-1); 18759} 18760 18761/** 18762 * xmlSchemaGetCircModelGrDefRef: 18763 * @ctxtMGroup: the searched model group 18764 * @selfMGroup: the second searched model group 18765 * @particle: the first particle 18766 * 18767 * This one is intended to be used by 18768 * xmlSchemaCheckGroupDefCircular only. 18769 * 18770 * Returns the particle with the circular model group definition reference, 18771 * otherwise NULL. 18772 */ 18773static xmlSchemaTreeItemPtr 18774xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18775 xmlSchemaTreeItemPtr particle) 18776{ 18777 xmlSchemaTreeItemPtr circ = NULL; 18778 xmlSchemaTreeItemPtr term; 18779 xmlSchemaModelGroupDefPtr gdef; 18780 18781 for (; particle != NULL; particle = particle->next) { 18782 term = particle->children; 18783 if (term == NULL) 18784 continue; 18785 switch (term->type) { 18786 case XML_SCHEMA_TYPE_GROUP: 18787 gdef = (xmlSchemaModelGroupDefPtr) term; 18788 if (gdef == groupDef) 18789 return (particle); 18790 /* 18791 * Mark this model group definition to avoid infinite 18792 * recursion on circular references not yet examined. 18793 */ 18794 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18795 continue; 18796 if (gdef->children != NULL) { 18797 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18798 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18799 gdef->children->children); 18800 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18801 if (circ != NULL) 18802 return (circ); 18803 } 18804 break; 18805 case XML_SCHEMA_TYPE_SEQUENCE: 18806 case XML_SCHEMA_TYPE_CHOICE: 18807 case XML_SCHEMA_TYPE_ALL: 18808 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18809 if (circ != NULL) 18810 return (circ); 18811 break; 18812 default: 18813 break; 18814 } 18815 } 18816 return (NULL); 18817} 18818 18819/** 18820 * xmlSchemaCheckGroupDefCircular: 18821 * @item: the model group definition 18822 * @ctxt: the parser context 18823 * @name: the name 18824 * 18825 * Checks for circular references to model group definitions. 18826 */ 18827static void 18828xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18829 xmlSchemaParserCtxtPtr ctxt) 18830{ 18831 /* 18832 * Schema Component Constraint: Model Group Correct 18833 * 2 Circular groups are disallowed. That is, within the {particles} 18834 * of a group there must not be at any depth a particle whose {term} 18835 * is the group itself. 18836 */ 18837 if ((item == NULL) || 18838 (item->type != XML_SCHEMA_TYPE_GROUP) || 18839 (item->children == NULL)) 18840 return; 18841 { 18842 xmlSchemaTreeItemPtr circ; 18843 18844 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18845 if (circ != NULL) { 18846 xmlChar *str = NULL; 18847 /* 18848 * TODO: The error report is not adequate: this constraint 18849 * is defined for model groups but not definitions, but since 18850 * there cannot be any circular model groups without a model group 18851 * definition (if not using a construction API), we check those 18852 * defintions only. 18853 */ 18854 xmlSchemaPCustomErr(ctxt, 18855 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18856 NULL, WXS_ITEM_NODE(circ), 18857 "Circular reference to the model group definition '%s' " 18858 "defined", xmlSchemaFormatQName(&str, 18859 item->targetNamespace, item->name)); 18860 FREE_AND_NULL(str) 18861 /* 18862 * NOTE: We will cut the reference to avoid further 18863 * confusion of the processor. This is a fatal error. 18864 */ 18865 circ->children = NULL; 18866 } 18867 } 18868} 18869 18870/** 18871 * xmlSchemaModelGroupToModelGroupDefFixup: 18872 * @ctxt: the parser context 18873 * @mg: the model group 18874 * 18875 * Assigns the model group of model group definitions to the "term" 18876 * of the referencing particle. 18877 * In xmlSchemaResolveModelGroupParticleReferences the model group 18878 * definitions were assigned to the "term", since needed for the 18879 * circularity check. 18880 * 18881 * Schema Component Constraint: 18882 * All Group Limited (cos-all-limited) (1.2) 18883 */ 18884static void 18885xmlSchemaModelGroupToModelGroupDefFixup( 18886 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 18887 xmlSchemaModelGroupPtr mg) 18888{ 18889 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 18890 18891 while (particle != NULL) { 18892 if ((WXS_PARTICLE_TERM(particle) == NULL) || 18893 ((WXS_PARTICLE_TERM(particle))->type != 18894 XML_SCHEMA_TYPE_GROUP)) 18895 { 18896 particle = WXS_PTC_CAST particle->next; 18897 continue; 18898 } 18899 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 18900 /* 18901 * TODO: Remove the particle. 18902 */ 18903 WXS_PARTICLE_TERM(particle) = NULL; 18904 particle = WXS_PTC_CAST particle->next; 18905 continue; 18906 } 18907 /* 18908 * Assign the model group to the {term} of the particle. 18909 */ 18910 WXS_PARTICLE_TERM(particle) = 18911 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 18912 18913 particle = WXS_PTC_CAST particle->next; 18914 } 18915} 18916 18917/** 18918 * xmlSchemaCheckAttrGroupCircularRecur: 18919 * @ctxtGr: the searched attribute group 18920 * @attr: the current attribute list to be processed 18921 * 18922 * This one is intended to be used by 18923 * xmlSchemaCheckAttrGroupCircular only. 18924 * 18925 * Returns the circular attribute grou reference, otherwise NULL. 18926 */ 18927static xmlSchemaQNameRefPtr 18928xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 18929 xmlSchemaItemListPtr list) 18930{ 18931 xmlSchemaAttributeGroupPtr gr; 18932 xmlSchemaQNameRefPtr ref, circ; 18933 int i; 18934 /* 18935 * We will search for an attribute group reference which 18936 * references the context attribute group. 18937 */ 18938 for (i = 0; i < list->nbItems; i++) { 18939 ref = list->items[i]; 18940 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 18941 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 18942 (ref->item != NULL)) 18943 { 18944 gr = WXS_ATTR_GROUP_CAST ref->item; 18945 if (gr == ctxtGr) 18946 return(ref); 18947 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 18948 continue; 18949 /* 18950 * Mark as visited to avoid infinite recursion on 18951 * circular references not yet examined. 18952 */ 18953 if ((gr->attrUses) && 18954 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 18955 { 18956 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 18957 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 18958 (xmlSchemaItemListPtr) gr->attrUses); 18959 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 18960 if (circ != NULL) 18961 return (circ); 18962 } 18963 18964 } 18965 } 18966 return (NULL); 18967} 18968 18969/** 18970 * xmlSchemaCheckAttrGroupCircular: 18971 * attrGr: the attribute group definition 18972 * @ctxt: the parser context 18973 * @name: the name 18974 * 18975 * Checks for circular references of attribute groups. 18976 */ 18977static int 18978xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 18979 xmlSchemaParserCtxtPtr ctxt) 18980{ 18981 /* 18982 * Schema Representation Constraint: 18983 * Attribute Group Definition Representation OK 18984 * 3 Circular group reference is disallowed outside <redefine>. 18985 * That is, unless this element information item's parent is 18986 * <redefine>, then among the [children], if any, there must 18987 * not be an <attributeGroup> with ref [attribute] which resolves 18988 * to the component corresponding to this <attributeGroup>. Indirect 18989 * circularity is also ruled out. That is, when QName resolution 18990 * (Schema Document) (�3.15.3) is applied to a �QName� arising from 18991 * any <attributeGroup>s with a ref [attribute] among the [children], 18992 * it must not be the case that a �QName� is encountered at any depth 18993 * which resolves to the component corresponding to this <attributeGroup>. 18994 */ 18995 if (attrGr->attrUses == NULL) 18996 return(0); 18997 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 18998 return(0); 18999 else { 19000 xmlSchemaQNameRefPtr circ; 19001 19002 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19003 (xmlSchemaItemListPtr) attrGr->attrUses); 19004 if (circ != NULL) { 19005 xmlChar *str = NULL; 19006 /* 19007 * TODO: Report the referenced attr group as QName. 19008 */ 19009 xmlSchemaPCustomErr(ctxt, 19010 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19011 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19012 "Circular reference to the attribute group '%s' " 19013 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19014 FREE_AND_NULL(str); 19015 /* 19016 * NOTE: We will cut the reference to avoid further 19017 * confusion of the processor. 19018 * BADSPEC TODO: The spec should define how to process in this case. 19019 */ 19020 circ->item = NULL; 19021 return(ctxt->err); 19022 } 19023 } 19024 return(0); 19025} 19026 19027static int 19028xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19029 xmlSchemaAttributeGroupPtr attrGr); 19030 19031/** 19032 * xmlSchemaExpandAttributeGroupRefs: 19033 * @pctxt: the parser context 19034 * @node: the node of the component holding the attribute uses 19035 * @completeWild: the intersected wildcard to be returned 19036 * @list: the attribute uses 19037 * 19038 * Substitutes contained attribute group references 19039 * for their attribute uses. Wilcards are intersected. 19040 * Attribute use prohibitions are removed from the list 19041 * and returned via the @prohibs list. 19042 * Pointlessness of attr. prohibs, if a matching attr. decl 19043 * is existent a well, are checked. 19044 */ 19045static int 19046xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19047 xmlSchemaBasicItemPtr item, 19048 xmlSchemaWildcardPtr *completeWild, 19049 xmlSchemaItemListPtr list, 19050 xmlSchemaItemListPtr prohibs) 19051{ 19052 xmlSchemaAttributeGroupPtr gr; 19053 xmlSchemaAttributeUsePtr use; 19054 xmlSchemaItemListPtr sublist; 19055 int i, j; 19056 int created = (*completeWild == NULL) ? 0 : 1; 19057 19058 if (prohibs) 19059 prohibs->nbItems = 0; 19060 19061 for (i = 0; i < list->nbItems; i++) { 19062 use = list->items[i]; 19063 19064 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19065 if (prohibs == NULL) { 19066 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19067 "unexpected attr prohibition found"); 19068 return(-1); 19069 } 19070 /* 19071 * Remove from attribute uses. 19072 */ 19073 if (xmlSchemaItemListRemove(list, i) == -1) 19074 return(-1); 19075 i--; 19076 /* 19077 * Note that duplicate prohibitions were already 19078 * handled at parsing time. 19079 */ 19080 /* 19081 * Add to list of prohibitions. 19082 */ 19083 xmlSchemaItemListAddSize(prohibs, 2, use); 19084 continue; 19085 } 19086 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19087 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19088 { 19089 if ((WXS_QNAME_CAST use)->item == NULL) 19090 return(-1); 19091 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19092 /* 19093 * Expand the referenced attr. group. 19094 * TODO: remove this, this is done in a previous step, so 19095 * already done here. 19096 */ 19097 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19098 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19099 return(-1); 19100 } 19101 /* 19102 * Build the 'complete' wildcard; i.e. intersect multiple 19103 * wildcards. 19104 */ 19105 if (gr->attributeWildcard != NULL) { 19106 if (*completeWild == NULL) { 19107 *completeWild = gr->attributeWildcard; 19108 } else { 19109 if (! created) { 19110 xmlSchemaWildcardPtr tmpWild; 19111 19112 /* 19113 * Copy the first encountered wildcard as context, 19114 * except for the annotation. 19115 * 19116 * Although the complete wildcard might not correspond 19117 * to any node in the schema, we will anchor it on 19118 * the node of the owner component. 19119 */ 19120 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19121 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19122 WXS_ITEM_NODE(item)); 19123 if (tmpWild == NULL) 19124 return(-1); 19125 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19126 tmpWild, *completeWild) == -1) 19127 return (-1); 19128 tmpWild->processContents = (*completeWild)->processContents; 19129 *completeWild = tmpWild; 19130 created = 1; 19131 } 19132 19133 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19134 gr->attributeWildcard) == -1) 19135 return(-1); 19136 } 19137 } 19138 /* 19139 * Just remove the reference if the referenced group does not 19140 * contain any attribute uses. 19141 */ 19142 if (gr->attrUses == NULL) { 19143 if (xmlSchemaItemListRemove(list, i) == -1) 19144 return(-1); 19145 i--; 19146 continue; 19147 } 19148 /* 19149 * Add the attribute uses. 19150 */ 19151 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19152 if (sublist->nbItems != 0) { 19153 list->items[i] = sublist->items[0]; 19154 if (sublist->nbItems != 1) { 19155 for (j = 1; j < sublist->nbItems; j++) { 19156 i++; 19157 if (xmlSchemaItemListInsert(list, 19158 sublist->items[j], i) == -1) 19159 return(-1); 19160 } 19161 } 19162 } 19163 } 19164 19165 } 19166 /* 19167 * Handle pointless prohibitions of declared attributes. 19168 */ 19169 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19170 xmlSchemaAttributeUseProhibPtr prohib; 19171 19172 for (i = prohibs->nbItems -1; i >= 0; i--) { 19173 prohib = prohibs->items[i]; 19174 for (j = 0; j < list->nbItems; j++) { 19175 use = list->items[j]; 19176 19177 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19178 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19179 { 19180 xmlChar *str = NULL; 19181 19182 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19183 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19184 prohib->node, NULL, 19185 "Skipping pointless attribute use prohibition " 19186 "'%s', since a corresponding attribute use " 19187 "exists already in the type definition", 19188 xmlSchemaFormatQName(&str, 19189 prohib->targetNamespace, prohib->name), 19190 NULL, NULL); 19191 FREE_AND_NULL(str); 19192 /* 19193 * Remove the prohibition. 19194 */ 19195 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19196 return(-1); 19197 break; 19198 } 19199 } 19200 } 19201 } 19202 return(0); 19203} 19204 19205/** 19206 * xmlSchemaAttributeGroupExpandRefs: 19207 * @pctxt: the parser context 19208 * @attrGr: the attribute group definition 19209 * 19210 * Computation of: 19211 * {attribute uses} property 19212 * {attribute wildcard} property 19213 * 19214 * Substitutes contained attribute group references 19215 * for their attribute uses. Wilcards are intersected. 19216 */ 19217static int 19218xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19219 xmlSchemaAttributeGroupPtr attrGr) 19220{ 19221 if ((attrGr->attrUses == NULL) || 19222 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19223 return(0); 19224 19225 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19226 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19227 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19228 return(-1); 19229 return(0); 19230} 19231 19232/** 19233 * xmlSchemaAttributeGroupExpandRefs: 19234 * @pctxt: the parser context 19235 * @attrGr: the attribute group definition 19236 * 19237 * Substitutes contained attribute group references 19238 * for their attribute uses. Wilcards are intersected. 19239 * 19240 * Schema Component Constraint: 19241 * Attribute Group Definition Properties Correct (ag-props-correct) 19242 */ 19243static int 19244xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19245 xmlSchemaAttributeGroupPtr attrGr) 19246{ 19247 /* 19248 * SPEC ag-props-correct 19249 * (1) "The values of the properties of an attribute group definition 19250 * must be as described in the property tableau in The Attribute 19251 * Group Definition Schema Component (�3.6.1), modulo the impact of 19252 * Missing Sub-components (�5.3);" 19253 */ 19254 19255 if ((attrGr->attrUses != NULL) && 19256 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19257 { 19258 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19259 xmlSchemaAttributeUsePtr use, tmp; 19260 int i, j, hasId = 0; 19261 19262 for (i = uses->nbItems -1; i >= 0; i--) { 19263 use = uses->items[i]; 19264 /* 19265 * SPEC ag-props-correct 19266 * (2) "Two distinct members of the {attribute uses} must not have 19267 * {attribute declaration}s both of whose {name}s match and whose 19268 * {target namespace}s are identical." 19269 */ 19270 if (i > 0) { 19271 for (j = i -1; j >= 0; j--) { 19272 tmp = uses->items[j]; 19273 if ((WXS_ATTRUSE_DECL_NAME(use) == 19274 WXS_ATTRUSE_DECL_NAME(tmp)) && 19275 (WXS_ATTRUSE_DECL_TNS(use) == 19276 WXS_ATTRUSE_DECL_TNS(tmp))) 19277 { 19278 xmlChar *str = NULL; 19279 19280 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19281 XML_SCHEMAP_AG_PROPS_CORRECT, 19282 attrGr->node, WXS_BASIC_CAST attrGr, 19283 "Duplicate %s", 19284 xmlSchemaGetComponentDesignation(&str, use), 19285 NULL); 19286 FREE_AND_NULL(str); 19287 /* 19288 * Remove the duplicate. 19289 */ 19290 if (xmlSchemaItemListRemove(uses, i) == -1) 19291 return(-1); 19292 goto next_use; 19293 } 19294 } 19295 } 19296 /* 19297 * SPEC ag-props-correct 19298 * (3) "Two distinct members of the {attribute uses} must not have 19299 * {attribute declaration}s both of whose {type definition}s are or 19300 * are derived from ID." 19301 * TODO: Does 'derived' include member-types of unions? 19302 */ 19303 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19304 if (xmlSchemaIsDerivedFromBuiltInType( 19305 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19306 { 19307 if (hasId) { 19308 xmlChar *str = NULL; 19309 19310 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19311 XML_SCHEMAP_AG_PROPS_CORRECT, 19312 attrGr->node, WXS_BASIC_CAST attrGr, 19313 "There must not exist more than one attribute " 19314 "declaration of type 'xs:ID' " 19315 "(or derived from 'xs:ID'). The %s violates this " 19316 "constraint", 19317 xmlSchemaGetComponentDesignation(&str, use), 19318 NULL); 19319 FREE_AND_NULL(str); 19320 if (xmlSchemaItemListRemove(uses, i) == -1) 19321 return(-1); 19322 } 19323 hasId = 1; 19324 } 19325 } 19326next_use: {} 19327 } 19328 } 19329 return(0); 19330} 19331 19332/** 19333 * xmlSchemaResolveAttrGroupReferences: 19334 * @attrgrpDecl: the schema attribute definition 19335 * @ctxt: the schema parser context 19336 * @name: the attribute name 19337 * 19338 * Resolves references to attribute group definitions. 19339 */ 19340static int 19341xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19342 xmlSchemaParserCtxtPtr ctxt) 19343{ 19344 xmlSchemaAttributeGroupPtr group; 19345 19346 if (ref->item != NULL) 19347 return(0); 19348 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19349 ref->name, 19350 ref->targetNamespace); 19351 if (group == NULL) { 19352 xmlSchemaPResCompAttrErr(ctxt, 19353 XML_SCHEMAP_SRC_RESOLVE, 19354 NULL, ref->node, 19355 "ref", ref->name, ref->targetNamespace, 19356 ref->itemType, NULL); 19357 return(ctxt->err); 19358 } 19359 ref->item = WXS_BASIC_CAST group; 19360 return(0); 19361} 19362 19363/** 19364 * xmlSchemaCheckAttrPropsCorrect: 19365 * @item: an schema attribute declaration/use 19366 * @ctxt: a schema parser context 19367 * @name: the name of the attribute 19368 * 19369 * 19370 * Schema Component Constraint: 19371 * Attribute Declaration Properties Correct (a-props-correct) 19372 * 19373 * Validates the value constraints of an attribute declaration/use. 19374 * NOTE that this needs the simle type definitions to be already 19375 * builded and checked. 19376 */ 19377static int 19378xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19379 xmlSchemaAttributePtr attr) 19380{ 19381 19382 /* 19383 * SPEC a-props-correct (1) 19384 * "The values of the properties of an attribute declaration must 19385 * be as described in the property tableau in The Attribute 19386 * Declaration Schema Component (�3.2.1), modulo the impact of 19387 * Missing Sub-components (�5.3)." 19388 */ 19389 19390 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19391 return(0); 19392 19393 if (attr->defValue != NULL) { 19394 int ret; 19395 19396 /* 19397 * SPEC a-props-correct (3) 19398 * "If the {type definition} is or is derived from ID then there 19399 * must not be a {value constraint}." 19400 */ 19401 if (xmlSchemaIsDerivedFromBuiltInType( 19402 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19403 { 19404 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19405 XML_SCHEMAP_A_PROPS_CORRECT_3, 19406 NULL, WXS_BASIC_CAST attr, 19407 "Value constraints are not allowed if the type definition " 19408 "is or is derived from xs:ID", 19409 NULL, NULL); 19410 return(pctxt->err); 19411 } 19412 /* 19413 * SPEC a-props-correct (2) 19414 * "if there is a {value constraint}, the canonical lexical 19415 * representation of its value must be �valid� with respect 19416 * to the {type definition} as defined in String Valid (�3.14.4)." 19417 * TODO: Don't care about the *cononical* stuff here, this requirement 19418 * will be removed in WXS 1.1 anyway. 19419 */ 19420 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19421 attr->node, WXS_ATTR_TYPEDEF(attr), 19422 attr->defValue, &(attr->defVal), 19423 1, 1, 0); 19424 if (ret != 0) { 19425 if (ret < 0) { 19426 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19427 "calling xmlSchemaVCheckCVCSimpleType()"); 19428 return(-1); 19429 } 19430 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19431 XML_SCHEMAP_A_PROPS_CORRECT_2, 19432 NULL, WXS_BASIC_CAST attr, 19433 "The value of the value constraint is not valid", 19434 NULL, NULL); 19435 return(pctxt->err); 19436 } 19437 } 19438 19439 return(0); 19440} 19441 19442static xmlSchemaElementPtr 19443xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19444 xmlSchemaElementPtr ancestor) 19445{ 19446 xmlSchemaElementPtr ret; 19447 19448 if (WXS_SUBST_HEAD(ancestor) == NULL) 19449 return (NULL); 19450 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19451 return (ancestor); 19452 19453 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19454 return (NULL); 19455 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19456 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19457 WXS_SUBST_HEAD(ancestor)); 19458 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19459 19460 return (ret); 19461} 19462 19463/** 19464 * xmlSchemaCheckElemPropsCorrect: 19465 * @ctxt: a schema parser context 19466 * @decl: the element declaration 19467 * @name: the name of the attribute 19468 * 19469 * Schema Component Constraint: 19470 * Element Declaration Properties Correct (e-props-correct) 19471 * 19472 * STATUS: 19473 * missing: (6) 19474 */ 19475static int 19476xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19477 xmlSchemaElementPtr elemDecl) 19478{ 19479 int ret = 0; 19480 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19481 /* 19482 * SPEC (1) "The values of the properties of an element declaration 19483 * must be as described in the property tableau in The Element 19484 * Declaration Schema Component (�3.3.1), modulo the impact of Missing 19485 * Sub-components (�5.3)." 19486 */ 19487 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19488 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19489 19490 xmlSchemaCheckElementDeclComponent(head, pctxt); 19491 /* 19492 * SPEC (3) "If there is a non-�absent� {substitution group 19493 * affiliation}, then {scope} must be global." 19494 */ 19495 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19496 xmlSchemaPCustomErr(pctxt, 19497 XML_SCHEMAP_E_PROPS_CORRECT_3, 19498 WXS_BASIC_CAST elemDecl, NULL, 19499 "Only global element declarations can have a " 19500 "substitution group affiliation", NULL); 19501 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19502 } 19503 /* 19504 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19505 * That is, it must not be possible to return to an element declaration 19506 * by repeatedly following the {substitution group affiliation} 19507 * property." 19508 */ 19509 if (head == elemDecl) 19510 circ = head; 19511 else if (WXS_SUBST_HEAD(head) != NULL) 19512 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19513 else 19514 circ = NULL; 19515 if (circ != NULL) { 19516 xmlChar *strA = NULL, *strB = NULL; 19517 19518 xmlSchemaPCustomErrExt(pctxt, 19519 XML_SCHEMAP_E_PROPS_CORRECT_6, 19520 WXS_BASIC_CAST circ, NULL, 19521 "The element declaration '%s' defines a circular " 19522 "substitution group to element declaration '%s'", 19523 xmlSchemaGetComponentQName(&strA, circ), 19524 xmlSchemaGetComponentQName(&strB, head), 19525 NULL); 19526 FREE_AND_NULL(strA) 19527 FREE_AND_NULL(strB) 19528 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19529 } 19530 /* 19531 * SPEC (4) "If there is a {substitution group affiliation}, 19532 * the {type definition} 19533 * of the element declaration must be validly derived from the {type 19534 * definition} of the {substitution group affiliation}, given the value 19535 * of the {substitution group exclusions} of the {substitution group 19536 * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6) 19537 * (if the {type definition} is complex) or as defined in 19538 * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is 19539 * simple)." 19540 * 19541 * NOTE: {substitution group exclusions} means the values of the 19542 * attribute "final". 19543 */ 19544 19545 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19546 int set = 0; 19547 19548 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19549 set |= SUBSET_EXTENSION; 19550 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19551 set |= SUBSET_RESTRICTION; 19552 19553 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19554 WXS_ELEM_TYPEDEF(head), set) != 0) { 19555 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19556 19557 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19558 xmlSchemaPCustomErrExt(pctxt, 19559 XML_SCHEMAP_E_PROPS_CORRECT_4, 19560 WXS_BASIC_CAST elemDecl, NULL, 19561 "The type definition '%s' was " 19562 "either rejected by the substitution group " 19563 "affiliation '%s', or not validly derived from its type " 19564 "definition '%s'", 19565 xmlSchemaGetComponentQName(&strA, typeDef), 19566 xmlSchemaGetComponentQName(&strB, head), 19567 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19568 FREE_AND_NULL(strA) 19569 FREE_AND_NULL(strB) 19570 FREE_AND_NULL(strC) 19571 } 19572 } 19573 } 19574 /* 19575 * SPEC (5) "If the {type definition} or {type definition}'s 19576 * {content type} 19577 * is or is derived from ID then there must not be a {value constraint}. 19578 * Note: The use of ID as a type definition for elements goes beyond 19579 * XML 1.0, and should be avoided if backwards compatibility is desired" 19580 */ 19581 if ((elemDecl->value != NULL) && 19582 ((WXS_IS_SIMPLE(typeDef) && 19583 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19584 (WXS_IS_COMPLEX(typeDef) && 19585 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19586 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19587 XML_SCHEMAS_ID)))) { 19588 19589 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19590 xmlSchemaPCustomErr(pctxt, 19591 XML_SCHEMAP_E_PROPS_CORRECT_5, 19592 WXS_BASIC_CAST elemDecl, NULL, 19593 "The type definition (or type definition's content type) is or " 19594 "is derived from ID; value constraints are not allowed in " 19595 "conjunction with such a type definition", NULL); 19596 } else if (elemDecl->value != NULL) { 19597 int vcret; 19598 xmlNodePtr node = NULL; 19599 19600 /* 19601 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19602 * representation of its value must be �valid� with respect to the 19603 * {type definition} as defined in Element Default Valid (Immediate) 19604 * (�3.3.6)." 19605 */ 19606 if (typeDef == NULL) { 19607 xmlSchemaPErr(pctxt, elemDecl->node, 19608 XML_SCHEMAP_INTERNAL, 19609 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19610 "type is missing... skipping validation of " 19611 "the value constraint", NULL, NULL); 19612 return (-1); 19613 } 19614 if (elemDecl->node != NULL) { 19615 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19616 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19617 BAD_CAST "fixed"); 19618 else 19619 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19620 BAD_CAST "default"); 19621 } 19622 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19623 typeDef, elemDecl->value, &(elemDecl->defVal)); 19624 if (vcret != 0) { 19625 if (vcret < 0) { 19626 PERROR_INT("xmlSchemaElemCheckValConstr", 19627 "failed to validate the value constraint of an " 19628 "element declaration"); 19629 return (-1); 19630 } 19631 return (vcret); 19632 } 19633 } 19634 19635 return (ret); 19636} 19637 19638/** 19639 * xmlSchemaCheckElemSubstGroup: 19640 * @ctxt: a schema parser context 19641 * @decl: the element declaration 19642 * @name: the name of the attribute 19643 * 19644 * Schema Component Constraint: 19645 * Substitution Group (cos-equiv-class) 19646 * 19647 * In Libxml2 the subst. groups will be precomputed, in terms of that 19648 * a list will be built for each subst. group head, holding all direct 19649 * referents to this head. 19650 * NOTE that this function needs: 19651 * 1. circular subst. groups to be checked beforehand 19652 * 2. the declaration's type to be derived from the head's type 19653 * 19654 * STATUS: 19655 * 19656 */ 19657static void 19658xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19659 xmlSchemaElementPtr elemDecl) 19660{ 19661 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19662 /* SPEC (1) "Its {abstract} is false." */ 19663 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19664 return; 19665 { 19666 xmlSchemaElementPtr head; 19667 xmlSchemaTypePtr headType, type; 19668 int set, methSet; 19669 /* 19670 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19671 * {disallowed substitutions} as the blocking constraint, as defined in 19672 * Substitution Group OK (Transitive) (�3.3.6)." 19673 */ 19674 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19675 head = WXS_SUBST_HEAD(head)) { 19676 set = 0; 19677 methSet = 0; 19678 /* 19679 * The blocking constraints. 19680 */ 19681 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19682 continue; 19683 headType = head->subtypes; 19684 type = elemDecl->subtypes; 19685 if (headType == type) 19686 goto add_member; 19687 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19688 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19689 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19690 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19691 /* 19692 * SPEC: Substitution Group OK (Transitive) (2.3) 19693 * "The set of all {derivation method}s involved in the 19694 * derivation of D's {type definition} from C's {type definition} 19695 * does not intersect with the union of the blocking constraint, 19696 * C's {prohibited substitutions} (if C is complex, otherwise the 19697 * empty set) and the {prohibited substitutions} (respectively the 19698 * empty set) of any intermediate {type definition}s in the 19699 * derivation of D's {type definition} from C's {type definition}." 19700 */ 19701 /* 19702 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19703 * subst.head axis, the methSet does not need to be computed for 19704 * the full depth over and over. 19705 */ 19706 /* 19707 * The set of all {derivation method}s involved in the derivation 19708 */ 19709 while ((type != NULL) && (type != headType)) { 19710 if ((WXS_IS_EXTENSION(type)) && 19711 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19712 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19713 19714 if (WXS_IS_RESTRICTION(type) && 19715 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19716 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19717 19718 type = type->baseType; 19719 } 19720 /* 19721 * The {prohibited substitutions} of all intermediate types + 19722 * the head's type. 19723 */ 19724 type = elemDecl->subtypes->baseType; 19725 while (type != NULL) { 19726 if (WXS_IS_COMPLEX(type)) { 19727 if ((type->flags & 19728 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19729 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19730 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19731 if ((type->flags & 19732 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19733 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19734 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19735 } else 19736 break; 19737 if (type == headType) 19738 break; 19739 type = type->baseType; 19740 } 19741 if ((set != 0) && 19742 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19743 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19744 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19745 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19746 continue; 19747 } 19748add_member: 19749 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19750 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19751 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19752 } 19753 } 19754} 19755 19756#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19757/** 19758 * xmlSchemaCheckElementDeclComponent 19759 * @pctxt: the schema parser context 19760 * @ctxtComponent: the context component (an element declaration) 19761 * @ctxtParticle: the first particle of the context component 19762 * @searchParticle: the element declaration particle to be analysed 19763 * 19764 * Schema Component Constraint: Element Declarations Consistent 19765 */ 19766static int 19767xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19768 xmlSchemaBasicItemPtr ctxtComponent, 19769 xmlSchemaParticlePtr ctxtParticle, 19770 xmlSchemaParticlePtr searchParticle, 19771 xmlSchemaParticlePtr curParticle, 19772 int search) 19773{ 19774 return(0); 19775 19776 int ret = 0; 19777 xmlSchemaParticlePtr cur = curParticle; 19778 if (curParticle == NULL) { 19779 return(0); 19780 } 19781 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19782 /* 19783 * Just return in this case. A missing "term" of the particle 19784 * might arise due to an invalid "term" component. 19785 */ 19786 return(0); 19787 } 19788 while (cur != NULL) { 19789 switch (WXS_PARTICLE_TERM(cur)->type) { 19790 case XML_SCHEMA_TYPE_ANY: 19791 break; 19792 case XML_SCHEMA_TYPE_ELEMENT: 19793 if (search == 0) { 19794 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19795 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19796 if (ret != 0) 19797 return(ret); 19798 } else { 19799 xmlSchemaElementPtr elem = 19800 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19801 /* 19802 * SPEC Element Declarations Consistent: 19803 * "If the {particles} contains, either directly, 19804 * indirectly (that is, within the {particles} of a 19805 * contained model group, recursively) or �implicitly� 19806 * two or more element declaration particles with 19807 * the same {name} and {target namespace}, then 19808 * all their type definitions must be the same 19809 * top-level definition [...]" 19810 */ 19811 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19812 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19813 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19814 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19815 { 19816 xmlChar *strA = NULL, *strB = NULL; 19817 19818 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19819 /* TODO: error code */ 19820 XML_SCHEMAP_COS_NONAMBIG, 19821 WXS_ITEM_NODE(cur), NULL, 19822 "In the content model of %s, there are multiple " 19823 "element declarations for '%s' with different " 19824 "type definitions", 19825 xmlSchemaGetComponentDesignation(&strA, 19826 ctxtComponent), 19827 xmlSchemaFormatQName(&strB, 19828 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19829 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19830 FREE_AND_NULL(strA); 19831 FREE_AND_NULL(strB); 19832 return(XML_SCHEMAP_COS_NONAMBIG); 19833 } 19834 } 19835 break; 19836 case XML_SCHEMA_TYPE_SEQUENCE: { 19837 break; 19838 } 19839 case XML_SCHEMA_TYPE_CHOICE:{ 19840 /* 19841 xmlSchemaTreeItemPtr sub; 19842 19843 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19844 while (sub != NULL) { 19845 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19846 ctxtParticle, ctxtElem); 19847 if (ret != 0) 19848 return(ret); 19849 sub = sub->next; 19850 } 19851 */ 19852 break; 19853 } 19854 case XML_SCHEMA_TYPE_ALL: 19855 break; 19856 case XML_SCHEMA_TYPE_GROUP: 19857 break; 19858 default: 19859 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19860 "xmlSchemaCheckElementDeclConsistent", 19861 "found unexpected term of type '%s' in content model", 19862 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19863 return(-1); 19864 } 19865 cur = (xmlSchemaParticlePtr) cur->next; 19866 } 19867 19868exit: 19869 return(ret); 19870} 19871#endif 19872 19873/** 19874 * xmlSchemaCheckElementDeclComponent 19875 * @item: an schema element declaration/particle 19876 * @ctxt: a schema parser context 19877 * @name: the name of the attribute 19878 * 19879 * Validates the value constraints of an element declaration. 19880 * Adds substitution group members. 19881 */ 19882static void 19883xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 19884 xmlSchemaParserCtxtPtr ctxt) 19885{ 19886 if (elemDecl == NULL) 19887 return; 19888 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 19889 return; 19890 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 19891 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 19892 /* 19893 * Adds substitution group members. 19894 */ 19895 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 19896 } 19897} 19898 19899/** 19900 * xmlSchemaResolveModelGroupParticleReferences: 19901 * @particle: a particle component 19902 * @ctxt: a parser context 19903 * 19904 * Resolves references of a model group's {particles} to 19905 * model group definitions and to element declarations. 19906 */ 19907static void 19908xmlSchemaResolveModelGroupParticleReferences( 19909 xmlSchemaParserCtxtPtr ctxt, 19910 xmlSchemaModelGroupPtr mg) 19911{ 19912 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19913 xmlSchemaQNameRefPtr ref; 19914 xmlSchemaBasicItemPtr refItem; 19915 19916 /* 19917 * URGENT TODO: Test this. 19918 */ 19919 while (particle != NULL) { 19920 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19921 ((WXS_PARTICLE_TERM(particle))->type != 19922 XML_SCHEMA_EXTRA_QNAMEREF)) 19923 { 19924 goto next_particle; 19925 } 19926 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 19927 /* 19928 * Resolve the reference. 19929 * NULL the {term} by default. 19930 */ 19931 particle->children = NULL; 19932 19933 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 19934 ref->itemType, ref->name, ref->targetNamespace); 19935 if (refItem == NULL) { 19936 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 19937 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 19938 ref->targetNamespace, ref->itemType, NULL); 19939 /* TODO: remove the particle. */ 19940 goto next_particle; 19941 } 19942 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 19943 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 19944 /* TODO: remove the particle. */ 19945 goto next_particle; 19946 /* 19947 * NOTE that we will assign the model group definition 19948 * itself to the "term" of the particle. This will ease 19949 * the check for circular model group definitions. After 19950 * that the "term" will be assigned the model group of the 19951 * model group definition. 19952 */ 19953 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 19954 XML_SCHEMA_TYPE_ALL) { 19955 /* 19956 * SPEC cos-all-limited (1) 19957 * SPEC cos-all-limited (1.2) 19958 * "It appears only as the value of one or both of the 19959 * following properties:" 19960 * (1.1) "the {model group} property of a model group 19961 * definition." 19962 * (1.2) "the {term} property of a particle [... of] the " 19963 * {content type} of a complex type definition." 19964 */ 19965 xmlSchemaCustomErr(ACTXT_CAST ctxt, 19966 /* TODO: error code */ 19967 XML_SCHEMAP_COS_ALL_LIMITED, 19968 WXS_ITEM_NODE(particle), NULL, 19969 "A model group definition is referenced, but " 19970 "it contains an 'all' model group, which " 19971 "cannot be contained by model groups", 19972 NULL, NULL); 19973 /* TODO: remove the particle. */ 19974 goto next_particle; 19975 } 19976 particle->children = (xmlSchemaTreeItemPtr) refItem; 19977 } else { 19978 /* 19979 * TODO: Are referenced element declarations the only 19980 * other components we expect here? 19981 */ 19982 particle->children = (xmlSchemaTreeItemPtr) refItem; 19983 } 19984next_particle: 19985 particle = WXS_PTC_CAST particle->next; 19986 } 19987} 19988 19989static int 19990xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 19991 xmlSchemaValPtr y) 19992{ 19993 xmlSchemaTypePtr tx, ty, ptx, pty; 19994 int ret; 19995 19996 while (x != NULL) { 19997 /* Same types. */ 19998 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 19999 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20000 ptx = xmlSchemaGetPrimitiveType(tx); 20001 pty = xmlSchemaGetPrimitiveType(ty); 20002 /* 20003 * (1) if a datatype T' is �derived� by �restriction� from an 20004 * atomic datatype T then the �value space� of T' is a subset of 20005 * the �value space� of T. */ 20006 /* 20007 * (2) if datatypes T' and T'' are �derived� by �restriction� 20008 * from a common atomic ancestor T then the �value space�s of T' 20009 * and T'' may overlap. 20010 */ 20011 if (ptx != pty) 20012 return(0); 20013 /* 20014 * We assume computed values to be normalized, so do a fast 20015 * string comparison for string based types. 20016 */ 20017 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20018 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20019 if (! xmlStrEqual( 20020 xmlSchemaValueGetAsString(x), 20021 xmlSchemaValueGetAsString(y))) 20022 return (0); 20023 } else { 20024 ret = xmlSchemaCompareValuesWhtsp( 20025 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20026 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20027 if (ret == -2) 20028 return(-1); 20029 if (ret != 0) 20030 return(0); 20031 } 20032 /* 20033 * Lists. 20034 */ 20035 x = xmlSchemaValueGetNext(x); 20036 if (x != NULL) { 20037 y = xmlSchemaValueGetNext(y); 20038 if (y == NULL) 20039 return (0); 20040 } else if (xmlSchemaValueGetNext(y) != NULL) 20041 return (0); 20042 else 20043 return (1); 20044 } 20045 return (0); 20046} 20047 20048/** 20049 * xmlSchemaResolveAttrUseReferences: 20050 * @item: an attribute use 20051 * @ctxt: a parser context 20052 * 20053 * Resolves the referenced attribute declaration. 20054 */ 20055static int 20056xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20057 xmlSchemaParserCtxtPtr ctxt) 20058{ 20059 if ((ctxt == NULL) || (ause == NULL)) 20060 return(-1); 20061 if ((ause->attrDecl == NULL) || 20062 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20063 return(0); 20064 20065 { 20066 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20067 20068 /* 20069 * TODO: Evaluate, what errors could occur if the declaration is not 20070 * found. 20071 */ 20072 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20073 ref->name, ref->targetNamespace); 20074 if (ause->attrDecl == NULL) { 20075 xmlSchemaPResCompAttrErr(ctxt, 20076 XML_SCHEMAP_SRC_RESOLVE, 20077 WXS_BASIC_CAST ause, ause->node, 20078 "ref", ref->name, ref->targetNamespace, 20079 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20080 return(ctxt->err);; 20081 } 20082 } 20083 return(0); 20084} 20085 20086/** 20087 * xmlSchemaCheckAttrUsePropsCorrect: 20088 * @ctxt: a parser context 20089 * @use: an attribute use 20090 * 20091 * Schema Component Constraint: 20092 * Attribute Use Correct (au-props-correct) 20093 * 20094 */ 20095static int 20096xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20097 xmlSchemaAttributeUsePtr use) 20098{ 20099 if ((ctxt == NULL) || (use == NULL)) 20100 return(-1); 20101 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20102 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20103 return(0); 20104 20105 /* 20106 * SPEC au-props-correct (1) 20107 * "The values of the properties of an attribute use must be as 20108 * described in the property tableau in The Attribute Use Schema 20109 * Component (�3.5.1), modulo the impact of Missing 20110 * Sub-components (�5.3)." 20111 */ 20112 20113 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20114 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20115 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20116 { 20117 xmlSchemaPCustomErr(ctxt, 20118 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20119 WXS_BASIC_CAST use, NULL, 20120 "The attribute declaration has a 'fixed' value constraint " 20121 ", thus the attribute use must also have a 'fixed' value " 20122 "constraint", 20123 NULL); 20124 return(ctxt->err); 20125 } 20126 /* 20127 * Compute and check the value constraint's value. 20128 */ 20129 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20130 int ret; 20131 /* 20132 * TODO: The spec seems to be missing a check of the 20133 * value constraint of the attribute use. We will do it here. 20134 */ 20135 /* 20136 * SPEC a-props-correct (3) 20137 */ 20138 if (xmlSchemaIsDerivedFromBuiltInType( 20139 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20140 { 20141 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20142 XML_SCHEMAP_AU_PROPS_CORRECT, 20143 NULL, WXS_BASIC_CAST use, 20144 "Value constraints are not allowed if the type definition " 20145 "is or is derived from xs:ID", 20146 NULL, NULL); 20147 return(ctxt->err); 20148 } 20149 20150 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20151 use->node, WXS_ATTRUSE_TYPEDEF(use), 20152 use->defValue, &(use->defVal), 20153 1, 1, 0); 20154 if (ret != 0) { 20155 if (ret < 0) { 20156 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20157 "calling xmlSchemaVCheckCVCSimpleType()"); 20158 return(-1); 20159 } 20160 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20161 XML_SCHEMAP_AU_PROPS_CORRECT, 20162 NULL, WXS_BASIC_CAST use, 20163 "The value of the value constraint is not valid", 20164 NULL, NULL); 20165 return(ctxt->err); 20166 } 20167 } 20168 /* 20169 * SPEC au-props-correct (2) 20170 * "If the {attribute declaration} has a fixed 20171 * {value constraint}, then if the attribute use itself has a 20172 * {value constraint}, it must also be fixed and its value must match 20173 * that of the {attribute declaration}'s {value constraint}." 20174 */ 20175 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20176 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20177 { 20178 if (! xmlSchemaAreValuesEqual(use->defVal, 20179 (WXS_ATTRUSE_DECL(use))->defVal)) 20180 { 20181 xmlSchemaPCustomErr(ctxt, 20182 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20183 WXS_BASIC_CAST use, NULL, 20184 "The 'fixed' value constraint of the attribute use " 20185 "must match the attribute declaration's value " 20186 "constraint '%s'", 20187 (WXS_ATTRUSE_DECL(use))->defValue); 20188 } 20189 return(ctxt->err); 20190 } 20191 return(0); 20192} 20193 20194 20195 20196 20197/** 20198 * xmlSchemaResolveAttrTypeReferences: 20199 * @item: an attribute declaration 20200 * @ctxt: a parser context 20201 * 20202 * Resolves the referenced type definition component. 20203 */ 20204static int 20205xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20206 xmlSchemaParserCtxtPtr ctxt) 20207{ 20208 /* 20209 * The simple type definition corresponding to the <simpleType> element 20210 * information item in the [children], if present, otherwise the simple 20211 * type definition �resolved� to by the �actual value� of the type 20212 * [attribute], if present, otherwise the �simple ur-type definition�. 20213 */ 20214 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20215 return(0); 20216 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20217 if (item->subtypes != NULL) 20218 return(0); 20219 if (item->typeName != NULL) { 20220 xmlSchemaTypePtr type; 20221 20222 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20223 item->typeNs); 20224 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20225 xmlSchemaPResCompAttrErr(ctxt, 20226 XML_SCHEMAP_SRC_RESOLVE, 20227 WXS_BASIC_CAST item, item->node, 20228 "type", item->typeName, item->typeNs, 20229 XML_SCHEMA_TYPE_SIMPLE, NULL); 20230 return(ctxt->err); 20231 } else 20232 item->subtypes = type; 20233 20234 } else { 20235 /* 20236 * The type defaults to the xs:anySimpleType. 20237 */ 20238 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20239 } 20240 return(0); 20241} 20242 20243/** 20244 * xmlSchemaResolveIDCKeyReferences: 20245 * @idc: the identity-constraint definition 20246 * @ctxt: the schema parser context 20247 * @name: the attribute name 20248 * 20249 * Resolve keyRef references to key/unique IDCs. 20250 * Schema Component Constraint: 20251 * Identity-constraint Definition Properties Correct (c-props-correct) 20252 */ 20253static int 20254xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20255 xmlSchemaParserCtxtPtr pctxt) 20256{ 20257 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20258 return(0); 20259 if (idc->ref->name != NULL) { 20260 idc->ref->item = (xmlSchemaBasicItemPtr) 20261 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20262 idc->ref->targetNamespace); 20263 if (idc->ref->item == NULL) { 20264 /* 20265 * TODO: It is actually not an error to fail to resolve 20266 * at this stage. BUT we need to be that strict! 20267 */ 20268 xmlSchemaPResCompAttrErr(pctxt, 20269 XML_SCHEMAP_SRC_RESOLVE, 20270 WXS_BASIC_CAST idc, idc->node, 20271 "refer", idc->ref->name, 20272 idc->ref->targetNamespace, 20273 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20274 return(pctxt->err); 20275 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20276 /* 20277 * SPEC c-props-correct (1) 20278 */ 20279 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20280 XML_SCHEMAP_C_PROPS_CORRECT, 20281 NULL, WXS_BASIC_CAST idc, 20282 "The keyref references a keyref", 20283 NULL, NULL); 20284 idc->ref->item = NULL; 20285 return(pctxt->err); 20286 } else { 20287 if (idc->nbFields != 20288 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20289 xmlChar *str = NULL; 20290 xmlSchemaIDCPtr refer; 20291 20292 refer = (xmlSchemaIDCPtr) idc->ref->item; 20293 /* 20294 * SPEC c-props-correct(2) 20295 * "If the {identity-constraint category} is keyref, 20296 * the cardinality of the {fields} must equal that of 20297 * the {fields} of the {referenced key}. 20298 */ 20299 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20300 XML_SCHEMAP_C_PROPS_CORRECT, 20301 NULL, WXS_BASIC_CAST idc, 20302 "The cardinality of the keyref differs from the " 20303 "cardinality of the referenced key/unique '%s'", 20304 xmlSchemaFormatQName(&str, refer->targetNamespace, 20305 refer->name), 20306 NULL); 20307 FREE_AND_NULL(str) 20308 return(pctxt->err); 20309 } 20310 } 20311 } 20312 return(0); 20313} 20314 20315static int 20316xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20317 xmlSchemaParserCtxtPtr pctxt) 20318{ 20319 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20320 prohib->targetNamespace) == NULL) { 20321 20322 xmlSchemaPResCompAttrErr(pctxt, 20323 XML_SCHEMAP_SRC_RESOLVE, 20324 NULL, prohib->node, 20325 "ref", prohib->name, prohib->targetNamespace, 20326 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20327 return(XML_SCHEMAP_SRC_RESOLVE); 20328 } 20329 return(0); 20330} 20331 20332#define WXS_REDEFINED_TYPE(c) \ 20333(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20334 20335#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20336(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20337 20338#define WXS_REDEFINED_ATTR_GROUP(c) \ 20339(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20340 20341static int 20342xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20343{ 20344 int err = 0; 20345 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20346 xmlSchemaBasicItemPtr prev, item; 20347 int wasRedefined; 20348 20349 if (redef == NULL) 20350 return(0); 20351 20352 do { 20353 item = redef->item; 20354 /* 20355 * First try to locate the redefined component in the 20356 * schema graph starting with the redefined schema. 20357 * NOTE: According to this schema bug entry: 20358 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20359 * it's not clear if the referenced component needs to originate 20360 * from the <redefine>d schema _document_ or the schema; the latter 20361 * would include all imported and included sub-schemas of the 20362 * <redefine>d schema. Currenlty we latter approach is used. 20363 * SUPPLEMENT: It seems that the WG moves towards the latter 20364 * approach, so we are doing it right. 20365 * 20366 */ 20367 prev = xmlSchemaFindRedefCompInGraph( 20368 redef->targetBucket, item->type, 20369 redef->refName, redef->refTargetNs); 20370 if (prev == NULL) { 20371 xmlChar *str = NULL; 20372 xmlNodePtr node; 20373 20374 /* 20375 * SPEC src-redefine: 20376 * (6.2.1) "The �actual value� of its own name attribute plus 20377 * target namespace must successfully �resolve� to a model 20378 * group definition in I." 20379 * (7.2.1) "The �actual value� of its own name attribute plus 20380 * target namespace must successfully �resolve� to an attribute 20381 * group definition in I." 20382 20383 * 20384 * Note that, if we are redefining with the use of references 20385 * to components, the spec assumes the src-resolve to be used; 20386 * but this won't assure that we search only *inside* the 20387 * redefined schema. 20388 */ 20389 if (redef->reference) 20390 node = WXS_ITEM_NODE(redef->reference); 20391 else 20392 node = WXS_ITEM_NODE(item); 20393 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20394 /* 20395 * TODO: error code. 20396 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20397 * reference kind. 20398 */ 20399 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20400 "The %s '%s' to be redefined could not be found in " 20401 "the redefined schema", 20402 WXS_ITEM_TYPE_NAME(item), 20403 xmlSchemaFormatQName(&str, redef->refTargetNs, 20404 redef->refName)); 20405 FREE_AND_NULL(str); 20406 err = pctxt->err; 20407 redef = redef->next; 20408 continue; 20409 } 20410 /* 20411 * TODO: Obtaining and setting the redefinition state is really 20412 * clumsy. 20413 */ 20414 wasRedefined = 0; 20415 switch (item->type) { 20416 case XML_SCHEMA_TYPE_COMPLEX: 20417 case XML_SCHEMA_TYPE_SIMPLE: 20418 if ((WXS_TYPE_CAST prev)->flags & 20419 XML_SCHEMAS_TYPE_REDEFINED) 20420 { 20421 wasRedefined = 1; 20422 break; 20423 } 20424 /* Mark it as redefined. */ 20425 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20426 /* 20427 * Assign the redefined type to the 20428 * base type of the redefining type. 20429 * TODO: How 20430 */ 20431 ((xmlSchemaTypePtr) item)->baseType = 20432 (xmlSchemaTypePtr) prev; 20433 break; 20434 case XML_SCHEMA_TYPE_GROUP: 20435 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20436 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20437 { 20438 wasRedefined = 1; 20439 break; 20440 } 20441 /* Mark it as redefined. */ 20442 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20443 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20444 if (redef->reference != NULL) { 20445 /* 20446 * Overwrite the QName-reference with the 20447 * referenced model group def. 20448 */ 20449 (WXS_PTC_CAST redef->reference)->children = 20450 WXS_TREE_CAST prev; 20451 } 20452 redef->target = prev; 20453 break; 20454 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20455 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20456 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20457 { 20458 wasRedefined = 1; 20459 break; 20460 } 20461 (WXS_ATTR_GROUP_CAST prev)->flags |= 20462 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20463 if (redef->reference != NULL) { 20464 /* 20465 * Assign the redefined attribute group to the 20466 * QName-reference component. 20467 * This is the easy case, since we will just 20468 * expand the redefined group. 20469 */ 20470 (WXS_QNAME_CAST redef->reference)->item = prev; 20471 redef->target = NULL; 20472 } else { 20473 /* 20474 * This is the complicated case: we need 20475 * to apply src-redefine (7.2.2) at a later 20476 * stage, i.e. when attribute group references 20477 * have beed expanded and simple types have 20478 * beed fixed. 20479 */ 20480 redef->target = prev; 20481 } 20482 break; 20483 default: 20484 PERROR_INT("xmlSchemaResolveRedefReferences", 20485 "Unexpected redefined component type"); 20486 return(-1); 20487 } 20488 if (wasRedefined) { 20489 xmlChar *str = NULL; 20490 xmlNodePtr node; 20491 20492 if (redef->reference) 20493 node = WXS_ITEM_NODE(redef->reference); 20494 else 20495 node = WXS_ITEM_NODE(redef->item); 20496 20497 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20498 /* TODO: error code. */ 20499 XML_SCHEMAP_SRC_REDEFINE, 20500 node, NULL, 20501 "The referenced %s was already redefined. Multiple " 20502 "redefinition of the same component is not supported", 20503 xmlSchemaGetComponentDesignation(&str, prev), 20504 NULL); 20505 FREE_AND_NULL(str) 20506 err = pctxt->err; 20507 redef = redef->next; 20508 continue; 20509 } 20510 redef = redef->next; 20511 } while (redef != NULL); 20512 20513 return(err); 20514} 20515 20516static int 20517xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20518{ 20519 int err = 0; 20520 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20521 xmlSchemaBasicItemPtr item; 20522 20523 if (redef == NULL) 20524 return(0); 20525 20526 do { 20527 if (redef->target == NULL) { 20528 redef = redef->next; 20529 continue; 20530 } 20531 item = redef->item; 20532 20533 switch (item->type) { 20534 case XML_SCHEMA_TYPE_SIMPLE: 20535 case XML_SCHEMA_TYPE_COMPLEX: 20536 /* 20537 * Since the spec wants the {name} of the redefined 20538 * type to be 'absent', we'll NULL it. 20539 */ 20540 (WXS_TYPE_CAST redef->target)->name = NULL; 20541 20542 /* 20543 * TODO: Seems like there's nothing more to do. The normal 20544 * inheritance mechanism is used. But not 100% sure. 20545 */ 20546 break; 20547 case XML_SCHEMA_TYPE_GROUP: 20548 /* 20549 * URGENT TODO: 20550 * SPEC src-redefine: 20551 * (6.2.2) "The {model group} of the model group definition 20552 * which corresponds to it per XML Representation of Model 20553 * Group Definition Schema Components (�3.7.2) must be a 20554 * �valid restriction� of the {model group} of that model 20555 * group definition in I, as defined in Particle Valid 20556 * (Restriction) (�3.9.6)." 20557 */ 20558 break; 20559 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20560 /* 20561 * SPEC src-redefine: 20562 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20563 * the attribute group definition which corresponds to it 20564 * per XML Representation of Attribute Group Definition Schema 20565 * Components (�3.6.2) must be �valid restrictions� of the 20566 * {attribute uses} and {attribute wildcard} of that attribute 20567 * group definition in I, as defined in clause 2, clause 3 and 20568 * clause 4 of Derivation Valid (Restriction, Complex) 20569 * (�3.4.6) (where references to the base type definition are 20570 * understood as references to the attribute group definition 20571 * in I)." 20572 */ 20573 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20574 XML_SCHEMA_ACTION_REDEFINE, 20575 item, redef->target, 20576 (WXS_ATTR_GROUP_CAST item)->attrUses, 20577 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20578 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20579 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20580 if (err == -1) 20581 return(-1); 20582 break; 20583 default: 20584 break; 20585 } 20586 redef = redef->next; 20587 } while (redef != NULL); 20588 return(0); 20589} 20590 20591 20592static int 20593xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20594 xmlSchemaBucketPtr bucket) 20595{ 20596 xmlSchemaBasicItemPtr item; 20597 int err; 20598 xmlHashTablePtr *table; 20599 const xmlChar *name; 20600 int i; 20601 20602#define WXS_GET_GLOBAL_HASH(c, slot) { \ 20603 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20604 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20605 else \ 20606 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20607 20608 /* 20609 * Add global components to the schema's hash tables. 20610 * This is the place where duplicate components will be 20611 * detected. 20612 * TODO: I think normally we should support imports of the 20613 * same namespace from multiple locations. We don't do currently, 20614 * but if we do then according to: 20615 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20616 * we would need, if imported directly, to import redefined 20617 * components as well to be able to catch clashing components. 20618 * (I hope I'll still know what this means after some months :-() 20619 */ 20620 if (bucket == NULL) 20621 return(-1); 20622 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20623 return(0); 20624 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20625 20626 for (i = 0; i < bucket->globals->nbItems; i++) { 20627 item = bucket->globals->items[i]; 20628 table = NULL; 20629 switch (item->type) { 20630 case XML_SCHEMA_TYPE_COMPLEX: 20631 case XML_SCHEMA_TYPE_SIMPLE: 20632 if (WXS_REDEFINED_TYPE(item)) 20633 continue; 20634 name = (WXS_TYPE_CAST item)->name; 20635 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20636 break; 20637 case XML_SCHEMA_TYPE_ELEMENT: 20638 name = (WXS_ELEM_CAST item)->name; 20639 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20640 break; 20641 case XML_SCHEMA_TYPE_ATTRIBUTE: 20642 name = (WXS_ATTR_CAST item)->name; 20643 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20644 break; 20645 case XML_SCHEMA_TYPE_GROUP: 20646 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20647 continue; 20648 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20649 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20650 break; 20651 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20652 if (WXS_REDEFINED_ATTR_GROUP(item)) 20653 continue; 20654 name = (WXS_ATTR_GROUP_CAST item)->name; 20655 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20656 break; 20657 case XML_SCHEMA_TYPE_IDC_KEY: 20658 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20659 case XML_SCHEMA_TYPE_IDC_KEYREF: 20660 name = (WXS_IDC_CAST item)->name; 20661 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20662 break; 20663 case XML_SCHEMA_TYPE_NOTATION: 20664 name = ((xmlSchemaNotationPtr) item)->name; 20665 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20666 break; 20667 default: 20668 PERROR_INT("xmlSchemaAddComponents", 20669 "Unexpected global component type"); 20670 continue; 20671 } 20672 if (*table == NULL) { 20673 *table = xmlHashCreateDict(10, pctxt->dict); 20674 if (*table == NULL) { 20675 PERROR_INT("xmlSchemaAddComponents", 20676 "failed to create a component hash table"); 20677 return(-1); 20678 } 20679 } 20680 err = xmlHashAddEntry(*table, name, item); 20681 if (err != 0) { 20682 xmlChar *str = NULL; 20683 20684 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20685 XML_SCHEMAP_REDEFINED_TYPE, 20686 WXS_ITEM_NODE(item), 20687 WXS_BASIC_CAST item, 20688 "A global %s '%s' does already exist", 20689 WXS_ITEM_TYPE_NAME(item), 20690 xmlSchemaGetComponentQName(&str, item)); 20691 FREE_AND_NULL(str); 20692 } 20693 } 20694 /* 20695 * Process imported/included schemas. 20696 */ 20697 if (bucket->relations != NULL) { 20698 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20699 do { 20700 if ((rel->bucket != NULL) && 20701 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20702 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20703 return(-1); 20704 } 20705 rel = rel->next; 20706 } while (rel != NULL); 20707 } 20708 return(0); 20709} 20710 20711static int 20712xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20713 xmlSchemaBucketPtr rootBucket) 20714{ 20715 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20716 xmlSchemaTreeItemPtr item, *items; 20717 int nbItems, i, ret = 0; 20718 xmlSchemaBucketPtr oldbucket = con->bucket; 20719 xmlSchemaElementPtr elemDecl; 20720 20721#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20722 20723 if ((con->pending == NULL) || 20724 (con->pending->nbItems == 0)) 20725 return(0); 20726 20727 /* 20728 * Since xmlSchemaFixupComplexType() will create new particles 20729 * (local components), and those particle components need a bucket 20730 * on the constructor, we'll assure here that the constructor has 20731 * a bucket. 20732 * TODO: Think about storing locals _only_ on the main bucket. 20733 */ 20734 if (con->bucket == NULL) 20735 con->bucket = rootBucket; 20736 20737 /* TODO: 20738 * SPEC (src-redefine): 20739 * (6.2) "If it has no such self-reference, then all of the 20740 * following must be true:" 20741 20742 * (6.2.2) The {model group} of the model group definition which 20743 * corresponds to it per XML Representation of Model Group 20744 * Definition Schema Components (�3.7.2) must be a �valid 20745 * restriction� of the {model group} of that model group definition 20746 * in I, as defined in Particle Valid (Restriction) (�3.9.6)." 20747 */ 20748 xmlSchemaCheckSRCRedefineFirst(pctxt); 20749 20750 /* 20751 * Add global components to the schemata's hash tables. 20752 */ 20753 xmlSchemaAddComponents(pctxt, rootBucket); 20754 20755 pctxt->ctxtType = NULL; 20756 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20757 nbItems = con->pending->nbItems; 20758 /* 20759 * Now that we have parsed *all* the schema document(s) and converted 20760 * them to schema components, we can resolve references, apply component 20761 * constraints, create the FSA from the content model, etc. 20762 */ 20763 /* 20764 * Resolve references of.. 20765 * 20766 * 1. element declarations: 20767 * - the type definition 20768 * - the substitution group affiliation 20769 * 2. simple/complex types: 20770 * - the base type definition 20771 * - the memberTypes of union types 20772 * - the itemType of list types 20773 * 3. attributes declarations and attribute uses: 20774 * - the type definition 20775 * - if an attribute use, then the attribute declaration 20776 * 4. attribute group references: 20777 * - the attribute group definition 20778 * 5. particles: 20779 * - the term of the particle (e.g. a model group) 20780 * 6. IDC key-references: 20781 * - the referenced IDC 'key' or 'unique' definition 20782 * 7. Attribute prohibitions which had a "ref" attribute. 20783 */ 20784 for (i = 0; i < nbItems; i++) { 20785 item = items[i]; 20786 switch (item->type) { 20787 case XML_SCHEMA_TYPE_ELEMENT: 20788 xmlSchemaResolveElementReferences( 20789 (xmlSchemaElementPtr) item, pctxt); 20790 FIXHFAILURE; 20791 break; 20792 case XML_SCHEMA_TYPE_COMPLEX: 20793 case XML_SCHEMA_TYPE_SIMPLE: 20794 xmlSchemaResolveTypeReferences( 20795 (xmlSchemaTypePtr) item, pctxt); 20796 FIXHFAILURE; 20797 break; 20798 case XML_SCHEMA_TYPE_ATTRIBUTE: 20799 xmlSchemaResolveAttrTypeReferences( 20800 (xmlSchemaAttributePtr) item, pctxt); 20801 FIXHFAILURE; 20802 break; 20803 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20804 xmlSchemaResolveAttrUseReferences( 20805 (xmlSchemaAttributeUsePtr) item, pctxt); 20806 FIXHFAILURE; 20807 break; 20808 case XML_SCHEMA_EXTRA_QNAMEREF: 20809 if ((WXS_QNAME_CAST item)->itemType == 20810 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20811 { 20812 xmlSchemaResolveAttrGroupReferences( 20813 WXS_QNAME_CAST item, pctxt); 20814 } 20815 FIXHFAILURE; 20816 break; 20817 case XML_SCHEMA_TYPE_SEQUENCE: 20818 case XML_SCHEMA_TYPE_CHOICE: 20819 case XML_SCHEMA_TYPE_ALL: 20820 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20821 WXS_MODEL_GROUP_CAST item); 20822 FIXHFAILURE; 20823 break; 20824 case XML_SCHEMA_TYPE_IDC_KEY: 20825 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20826 case XML_SCHEMA_TYPE_IDC_KEYREF: 20827 xmlSchemaResolveIDCKeyReferences( 20828 (xmlSchemaIDCPtr) item, pctxt); 20829 FIXHFAILURE; 20830 break; 20831 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20832 /* 20833 * Handle attribue prohibition which had a 20834 * "ref" attribute. 20835 */ 20836 xmlSchemaResolveAttrUseProhibReferences( 20837 WXS_ATTR_PROHIB_CAST item, pctxt); 20838 FIXHFAILURE; 20839 break; 20840 default: 20841 break; 20842 } 20843 } 20844 if (pctxt->nberrors != 0) 20845 goto exit_error; 20846 20847 /* 20848 * Now that all references are resolved we 20849 * can check for circularity of... 20850 * 1. the base axis of type definitions 20851 * 2. nested model group definitions 20852 * 3. nested attribute group definitions 20853 * TODO: check for circual substitution groups. 20854 */ 20855 for (i = 0; i < nbItems; i++) { 20856 item = items[i]; 20857 /* 20858 * Let's better stop on the first error here. 20859 */ 20860 switch (item->type) { 20861 case XML_SCHEMA_TYPE_COMPLEX: 20862 case XML_SCHEMA_TYPE_SIMPLE: 20863 xmlSchemaCheckTypeDefCircular( 20864 (xmlSchemaTypePtr) item, pctxt); 20865 FIXHFAILURE; 20866 if (pctxt->nberrors != 0) 20867 goto exit_error; 20868 break; 20869 case XML_SCHEMA_TYPE_GROUP: 20870 xmlSchemaCheckGroupDefCircular( 20871 (xmlSchemaModelGroupDefPtr) item, pctxt); 20872 FIXHFAILURE; 20873 if (pctxt->nberrors != 0) 20874 goto exit_error; 20875 break; 20876 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20877 xmlSchemaCheckAttrGroupCircular( 20878 (xmlSchemaAttributeGroupPtr) item, pctxt); 20879 FIXHFAILURE; 20880 if (pctxt->nberrors != 0) 20881 goto exit_error; 20882 break; 20883 default: 20884 break; 20885 } 20886 } 20887 if (pctxt->nberrors != 0) 20888 goto exit_error; 20889 /* 20890 * Model group definition references: 20891 * Such a reference is reflected by a particle at the component 20892 * level. Until now the 'term' of such particles pointed 20893 * to the model group definition; this was done, in order to 20894 * ease circularity checks. Now we need to set the 'term' of 20895 * such particles to the model group of the model group definition. 20896 */ 20897 for (i = 0; i < nbItems; i++) { 20898 item = items[i]; 20899 switch (item->type) { 20900 case XML_SCHEMA_TYPE_SEQUENCE: 20901 case XML_SCHEMA_TYPE_CHOICE: 20902 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 20903 WXS_MODEL_GROUP_CAST item); 20904 break; 20905 default: 20906 break; 20907 } 20908 } 20909 if (pctxt->nberrors != 0) 20910 goto exit_error; 20911 /* 20912 * Expand attribute group references of attribute group definitions. 20913 */ 20914 for (i = 0; i < nbItems; i++) { 20915 item = items[i]; 20916 switch (item->type) { 20917 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20918 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 20919 WXS_ATTR_GROUP_HAS_REFS(item)) 20920 { 20921 xmlSchemaAttributeGroupExpandRefs(pctxt, 20922 WXS_ATTR_GROUP_CAST item); 20923 FIXHFAILURE; 20924 } 20925 break; 20926 default: 20927 break; 20928 } 20929 } 20930 if (pctxt->nberrors != 0) 20931 goto exit_error; 20932 /* 20933 * First compute the variety of simple types. This is needed as 20934 * a seperate step, since otherwise we won't be able to detect 20935 * circular union types in all cases. 20936 */ 20937 for (i = 0; i < nbItems; i++) { 20938 item = items[i]; 20939 switch (item->type) { 20940 case XML_SCHEMA_TYPE_SIMPLE: 20941 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 20942 xmlSchemaFixupSimpleTypeStageOne(pctxt, 20943 (xmlSchemaTypePtr) item); 20944 FIXHFAILURE; 20945 } 20946 break; 20947 default: 20948 break; 20949 } 20950 } 20951 if (pctxt->nberrors != 0) 20952 goto exit_error; 20953 /* 20954 * Detect circular union types. Note that this needs the variety to 20955 * be already computed. 20956 */ 20957 for (i = 0; i < nbItems; i++) { 20958 item = items[i]; 20959 switch (item->type) { 20960 case XML_SCHEMA_TYPE_SIMPLE: 20961 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 20962 xmlSchemaCheckUnionTypeDefCircular(pctxt, 20963 (xmlSchemaTypePtr) item); 20964 FIXHFAILURE; 20965 } 20966 break; 20967 default: 20968 break; 20969 } 20970 } 20971 if (pctxt->nberrors != 0) 20972 goto exit_error; 20973 20974 /* 20975 * Do the complete type fixup for simple types. 20976 */ 20977 for (i = 0; i < nbItems; i++) { 20978 item = items[i]; 20979 switch (item->type) { 20980 case XML_SCHEMA_TYPE_SIMPLE: 20981 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 20982 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 20983 FIXHFAILURE; 20984 } 20985 break; 20986 default: 20987 break; 20988 } 20989 } 20990 if (pctxt->nberrors != 0) 20991 goto exit_error; 20992 /* 20993 * At this point we need build and check all simple types. 20994 */ 20995 /* 20996 * Apply contraints for attribute declarations. 20997 */ 20998 for (i = 0; i < nbItems; i++) { 20999 item = items[i]; 21000 switch (item->type) { 21001 case XML_SCHEMA_TYPE_ATTRIBUTE: 21002 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21003 FIXHFAILURE; 21004 break; 21005 default: 21006 break; 21007 } 21008 } 21009 if (pctxt->nberrors != 0) 21010 goto exit_error; 21011 /* 21012 * Apply constraints for attribute uses. 21013 */ 21014 for (i = 0; i < nbItems; i++) { 21015 item = items[i]; 21016 switch (item->type) { 21017 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21018 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21019 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21020 WXS_ATTR_USE_CAST item); 21021 FIXHFAILURE; 21022 } 21023 break; 21024 default: 21025 break; 21026 } 21027 } 21028 if (pctxt->nberrors != 0) 21029 goto exit_error; 21030 21031 /* 21032 * Apply constraints for attribute group definitions. 21033 */ 21034 for (i = 0; i < nbItems; i++) { 21035 item = items[i]; 21036 switch (item->type) { 21037 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21038 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21039 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21040 { 21041 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21042 FIXHFAILURE; 21043 } 21044 break; 21045 default: 21046 break; 21047 } 21048 } 21049 if (pctxt->nberrors != 0) 21050 goto exit_error; 21051 21052 /* 21053 * Apply constraints for redefinitions. 21054 */ 21055 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21056 xmlSchemaCheckSRCRedefineSecond(pctxt); 21057 if (pctxt->nberrors != 0) 21058 goto exit_error; 21059 21060 /* 21061 * Complex types are builded and checked. 21062 */ 21063 for (i = 0; i < nbItems; i++) { 21064 item = con->pending->items[i]; 21065 switch (item->type) { 21066 case XML_SCHEMA_TYPE_COMPLEX: 21067 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21068 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21069 FIXHFAILURE; 21070 } 21071 break; 21072 default: 21073 break; 21074 } 21075 } 21076 if (pctxt->nberrors != 0) 21077 goto exit_error; 21078 21079 /* 21080 * The list could have changed, since xmlSchemaFixupComplexType() 21081 * will create particles and model groups in some cases. 21082 */ 21083 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21084 nbItems = con->pending->nbItems; 21085 21086 /* 21087 * Apply some constraints for element declarations. 21088 */ 21089 for (i = 0; i < nbItems; i++) { 21090 item = items[i]; 21091 switch (item->type) { 21092 case XML_SCHEMA_TYPE_ELEMENT: 21093 elemDecl = (xmlSchemaElementPtr) item; 21094 21095 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21096 { 21097 xmlSchemaCheckElementDeclComponent( 21098 (xmlSchemaElementPtr) elemDecl, pctxt); 21099 FIXHFAILURE; 21100 } 21101 21102#ifdef WXS_ELEM_DECL_CONS_ENABLED 21103 /* 21104 * Schema Component Constraint: Element Declarations Consistent 21105 * Apply this constraint to local types of element declarations. 21106 */ 21107 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21108 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21109 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21110 { 21111 xmlSchemaCheckElementDeclConsistent(pctxt, 21112 WXS_BASIC_CAST elemDecl, 21113 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21114 NULL, NULL, 0); 21115 } 21116#endif 21117 break; 21118 default: 21119 break; 21120 } 21121 } 21122 if (pctxt->nberrors != 0) 21123 goto exit_error; 21124 21125 /* 21126 * Finally we can build the automaton from the content model of 21127 * complex types. 21128 */ 21129 21130 for (i = 0; i < nbItems; i++) { 21131 item = items[i]; 21132 switch (item->type) { 21133 case XML_SCHEMA_TYPE_COMPLEX: 21134 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21135 /* FIXHFAILURE; */ 21136 break; 21137 default: 21138 break; 21139 } 21140 } 21141 if (pctxt->nberrors != 0) 21142 goto exit_error; 21143 /* 21144 * URGENT TODO: cos-element-consistent 21145 */ 21146 goto exit; 21147 21148exit_error: 21149 ret = pctxt->err; 21150 goto exit; 21151 21152exit_failure: 21153 ret = -1; 21154 21155exit: 21156 /* 21157 * Reset the constructor. This is needed for XSI acquisition, since 21158 * those items will be processed over and over again for every XSI 21159 * if not cleared here. 21160 */ 21161 con->bucket = oldbucket; 21162 con->pending->nbItems = 0; 21163 if (con->substGroups != NULL) { 21164 xmlHashFree(con->substGroups, 21165 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 21166 con->substGroups = NULL; 21167 } 21168 if (con->redefs != NULL) { 21169 xmlSchemaRedefListFree(con->redefs); 21170 con->redefs = NULL; 21171 } 21172 return(ret); 21173} 21174/** 21175 * xmlSchemaParse: 21176 * @ctxt: a schema validation context 21177 * 21178 * parse a schema definition resource and build an internal 21179 * XML Shema struture which can be used to validate instances. 21180 * 21181 * Returns the internal XML Schema structure built from the resource or 21182 * NULL in case of error 21183 */ 21184xmlSchemaPtr 21185xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21186{ 21187 xmlSchemaPtr mainSchema = NULL; 21188 xmlSchemaBucketPtr bucket = NULL; 21189 int res; 21190 21191 /* 21192 * This one is used if the schema to be parsed was specified via 21193 * the API; i.e. not automatically by the validated instance document. 21194 */ 21195 21196 xmlSchemaInitTypes(); 21197 21198 if (ctxt == NULL) 21199 return (NULL); 21200 21201 /* TODO: Init the context. Is this all we need?*/ 21202 ctxt->nberrors = 0; 21203 ctxt->err = 0; 21204 ctxt->counter = 0; 21205 21206 /* Create the *main* schema. */ 21207 mainSchema = xmlSchemaNewSchema(ctxt); 21208 if (mainSchema == NULL) 21209 goto exit_failure; 21210 /* 21211 * Create the schema constructor. 21212 */ 21213 if (ctxt->constructor == NULL) { 21214 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21215 if (ctxt->constructor == NULL) 21216 return(NULL); 21217 /* Take ownership of the constructor to be able to free it. */ 21218 ctxt->ownsConstructor = 1; 21219 } 21220 ctxt->constructor->mainSchema = mainSchema; 21221 /* 21222 * Locate and add the schema document. 21223 */ 21224 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21225 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21226 NULL, NULL, &bucket); 21227 if (res == -1) 21228 goto exit_failure; 21229 if (res != 0) 21230 goto exit; 21231 21232 if (bucket == NULL) { 21233 /* TODO: Error code, actually we failed to *locate* the schema. */ 21234 if (ctxt->URL) 21235 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21236 NULL, NULL, 21237 "Failed to locate the main schema resource at '%s'", 21238 ctxt->URL, NULL); 21239 else 21240 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21241 NULL, NULL, 21242 "Failed to locate the main schema resource", 21243 NULL, NULL); 21244 goto exit; 21245 } 21246 /* Then do the parsing for good. */ 21247 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21248 goto exit_failure; 21249 if (ctxt->nberrors != 0) 21250 goto exit; 21251 21252 mainSchema->doc = bucket->doc; 21253 mainSchema->preserve = ctxt->preserve; 21254 21255 ctxt->schema = mainSchema; 21256 21257 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21258 goto exit_failure; 21259 21260 /* 21261 * TODO: This is not nice, since we cannot distinguish from the 21262 * result if there was an internal error or not. 21263 */ 21264exit: 21265 if (ctxt->nberrors != 0) { 21266 if (mainSchema) { 21267 xmlSchemaFree(mainSchema); 21268 mainSchema = NULL; 21269 } 21270 if (ctxt->constructor) { 21271 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21272 ctxt->constructor = NULL; 21273 ctxt->ownsConstructor = 0; 21274 } 21275 } 21276 ctxt->schema = NULL; 21277 return(mainSchema); 21278exit_failure: 21279 /* 21280 * Quite verbose, but should catch internal errors, which were 21281 * not communitated. 21282 */ 21283 if (mainSchema) { 21284 xmlSchemaFree(mainSchema); 21285 mainSchema = NULL; 21286 } 21287 if (ctxt->constructor) { 21288 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21289 ctxt->constructor = NULL; 21290 ctxt->ownsConstructor = 0; 21291 } 21292 PERROR_INT2("xmlSchemaParse", 21293 "An internal error occured"); 21294 ctxt->schema = NULL; 21295 return(NULL); 21296} 21297 21298/** 21299 * xmlSchemaSetParserErrors: 21300 * @ctxt: a schema validation context 21301 * @err: the error callback 21302 * @warn: the warning callback 21303 * @ctx: contextual data for the callbacks 21304 * 21305 * Set the callback functions used to handle errors for a validation context 21306 */ 21307void 21308xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21309 xmlSchemaValidityErrorFunc err, 21310 xmlSchemaValidityWarningFunc warn, void *ctx) 21311{ 21312 if (ctxt == NULL) 21313 return; 21314 ctxt->error = err; 21315 ctxt->warning = warn; 21316 ctxt->errCtxt = ctx; 21317 if (ctxt->vctxt != NULL) 21318 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21319} 21320 21321/** 21322 * xmlSchemaSetParserStructuredErrors: 21323 * @ctxt: a schema parser context 21324 * @serror: the structured error function 21325 * @ctx: the functions context 21326 * 21327 * Set the structured error callback 21328 */ 21329void 21330xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21331 xmlStructuredErrorFunc serror, 21332 void *ctx) 21333{ 21334 if (ctxt == NULL) 21335 return; 21336 ctxt->serror = serror; 21337 ctxt->errCtxt = ctx; 21338 if (ctxt->vctxt != NULL) 21339 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21340} 21341 21342/** 21343 * xmlSchemaGetParserErrors: 21344 * @ctxt: a XMl-Schema parser context 21345 * @err: the error callback result 21346 * @warn: the warning callback result 21347 * @ctx: contextual data for the callbacks result 21348 * 21349 * Get the callback information used to handle errors for a parser context 21350 * 21351 * Returns -1 in case of failure, 0 otherwise 21352 */ 21353int 21354xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21355 xmlSchemaValidityErrorFunc * err, 21356 xmlSchemaValidityWarningFunc * warn, void **ctx) 21357{ 21358 if (ctxt == NULL) 21359 return(-1); 21360 if (err != NULL) 21361 *err = ctxt->error; 21362 if (warn != NULL) 21363 *warn = ctxt->warning; 21364 if (ctx != NULL) 21365 *ctx = ctxt->errCtxt; 21366 return(0); 21367} 21368 21369/** 21370 * xmlSchemaFacetTypeToString: 21371 * @type: the facet type 21372 * 21373 * Convert the xmlSchemaTypeType to a char string. 21374 * 21375 * Returns the char string representation of the facet type if the 21376 * type is a facet and an "Internal Error" string otherwise. 21377 */ 21378static const xmlChar * 21379xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21380{ 21381 switch (type) { 21382 case XML_SCHEMA_FACET_PATTERN: 21383 return (BAD_CAST "pattern"); 21384 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21385 return (BAD_CAST "maxExclusive"); 21386 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21387 return (BAD_CAST "maxInclusive"); 21388 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21389 return (BAD_CAST "minExclusive"); 21390 case XML_SCHEMA_FACET_MININCLUSIVE: 21391 return (BAD_CAST "minInclusive"); 21392 case XML_SCHEMA_FACET_WHITESPACE: 21393 return (BAD_CAST "whiteSpace"); 21394 case XML_SCHEMA_FACET_ENUMERATION: 21395 return (BAD_CAST "enumeration"); 21396 case XML_SCHEMA_FACET_LENGTH: 21397 return (BAD_CAST "length"); 21398 case XML_SCHEMA_FACET_MAXLENGTH: 21399 return (BAD_CAST "maxLength"); 21400 case XML_SCHEMA_FACET_MINLENGTH: 21401 return (BAD_CAST "minLength"); 21402 case XML_SCHEMA_FACET_TOTALDIGITS: 21403 return (BAD_CAST "totalDigits"); 21404 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21405 return (BAD_CAST "fractionDigits"); 21406 default: 21407 break; 21408 } 21409 return (BAD_CAST "Internal Error"); 21410} 21411 21412static xmlSchemaWhitespaceValueType 21413xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21414{ 21415 /* 21416 * The normalization type can be changed only for types which are derived 21417 * from xsd:string. 21418 */ 21419 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21420 /* 21421 * Note that we assume a whitespace of preserve for anySimpleType. 21422 */ 21423 if ((type->builtInType == XML_SCHEMAS_STRING) || 21424 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21425 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21426 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21427 return(XML_SCHEMA_WHITESPACE_REPLACE); 21428 else { 21429 /* 21430 * For all �atomic� datatypes other than string (and types �derived� 21431 * by �restriction� from it) the value of whiteSpace is fixed to 21432 * collapse 21433 * Note that this includes built-in list datatypes. 21434 */ 21435 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21436 } 21437 } else if (WXS_IS_LIST(type)) { 21438 /* 21439 * For list types the facet "whiteSpace" is fixed to "collapse". 21440 */ 21441 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21442 } else if (WXS_IS_UNION(type)) { 21443 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21444 } else if (WXS_IS_ATOMIC(type)) { 21445 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21446 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21447 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21448 return (XML_SCHEMA_WHITESPACE_REPLACE); 21449 else 21450 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21451 } 21452 return (-1); 21453} 21454 21455/************************************************************************ 21456 * * 21457 * Simple type validation * 21458 * * 21459 ************************************************************************/ 21460 21461 21462/************************************************************************ 21463 * * 21464 * DOM Validation code * 21465 * * 21466 ************************************************************************/ 21467 21468/** 21469 * xmlSchemaAssembleByLocation: 21470 * @pctxt: a schema parser context 21471 * @vctxt: a schema validation context 21472 * @schema: the existing schema 21473 * @node: the node that fired the assembling 21474 * @nsName: the namespace name of the new schema 21475 * @location: the location of the schema 21476 * 21477 * Expands an existing schema by an additional schema. 21478 * 21479 * Returns 0 if the new schema is correct, a positive error code 21480 * number otherwise and -1 in case of an internal or API error. 21481 */ 21482static int 21483xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21484 xmlSchemaPtr schema, 21485 xmlNodePtr node, 21486 const xmlChar *nsName, 21487 const xmlChar *location) 21488{ 21489 int ret = 0; 21490 xmlSchemaParserCtxtPtr pctxt; 21491 xmlSchemaBucketPtr bucket = NULL; 21492 21493 if ((vctxt == NULL) || (schema == NULL)) 21494 return (-1); 21495 21496 if (vctxt->pctxt == NULL) { 21497 VERROR_INT("xmlSchemaAssembleByLocation", 21498 "no parser context available"); 21499 return(-1); 21500 } 21501 pctxt = vctxt->pctxt; 21502 if (pctxt->constructor == NULL) { 21503 PERROR_INT("xmlSchemaAssembleByLocation", 21504 "no constructor"); 21505 return(-1); 21506 } 21507 /* 21508 * Acquire the schema document. 21509 */ 21510 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21511 location, node); 21512 /* 21513 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21514 * the process will automatically change this to 21515 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21516 */ 21517 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21518 location, NULL, NULL, 0, node, NULL, nsName, 21519 &bucket); 21520 if (ret != 0) 21521 return(ret); 21522 if (bucket == NULL) { 21523 /* 21524 * Generate a warning that the document could not be located. 21525 */ 21526 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21527 node, NULL, 21528 "The document at location '%s' could not be acquired", 21529 location, NULL, NULL); 21530 return(ret); 21531 } 21532 /* 21533 * The first located schema will be handled as if all other 21534 * schemas imported by XSI were imported by this first schema. 21535 */ 21536 if ((bucket != NULL) && 21537 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21538 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21539 /* 21540 * TODO: Is this handled like an import? I.e. is it not an error 21541 * if the schema cannot be located? 21542 */ 21543 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21544 return(0); 21545 /* 21546 * We will reuse the parser context for every schema imported 21547 * directly via XSI. So reset the context. 21548 */ 21549 pctxt->nberrors = 0; 21550 pctxt->err = 0; 21551 pctxt->doc = bucket->doc; 21552 21553 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21554 if (ret == -1) { 21555 pctxt->doc = NULL; 21556 goto exit_failure; 21557 } 21558 /* Paranoid error channelling. */ 21559 if ((ret == 0) && (pctxt->nberrors != 0)) 21560 ret = pctxt->err; 21561 if (pctxt->nberrors == 0) { 21562 /* 21563 * Only bother to fixup pending components, if there was 21564 * no error yet. 21565 * For every XSI acquired schema (and its sub-schemata) we will 21566 * fixup the components. 21567 */ 21568 xmlSchemaFixupComponents(pctxt, bucket); 21569 ret = pctxt->err; 21570 /* 21571 * Not nice, but we need somehow to channel the schema parser 21572 * error to the validation context. 21573 */ 21574 if ((ret != 0) && (vctxt->err == 0)) 21575 vctxt->err = ret; 21576 vctxt->nberrors += pctxt->nberrors; 21577 } else { 21578 /* Add to validation error sum. */ 21579 vctxt->nberrors += pctxt->nberrors; 21580 } 21581 pctxt->doc = NULL; 21582 return(ret); 21583exit_failure: 21584 pctxt->doc = NULL; 21585 return (-1); 21586} 21587 21588static xmlSchemaAttrInfoPtr 21589xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21590 int metaType) 21591{ 21592 if (vctxt->nbAttrInfos == 0) 21593 return (NULL); 21594 { 21595 int i; 21596 xmlSchemaAttrInfoPtr iattr; 21597 21598 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21599 iattr = vctxt->attrInfos[i]; 21600 if (iattr->metaType == metaType) 21601 return (iattr); 21602 } 21603 21604 } 21605 return (NULL); 21606} 21607 21608/** 21609 * xmlSchemaAssembleByXSI: 21610 * @vctxt: a schema validation context 21611 * 21612 * Expands an existing schema by an additional schema using 21613 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21614 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21615 * must be set to 1. 21616 * 21617 * Returns 0 if the new schema is correct, a positive error code 21618 * number otherwise and -1 in case of an internal or API error. 21619 */ 21620static int 21621xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21622{ 21623 const xmlChar *cur, *end; 21624 const xmlChar *nsname = NULL, *location; 21625 int count = 0; 21626 int ret = 0; 21627 xmlSchemaAttrInfoPtr iattr; 21628 21629 /* 21630 * Parse the value; we will assume an even number of values 21631 * to be given (this is how Xerces and XSV work). 21632 * 21633 * URGENT TODO: !! This needs to work for both 21634 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21635 * element !! 21636 */ 21637 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21638 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21639 if (iattr == NULL) 21640 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21641 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21642 if (iattr == NULL) 21643 return (0); 21644 cur = iattr->value; 21645 do { 21646 /* 21647 * TODO: Move the string parsing mechanism away from here. 21648 */ 21649 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21650 /* 21651 * Get the namespace name. 21652 */ 21653 while (IS_BLANK_CH(*cur)) 21654 cur++; 21655 end = cur; 21656 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21657 end++; 21658 if (end == cur) 21659 break; 21660 count++; /* TODO: Don't use the schema's dict. */ 21661 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21662 cur = end; 21663 } 21664 /* 21665 * Get the URI. 21666 */ 21667 while (IS_BLANK_CH(*cur)) 21668 cur++; 21669 end = cur; 21670 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21671 end++; 21672 if (end == cur) { 21673 if (iattr->metaType == 21674 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21675 { 21676 /* 21677 * If using @schemaLocation then tuples are expected. 21678 * I.e. the namespace name *and* the document's URI. 21679 */ 21680 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21681 iattr->node, NULL, 21682 "The value must consist of tuples: the target namespace " 21683 "name and the document's URI", NULL, NULL, NULL); 21684 } 21685 break; 21686 } 21687 count++; /* TODO: Don't use the schema's dict. */ 21688 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21689 cur = end; 21690 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21691 iattr->node, nsname, location); 21692 if (ret == -1) { 21693 VERROR_INT("xmlSchemaAssembleByXSI", 21694 "assembling schemata"); 21695 return (-1); 21696 } 21697 } while (*cur != 0); 21698 return (ret); 21699} 21700 21701static const xmlChar * 21702xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21703 const xmlChar *prefix) 21704{ 21705 if (vctxt->sax != NULL) { 21706 int i, j; 21707 xmlSchemaNodeInfoPtr inode; 21708 21709 for (i = vctxt->depth; i >= 0; i--) { 21710 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21711 inode = vctxt->elemInfos[i]; 21712 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21713 if (((prefix == NULL) && 21714 (inode->nsBindings[j] == NULL)) || 21715 ((prefix != NULL) && xmlStrEqual(prefix, 21716 inode->nsBindings[j]))) { 21717 21718 /* 21719 * Note that the namespace bindings are already 21720 * in a string dict. 21721 */ 21722 return (inode->nsBindings[j+1]); 21723 } 21724 } 21725 } 21726 } 21727 return (NULL); 21728#ifdef LIBXML_WRITER_ENABLED 21729 } else if (vctxt->reader != NULL) { 21730 xmlChar *nsName; 21731 21732 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21733 if (nsName != NULL) { 21734 const xmlChar *ret; 21735 21736 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21737 xmlFree(nsName); 21738 return (ret); 21739 } else 21740 return (NULL); 21741#endif 21742 } else { 21743 xmlNsPtr ns; 21744 21745 if ((vctxt->inode->node == NULL) || 21746 (vctxt->inode->node->doc == NULL)) { 21747 VERROR_INT("xmlSchemaLookupNamespace", 21748 "no node or node's doc avaliable"); 21749 return (NULL); 21750 } 21751 ns = xmlSearchNs(vctxt->inode->node->doc, 21752 vctxt->inode->node, prefix); 21753 if (ns != NULL) 21754 return (ns->href); 21755 return (NULL); 21756 } 21757} 21758 21759/* 21760* This one works on the schema of the validation context. 21761*/ 21762static int 21763xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21764 xmlSchemaPtr schema, 21765 xmlNodePtr node, 21766 const xmlChar *value, 21767 xmlSchemaValPtr *val, 21768 int valNeeded) 21769{ 21770 int ret; 21771 21772 if (vctxt && (vctxt->schema == NULL)) { 21773 VERROR_INT("xmlSchemaValidateNotation", 21774 "a schema is needed on the validation context"); 21775 return (-1); 21776 } 21777 ret = xmlValidateQName(value, 1); 21778 if (ret != 0) 21779 return (ret); 21780 { 21781 xmlChar *localName = NULL; 21782 xmlChar *prefix = NULL; 21783 21784 localName = xmlSplitQName2(value, &prefix); 21785 if (prefix != NULL) { 21786 const xmlChar *nsName = NULL; 21787 21788 if (vctxt != NULL) 21789 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21790 else if (node != NULL) { 21791 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21792 if (ns != NULL) 21793 nsName = ns->href; 21794 } else { 21795 xmlFree(prefix); 21796 xmlFree(localName); 21797 return (1); 21798 } 21799 if (nsName == NULL) { 21800 xmlFree(prefix); 21801 xmlFree(localName); 21802 return (1); 21803 } 21804 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21805 if (valNeeded && (val != NULL)) { 21806 (*val) = xmlSchemaNewNOTATIONValue(BAD_CAST localName, 21807 BAD_CAST xmlStrdup(nsName)); 21808 if (*val == NULL) 21809 ret = -1; 21810 } 21811 } else 21812 ret = 1; 21813 xmlFree(prefix); 21814 xmlFree(localName); 21815 } else { 21816 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21817 if (valNeeded && (val != NULL)) { 21818 (*val) = xmlSchemaNewNOTATIONValue( 21819 BAD_CAST xmlStrdup(value), NULL); 21820 if (*val == NULL) 21821 ret = -1; 21822 } 21823 } else 21824 return (1); 21825 } 21826 } 21827 return (ret); 21828} 21829 21830static int 21831xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21832 const xmlChar* lname, 21833 const xmlChar* nsname) 21834{ 21835 int i; 21836 21837 lname = xmlDictLookup(vctxt->dict, lname, -1); 21838 if (lname == NULL) 21839 return(-1); 21840 if (nsname != NULL) { 21841 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21842 if (nsname == NULL) 21843 return(-1); 21844 } 21845 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21846 if ((vctxt->nodeQNames->items [i] == lname) && 21847 (vctxt->nodeQNames->items[i +1] == nsname)) 21848 /* Already there */ 21849 return(i); 21850 } 21851 /* Add new entry. */ 21852 i = vctxt->nodeQNames->nbItems; 21853 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21854 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21855 return(i); 21856} 21857 21858/************************************************************************ 21859 * * 21860 * Validation of identity-constraints (IDC) * 21861 * * 21862 ************************************************************************/ 21863 21864/** 21865 * xmlSchemaAugmentIDC: 21866 * @idcDef: the IDC definition 21867 * 21868 * Creates an augmented IDC definition item. 21869 * 21870 * Returns the item, or NULL on internal errors. 21871 */ 21872static void 21873xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, 21874 xmlSchemaValidCtxtPtr vctxt) 21875{ 21876 xmlSchemaIDCAugPtr aidc; 21877 21878 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 21879 if (aidc == NULL) { 21880 xmlSchemaVErrMemory(vctxt, 21881 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 21882 NULL); 21883 return; 21884 } 21885 aidc->keyrefDepth = -1; 21886 aidc->def = idcDef; 21887 aidc->next = NULL; 21888 if (vctxt->aidcs == NULL) 21889 vctxt->aidcs = aidc; 21890 else { 21891 aidc->next = vctxt->aidcs; 21892 vctxt->aidcs = aidc; 21893 } 21894 /* 21895 * Save if we have keyrefs at all. 21896 */ 21897 if ((vctxt->hasKeyrefs == 0) && 21898 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 21899 vctxt->hasKeyrefs = 1; 21900} 21901 21902/** 21903 * xmlSchemaIDCNewBinding: 21904 * @idcDef: the IDC definition of this binding 21905 * 21906 * Creates a new IDC binding. 21907 * 21908 * Returns the new IDC binding, NULL on internal errors. 21909 */ 21910static xmlSchemaPSVIIDCBindingPtr 21911xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 21912{ 21913 xmlSchemaPSVIIDCBindingPtr ret; 21914 21915 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 21916 sizeof(xmlSchemaPSVIIDCBinding)); 21917 if (ret == NULL) { 21918 xmlSchemaVErrMemory(NULL, 21919 "allocating a PSVI IDC binding item", NULL); 21920 return (NULL); 21921 } 21922 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 21923 ret->definition = idcDef; 21924 return (ret); 21925} 21926 21927/** 21928 * xmlSchemaIDCStoreNodeTableItem: 21929 * @vctxt: the WXS validation context 21930 * @item: the IDC node table item 21931 * 21932 * The validation context is used to store IDC node table items. 21933 * They are stored to avoid copying them if IDC node-tables are merged 21934 * with corresponding parent IDC node-tables (bubbling). 21935 * 21936 * Returns 0 if succeeded, -1 on internal errors. 21937 */ 21938static int 21939xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 21940 xmlSchemaPSVIIDCNodePtr item) 21941{ 21942 /* 21943 * Add to gobal list. 21944 */ 21945 if (vctxt->idcNodes == NULL) { 21946 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 21947 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 21948 if (vctxt->idcNodes == NULL) { 21949 xmlSchemaVErrMemory(vctxt, 21950 "allocating the IDC node table item list", NULL); 21951 return (-1); 21952 } 21953 vctxt->sizeIdcNodes = 20; 21954 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 21955 vctxt->sizeIdcNodes *= 2; 21956 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 21957 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 21958 sizeof(xmlSchemaPSVIIDCNodePtr)); 21959 if (vctxt->idcNodes == NULL) { 21960 xmlSchemaVErrMemory(vctxt, 21961 "re-allocating the IDC node table item list", NULL); 21962 return (-1); 21963 } 21964 } 21965 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 21966 21967 return (0); 21968} 21969 21970/** 21971 * xmlSchemaIDCStoreKey: 21972 * @vctxt: the WXS validation context 21973 * @item: the IDC key 21974 * 21975 * The validation context is used to store an IDC key. 21976 * 21977 * Returns 0 if succeeded, -1 on internal errors. 21978 */ 21979static int 21980xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 21981 xmlSchemaPSVIIDCKeyPtr key) 21982{ 21983 /* 21984 * Add to gobal list. 21985 */ 21986 if (vctxt->idcKeys == NULL) { 21987 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 21988 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 21989 if (vctxt->idcKeys == NULL) { 21990 xmlSchemaVErrMemory(vctxt, 21991 "allocating the IDC key storage list", NULL); 21992 return (-1); 21993 } 21994 vctxt->sizeIdcKeys = 40; 21995 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 21996 vctxt->sizeIdcKeys *= 2; 21997 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 21998 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 21999 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22000 if (vctxt->idcKeys == NULL) { 22001 xmlSchemaVErrMemory(vctxt, 22002 "re-allocating the IDC key storage list", NULL); 22003 return (-1); 22004 } 22005 } 22006 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22007 22008 return (0); 22009} 22010 22011/** 22012 * xmlSchemaIDCAppendNodeTableItem: 22013 * @bind: the IDC binding 22014 * @ntItem: the node-table item 22015 * 22016 * Appends the IDC node-table item to the binding. 22017 * 22018 * Returns 0 on success and -1 on internal errors. 22019 */ 22020static int 22021xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22022 xmlSchemaPSVIIDCNodePtr ntItem) 22023{ 22024 if (bind->nodeTable == NULL) { 22025 bind->sizeNodes = 10; 22026 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22027 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22028 if (bind->nodeTable == NULL) { 22029 xmlSchemaVErrMemory(NULL, 22030 "allocating an array of IDC node-table items", NULL); 22031 return(-1); 22032 } 22033 } else if (bind->sizeNodes <= bind->nbNodes) { 22034 bind->sizeNodes *= 2; 22035 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22036 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22037 sizeof(xmlSchemaPSVIIDCNodePtr)); 22038 if (bind->nodeTable == NULL) { 22039 xmlSchemaVErrMemory(NULL, 22040 "re-allocating an array of IDC node-table items", NULL); 22041 return(-1); 22042 } 22043 } 22044 bind->nodeTable[bind->nbNodes++] = ntItem; 22045 return(0); 22046} 22047 22048/** 22049 * xmlSchemaIDCAcquireBinding: 22050 * @vctxt: the WXS validation context 22051 * @matcher: the IDC matcher 22052 * 22053 * Looks up an PSVI IDC binding, for the IDC definition and 22054 * of the given matcher. If none found, a new one is created 22055 * and added to the IDC table. 22056 * 22057 * Returns an IDC binding or NULL on internal errors. 22058 */ 22059static xmlSchemaPSVIIDCBindingPtr 22060xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22061 xmlSchemaIDCMatcherPtr matcher) 22062{ 22063 xmlSchemaNodeInfoPtr ielem; 22064 22065 ielem = vctxt->elemInfos[matcher->depth]; 22066 22067 if (ielem->idcTable == NULL) { 22068 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22069 if (ielem->idcTable == NULL) 22070 return (NULL); 22071 return(ielem->idcTable); 22072 } else { 22073 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22074 22075 bind = ielem->idcTable; 22076 do { 22077 if (bind->definition == matcher->aidc->def) 22078 return(bind); 22079 if (bind->next == NULL) { 22080 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22081 if (bind->next == NULL) 22082 return (NULL); 22083 return(bind->next); 22084 } 22085 bind = bind->next; 22086 } while (bind != NULL); 22087 } 22088 return (NULL); 22089} 22090 22091static xmlSchemaItemListPtr 22092xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22093 xmlSchemaIDCMatcherPtr matcher) 22094{ 22095 if (matcher->targets == NULL) 22096 matcher->targets = xmlSchemaItemListCreate(); 22097 return(matcher->targets); 22098} 22099 22100/** 22101 * xmlSchemaIDCFreeKey: 22102 * @key: the IDC key 22103 * 22104 * Frees an IDC key together with its compiled value. 22105 */ 22106static void 22107xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22108{ 22109 if (key->val != NULL) 22110 xmlSchemaFreeValue(key->val); 22111 xmlFree(key); 22112} 22113 22114/** 22115 * xmlSchemaIDCFreeBinding: 22116 * 22117 * Frees an IDC binding. Note that the node table-items 22118 * are not freed. 22119 */ 22120static void 22121xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22122{ 22123 if (bind->nodeTable != NULL) 22124 xmlFree(bind->nodeTable); 22125 if (bind->dupls != NULL) 22126 xmlSchemaItemListFree(bind->dupls); 22127 xmlFree(bind); 22128} 22129 22130/** 22131 * xmlSchemaIDCFreeIDCTable: 22132 * @bind: the first IDC binding in the list 22133 * 22134 * Frees an IDC table, i.e. all the IDC bindings in the list. 22135 */ 22136static void 22137xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22138{ 22139 xmlSchemaPSVIIDCBindingPtr prev; 22140 22141 while (bind != NULL) { 22142 prev = bind; 22143 bind = bind->next; 22144 xmlSchemaIDCFreeBinding(prev); 22145 } 22146} 22147 22148/** 22149 * xmlSchemaIDCFreeMatcherList: 22150 * @matcher: the first IDC matcher in the list 22151 * 22152 * Frees a list of IDC matchers. 22153 */ 22154static void 22155xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22156{ 22157 xmlSchemaIDCMatcherPtr next; 22158 22159 while (matcher != NULL) { 22160 next = matcher->next; 22161 if (matcher->keySeqs != NULL) { 22162 int i; 22163 for (i = 0; i < matcher->sizeKeySeqs; i++) 22164 if (matcher->keySeqs[i] != NULL) 22165 xmlFree(matcher->keySeqs[i]); 22166 xmlFree(matcher->keySeqs); 22167 } 22168 if (matcher->targets != NULL) { 22169 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22170 int i; 22171 xmlSchemaPSVIIDCNodePtr idcNode; 22172 /* 22173 * Node-table items for keyrefs are not stored globally 22174 * to the validation context, since they are not bubbled. 22175 * We need to free them here. 22176 */ 22177 for (i = 0; i < matcher->targets->nbItems; i++) { 22178 idcNode = 22179 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22180 xmlFree(idcNode->keys); 22181 xmlFree(idcNode); 22182 } 22183 } 22184 xmlSchemaItemListFree(matcher->targets); 22185 } 22186 xmlFree(matcher); 22187 matcher = next; 22188 } 22189} 22190 22191/** 22192 * xmlSchemaIDCReleaseMatcherList: 22193 * @vctxt: the WXS validation context 22194 * @matcher: the first IDC matcher in the list 22195 * 22196 * Caches a list of IDC matchers for reuse. 22197 */ 22198static void 22199xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22200 xmlSchemaIDCMatcherPtr matcher) 22201{ 22202 xmlSchemaIDCMatcherPtr next; 22203 22204 while (matcher != NULL) { 22205 next = matcher->next; 22206 if (matcher->keySeqs != NULL) { 22207 int i; 22208 /* 22209 * Don't free the array, but only the content. 22210 */ 22211 for (i = 0; i < matcher->sizeKeySeqs; i++) 22212 if (matcher->keySeqs[i] != NULL) { 22213 xmlFree(matcher->keySeqs[i]); 22214 matcher->keySeqs[i] = NULL; 22215 } 22216 } 22217 if (matcher->targets) { 22218 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22219 int i; 22220 xmlSchemaPSVIIDCNodePtr idcNode; 22221 /* 22222 * Node-table items for keyrefs are not stored globally 22223 * to the validation context, since they are not bubbled. 22224 * We need to free them here. 22225 */ 22226 for (i = 0; i < matcher->targets->nbItems; i++) { 22227 idcNode = 22228 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22229 xmlFree(idcNode->keys); 22230 xmlFree(idcNode); 22231 } 22232 } 22233 xmlSchemaItemListFree(matcher->targets); 22234 matcher->targets = NULL; 22235 } 22236 matcher->next = NULL; 22237 /* 22238 * Cache the matcher. 22239 */ 22240 if (vctxt->idcMatcherCache != NULL) 22241 matcher->nextCached = vctxt->idcMatcherCache; 22242 vctxt->idcMatcherCache = matcher; 22243 22244 matcher = next; 22245 } 22246} 22247 22248/** 22249 * xmlSchemaIDCAddStateObject: 22250 * @vctxt: the WXS validation context 22251 * @matcher: the IDC matcher 22252 * @sel: the XPath information 22253 * @parent: the parent "selector" state object if any 22254 * @type: "selector" or "field" 22255 * 22256 * Creates/reuses and activates state objects for the given 22257 * XPath information; if the XPath expression consists of unions, 22258 * multiple state objects are created for every unioned expression. 22259 * 22260 * Returns 0 on success and -1 on internal errors. 22261 */ 22262static int 22263xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22264 xmlSchemaIDCMatcherPtr matcher, 22265 xmlSchemaIDCSelectPtr sel, 22266 int type) 22267{ 22268 xmlSchemaIDCStateObjPtr sto; 22269 22270 /* 22271 * Reuse the state objects from the pool. 22272 */ 22273 if (vctxt->xpathStatePool != NULL) { 22274 sto = vctxt->xpathStatePool; 22275 vctxt->xpathStatePool = sto->next; 22276 sto->next = NULL; 22277 } else { 22278 /* 22279 * Create a new state object. 22280 */ 22281 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22282 if (sto == NULL) { 22283 xmlSchemaVErrMemory(NULL, 22284 "allocating an IDC state object", NULL); 22285 return (-1); 22286 } 22287 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22288 } 22289 /* 22290 * Add to global list. 22291 */ 22292 if (vctxt->xpathStates != NULL) 22293 sto->next = vctxt->xpathStates; 22294 vctxt->xpathStates = sto; 22295 22296 /* 22297 * Free the old xpath validation context. 22298 */ 22299 if (sto->xpathCtxt != NULL) 22300 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22301 22302 /* 22303 * Create a new XPath (pattern) validation context. 22304 */ 22305 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22306 (xmlPatternPtr) sel->xpathComp); 22307 if (sto->xpathCtxt == NULL) { 22308 VERROR_INT("xmlSchemaIDCAddStateObject", 22309 "failed to create an XPath validation context"); 22310 return (-1); 22311 } 22312 sto->type = type; 22313 sto->depth = vctxt->depth; 22314 sto->matcher = matcher; 22315 sto->sel = sel; 22316 sto->nbHistory = 0; 22317 22318#ifdef DEBUG_IDC 22319 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22320 sto->sel->xpath); 22321#endif 22322 return (0); 22323} 22324 22325/** 22326 * xmlSchemaXPathEvaluate: 22327 * @vctxt: the WXS validation context 22328 * @nodeType: the nodeType of the current node 22329 * 22330 * Evaluates all active XPath state objects. 22331 * 22332 * Returns the number of IC "field" state objects which resolved to 22333 * this node, 0 if none resolved and -1 on internal errors. 22334 */ 22335static int 22336xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22337 xmlElementType nodeType) 22338{ 22339 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22340 int res, resolved = 0, depth = vctxt->depth; 22341 22342 if (vctxt->xpathStates == NULL) 22343 return (0); 22344 22345 if (nodeType == XML_ATTRIBUTE_NODE) 22346 depth++; 22347#ifdef DEBUG_IDC 22348 { 22349 xmlChar *str = NULL; 22350 xmlGenericError(xmlGenericErrorContext, 22351 "IDC: EVAL on %s, depth %d, type %d\n", 22352 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22353 vctxt->inode->localName), depth, nodeType); 22354 FREE_AND_NULL(str) 22355 } 22356#endif 22357 /* 22358 * Process all active XPath state objects. 22359 */ 22360 first = vctxt->xpathStates; 22361 sto = first; 22362 while (sto != head) { 22363#ifdef DEBUG_IDC 22364 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22365 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22366 sto->matcher->aidc->def->name, sto->sel->xpath); 22367 else 22368 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22369 sto->matcher->aidc->def->name, sto->sel->xpath); 22370#endif 22371 if (nodeType == XML_ELEMENT_NODE) 22372 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22373 vctxt->inode->localName, vctxt->inode->nsName); 22374 else 22375 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22376 vctxt->inode->localName, vctxt->inode->nsName); 22377 22378 if (res == -1) { 22379 VERROR_INT("xmlSchemaXPathEvaluate", 22380 "calling xmlStreamPush()"); 22381 return (-1); 22382 } 22383 if (res == 0) 22384 goto next_sto; 22385 /* 22386 * Full match. 22387 */ 22388#ifdef DEBUG_IDC 22389 xmlGenericError(xmlGenericErrorContext, "IDC: " 22390 "MATCH\n"); 22391#endif 22392 /* 22393 * Register a match in the state object history. 22394 */ 22395 if (sto->history == NULL) { 22396 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22397 if (sto->history == NULL) { 22398 xmlSchemaVErrMemory(NULL, 22399 "allocating the state object history", NULL); 22400 return(-1); 22401 } 22402 sto->sizeHistory = 5; 22403 } else if (sto->sizeHistory <= sto->nbHistory) { 22404 sto->sizeHistory *= 2; 22405 sto->history = (int *) xmlRealloc(sto->history, 22406 sto->sizeHistory * sizeof(int)); 22407 if (sto->history == NULL) { 22408 xmlSchemaVErrMemory(NULL, 22409 "re-allocating the state object history", NULL); 22410 return(-1); 22411 } 22412 } 22413 sto->history[sto->nbHistory++] = depth; 22414 22415#ifdef DEBUG_IDC 22416 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22417 vctxt->depth); 22418#endif 22419 22420 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22421 xmlSchemaIDCSelectPtr sel; 22422 /* 22423 * Activate state objects for the IDC fields of 22424 * the IDC selector. 22425 */ 22426#ifdef DEBUG_IDC 22427 xmlGenericError(xmlGenericErrorContext, "IDC: " 22428 "activating field states\n"); 22429#endif 22430 sel = sto->matcher->aidc->def->fields; 22431 while (sel != NULL) { 22432 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22433 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22434 return (-1); 22435 sel = sel->next; 22436 } 22437 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22438 /* 22439 * An IDC key node was found by the IDC field. 22440 */ 22441#ifdef DEBUG_IDC 22442 xmlGenericError(xmlGenericErrorContext, 22443 "IDC: key found\n"); 22444#endif 22445 /* 22446 * Notify that the character value of this node is 22447 * needed. 22448 */ 22449 if (resolved == 0) { 22450 if ((vctxt->inode->flags & 22451 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22452 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22453 } 22454 resolved++; 22455 } 22456next_sto: 22457 if (sto->next == NULL) { 22458 /* 22459 * Evaluate field state objects created on this node as well. 22460 */ 22461 head = first; 22462 sto = vctxt->xpathStates; 22463 } else 22464 sto = sto->next; 22465 } 22466 return (resolved); 22467} 22468 22469static const xmlChar * 22470xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22471 xmlChar **buf, 22472 xmlSchemaPSVIIDCKeyPtr *seq, 22473 int count) 22474{ 22475 int i, res; 22476 xmlChar *value = NULL; 22477 22478 *buf = xmlStrdup(BAD_CAST "["); 22479 for (i = 0; i < count; i++) { 22480 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22481 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22482 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22483 &value); 22484 if (res == 0) 22485 *buf = xmlStrcat(*buf, BAD_CAST value); 22486 else { 22487 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22488 "failed to compute a canonical value"); 22489 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22490 } 22491 if (i < count -1) 22492 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22493 else 22494 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22495 if (value != NULL) { 22496 xmlFree(value); 22497 value = NULL; 22498 } 22499 } 22500 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22501 22502 return (BAD_CAST *buf); 22503} 22504 22505/** 22506 * xmlSchemaXPathPop: 22507 * @vctxt: the WXS validation context 22508 * 22509 * Pops all XPath states. 22510 * 22511 * Returns 0 on success and -1 on internal errors. 22512 */ 22513static int 22514xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22515{ 22516 xmlSchemaIDCStateObjPtr sto; 22517 int res; 22518 22519 if (vctxt->xpathStates == NULL) 22520 return(0); 22521 sto = vctxt->xpathStates; 22522 do { 22523 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22524 if (res == -1) 22525 return (-1); 22526 sto = sto->next; 22527 } while (sto != NULL); 22528 return(0); 22529} 22530 22531/** 22532 * xmlSchemaXPathProcessHistory: 22533 * @vctxt: the WXS validation context 22534 * @type: the simple/complex type of the current node if any at all 22535 * @val: the precompiled value 22536 * 22537 * Processes and pops the history items of the IDC state objects. 22538 * IDC key-sequences are validated/created on IDC bindings. 22539 * 22540 * Returns 0 on success and -1 on internal errors. 22541 */ 22542static int 22543xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22544 int depth) 22545{ 22546 xmlSchemaIDCStateObjPtr sto, nextsto; 22547 int res, matchDepth; 22548 xmlSchemaPSVIIDCKeyPtr key = NULL; 22549 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22550 22551 if (vctxt->xpathStates == NULL) 22552 return (0); 22553 sto = vctxt->xpathStates; 22554 22555#ifdef DEBUG_IDC 22556 { 22557 xmlChar *str = NULL; 22558 xmlGenericError(xmlGenericErrorContext, 22559 "IDC: BACK on %s, depth %d\n", 22560 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22561 vctxt->inode->localName), vctxt->depth); 22562 FREE_AND_NULL(str) 22563 } 22564#endif 22565 /* 22566 * Evaluate the state objects. 22567 */ 22568 while (sto != NULL) { 22569 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22570 if (res == -1) { 22571 VERROR_INT("xmlSchemaXPathProcessHistory", 22572 "calling xmlStreamPop()"); 22573 return (-1); 22574 } 22575#ifdef DEBUG_IDC 22576 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22577 sto->sel->xpath); 22578#endif 22579 if (sto->nbHistory == 0) 22580 goto deregister_check; 22581 22582 matchDepth = sto->history[sto->nbHistory -1]; 22583 22584 /* 22585 * Only matches at the current depth are of interest. 22586 */ 22587 if (matchDepth != depth) { 22588 sto = sto->next; 22589 continue; 22590 } 22591 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22592 /* 22593 * NOTE: According to 22594 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22595 * ... the simple-content of complex types is also allowed. 22596 */ 22597 22598 if (WXS_IS_COMPLEX(type)) { 22599 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22600 /* 22601 * Sanity check for complex types with simple content. 22602 */ 22603 simpleType = type->contentTypeDef; 22604 if (simpleType == NULL) { 22605 VERROR_INT("xmlSchemaXPathProcessHistory", 22606 "field resolves to a CT with simple content " 22607 "but the CT is missing the ST definition"); 22608 return (-1); 22609 } 22610 } else 22611 simpleType = NULL; 22612 } else 22613 simpleType = type; 22614 if (simpleType == NULL) { 22615 xmlChar *str = NULL; 22616 22617 /* 22618 * Not qualified if the field resolves to a node of non 22619 * simple type. 22620 */ 22621 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22622 XML_SCHEMAV_CVC_IDC, NULL, 22623 WXS_BASIC_CAST sto->matcher->aidc->def, 22624 "The XPath '%s' of a field of %s does evaluate to a node of " 22625 "non-simple type", 22626 sto->sel->xpath, 22627 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22628 FREE_AND_NULL(str); 22629 sto->nbHistory--; 22630 goto deregister_check; 22631 } 22632 22633 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22634 /* 22635 * Failed to provide the normalized value; maybe 22636 * the value was invalid. 22637 */ 22638 VERROR(XML_SCHEMAV_CVC_IDC, 22639 WXS_BASIC_CAST sto->matcher->aidc->def, 22640 "Warning: No precomputed value available, the value " 22641 "was either invalid or something strange happend"); 22642 sto->nbHistory--; 22643 goto deregister_check; 22644 } else { 22645 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22646 xmlSchemaPSVIIDCKeyPtr *keySeq; 22647 int pos, idx; 22648 22649 /* 22650 * The key will be anchored on the matcher's list of 22651 * key-sequences. The position in this list is determined 22652 * by the target node's depth relative to the matcher's 22653 * depth of creation (i.e. the depth of the scope element). 22654 * 22655 * Element Depth Pos List-entries 22656 * <scope> 0 NULL 22657 * <bar> 1 NULL 22658 * <target/> 2 2 target 22659 * <bar> 22660 * </scope> 22661 * 22662 * The size of the list is only dependant on the depth of 22663 * the tree. 22664 * An entry will be NULLed in selector_leave, i.e. when 22665 * we hit the target's 22666 */ 22667 pos = sto->depth - matcher->depth; 22668 idx = sto->sel->index; 22669 22670 /* 22671 * Create/grow the array of key-sequences. 22672 */ 22673 if (matcher->keySeqs == NULL) { 22674 if (pos > 9) 22675 matcher->sizeKeySeqs = pos * 2; 22676 else 22677 matcher->sizeKeySeqs = 10; 22678 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22679 xmlMalloc(matcher->sizeKeySeqs * 22680 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22681 if (matcher->keySeqs == NULL) { 22682 xmlSchemaVErrMemory(NULL, 22683 "allocating an array of key-sequences", 22684 NULL); 22685 return(-1); 22686 } 22687 memset(matcher->keySeqs, 0, 22688 matcher->sizeKeySeqs * 22689 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22690 } else if (pos >= matcher->sizeKeySeqs) { 22691 int i = matcher->sizeKeySeqs; 22692 22693 matcher->sizeKeySeqs *= 2; 22694 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22695 xmlRealloc(matcher->keySeqs, 22696 matcher->sizeKeySeqs * 22697 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22698 if (matcher->keySeqs == NULL) { 22699 xmlSchemaVErrMemory(NULL, 22700 "reallocating an array of key-sequences", 22701 NULL); 22702 return (-1); 22703 } 22704 /* 22705 * The array needs to be NULLed. 22706 * TODO: Use memset? 22707 */ 22708 for (; i < matcher->sizeKeySeqs; i++) 22709 matcher->keySeqs[i] = NULL; 22710 } 22711 22712 /* 22713 * Get/create the key-sequence. 22714 */ 22715 keySeq = matcher->keySeqs[pos]; 22716 if (keySeq == NULL) { 22717 goto create_sequence; 22718 } else if (keySeq[idx] != NULL) { 22719 xmlChar *str = NULL; 22720 /* 22721 * cvc-identity-constraint: 22722 * 3 For each node in the �target node set� all 22723 * of the {fields}, with that node as the context 22724 * node, evaluate to either an empty node-set or 22725 * a node-set with exactly one member, which must 22726 * have a simple type. 22727 * 22728 * The key was already set; report an error. 22729 */ 22730 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22731 XML_SCHEMAV_CVC_IDC, NULL, 22732 WXS_BASIC_CAST matcher->aidc->def, 22733 "The XPath '%s' of a field of %s evaluates to a " 22734 "node-set with more than one member", 22735 sto->sel->xpath, 22736 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22737 FREE_AND_NULL(str); 22738 sto->nbHistory--; 22739 goto deregister_check; 22740 } else 22741 goto create_key; 22742 22743create_sequence: 22744 /* 22745 * Create a key-sequence. 22746 */ 22747 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22748 matcher->aidc->def->nbFields * 22749 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22750 if (keySeq == NULL) { 22751 xmlSchemaVErrMemory(NULL, 22752 "allocating an IDC key-sequence", NULL); 22753 return(-1); 22754 } 22755 memset(keySeq, 0, matcher->aidc->def->nbFields * 22756 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22757 matcher->keySeqs[pos] = keySeq; 22758create_key: 22759 /* 22760 * Create a key once per node only. 22761 */ 22762 if (key == NULL) { 22763 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22764 sizeof(xmlSchemaPSVIIDCKey)); 22765 if (key == NULL) { 22766 xmlSchemaVErrMemory(NULL, 22767 "allocating a IDC key", NULL); 22768 xmlFree(keySeq); 22769 matcher->keySeqs[pos] = NULL; 22770 return(-1); 22771 } 22772 /* 22773 * Consume the compiled value. 22774 */ 22775 key->type = simpleType; 22776 key->val = vctxt->inode->val; 22777 vctxt->inode->val = NULL; 22778 /* 22779 * Store the key in a global list. 22780 */ 22781 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22782 xmlSchemaIDCFreeKey(key); 22783 return (-1); 22784 } 22785 } 22786 keySeq[idx] = key; 22787 } 22788 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22789 22790 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22791 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22792 xmlSchemaPSVIIDCNodePtr ntItem; 22793 xmlSchemaIDCMatcherPtr matcher; 22794 xmlSchemaIDCPtr idc; 22795 xmlSchemaItemListPtr targets; 22796 int pos, i, j, nbKeys; 22797 /* 22798 * Here we have the following scenario: 22799 * An IDC 'selector' state object resolved to a target node, 22800 * during the time this target node was in the 22801 * ancestor-or-self axis, the 'field' state object(s) looked 22802 * out for matching nodes to create a key-sequence for this 22803 * target node. Now we are back to this target node and need 22804 * to put the key-sequence, together with the target node 22805 * itself, into the node-table of the corresponding IDC 22806 * binding. 22807 */ 22808 matcher = sto->matcher; 22809 idc = matcher->aidc->def; 22810 nbKeys = idc->nbFields; 22811 pos = depth - matcher->depth; 22812 /* 22813 * Check if the matcher has any key-sequences at all, plus 22814 * if it has a key-sequence for the current target node. 22815 */ 22816 if ((matcher->keySeqs == NULL) || 22817 (matcher->sizeKeySeqs <= pos)) { 22818 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22819 goto selector_key_error; 22820 else 22821 goto selector_leave; 22822 } 22823 22824 keySeq = &(matcher->keySeqs[pos]); 22825 if (*keySeq == NULL) { 22826 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22827 goto selector_key_error; 22828 else 22829 goto selector_leave; 22830 } 22831 22832 for (i = 0; i < nbKeys; i++) { 22833 if ((*keySeq)[i] == NULL) { 22834 /* 22835 * Not qualified, if not all fields did resolve. 22836 */ 22837 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22838 /* 22839 * All fields of a "key" IDC must resolve. 22840 */ 22841 goto selector_key_error; 22842 } 22843 goto selector_leave; 22844 } 22845 } 22846 /* 22847 * All fields did resolve. 22848 */ 22849 22850 /* 22851 * 4.1 If the {identity-constraint category} is unique(/key), 22852 * then no two members of the �qualified node set� have 22853 * �key-sequences� whose members are pairwise equal, as 22854 * defined by Equal in [XML Schemas: Datatypes]. 22855 * 22856 * Get the IDC binding from the matcher and check for 22857 * duplicate key-sequences. 22858 */ 22859#if 0 22860 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 22861#endif 22862 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 22863 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 22864 (targets->nbItems != 0)) { 22865 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 22866 22867 i = 0; 22868 res = 0; 22869 /* 22870 * Compare the key-sequences, key by key. 22871 */ 22872 do { 22873 bkeySeq = 22874 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 22875 for (j = 0; j < nbKeys; j++) { 22876 ckey = (*keySeq)[j]; 22877 bkey = bkeySeq[j]; 22878 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 22879 if (res == -1) { 22880 return (-1); 22881 } else if (res == 0) { 22882 /* 22883 * One of the keys differs, so the key-sequence 22884 * won't be equal; get out. 22885 */ 22886 break; 22887 } 22888 } 22889 if (res == 1) { 22890 /* 22891 * Duplicate key-sequence found. 22892 */ 22893 break; 22894 } 22895 i++; 22896 } while (i < targets->nbItems); 22897 if (i != targets->nbItems) { 22898 xmlChar *str = NULL, *strB = NULL; 22899 /* 22900 * TODO: Try to report the key-sequence. 22901 */ 22902 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22903 XML_SCHEMAV_CVC_IDC, NULL, 22904 WXS_BASIC_CAST idc, 22905 "Duplicate key-sequence %s in %s", 22906 xmlSchemaFormatIDCKeySequence(vctxt, &str, 22907 (*keySeq), nbKeys), 22908 xmlSchemaGetIDCDesignation(&strB, idc)); 22909 FREE_AND_NULL(str); 22910 FREE_AND_NULL(strB); 22911 goto selector_leave; 22912 } 22913 } 22914 /* 22915 * Add a node-table item to the IDC binding. 22916 */ 22917 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 22918 sizeof(xmlSchemaPSVIIDCNode)); 22919 if (ntItem == NULL) { 22920 xmlSchemaVErrMemory(NULL, 22921 "allocating an IDC node-table item", NULL); 22922 xmlFree(*keySeq); 22923 *keySeq = NULL; 22924 return(-1); 22925 } 22926 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 22927 22928 /* 22929 * Store the node-table item in a global list. 22930 */ 22931 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 22932 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 22933 xmlFree(ntItem); 22934 xmlFree(*keySeq); 22935 *keySeq = NULL; 22936 return (-1); 22937 } 22938 ntItem->nodeQNameID = -1; 22939 } else { 22940 /* 22941 * Save a cached QName for this node on the IDC node, to be 22942 * able to report it, even if the node is not saved. 22943 */ 22944 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 22945 vctxt->inode->localName, vctxt->inode->nsName); 22946 if (ntItem->nodeQNameID == -1) { 22947 xmlFree(ntItem); 22948 xmlFree(*keySeq); 22949 *keySeq = NULL; 22950 return (-1); 22951 } 22952 } 22953 /* 22954 * Init the node-table item: Save the node, position and 22955 * consume the key-sequence. 22956 */ 22957 ntItem->node = vctxt->node; 22958 ntItem->nodeLine = vctxt->inode->nodeLine; 22959 ntItem->keys = *keySeq; 22960 *keySeq = NULL; 22961#if 0 22962 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) { 22963#endif 22964 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 22965 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 22966 /* 22967 * Free the item, since keyref items won't be 22968 * put on a global list. 22969 */ 22970 xmlFree(ntItem->keys); 22971 xmlFree(ntItem); 22972 } 22973 return (-1); 22974 } 22975 22976 goto selector_leave; 22977selector_key_error: 22978 { 22979 xmlChar *str = NULL; 22980 /* 22981 * 4.2.1 (KEY) The �target node set� and the 22982 * �qualified node set� are equal, that is, every 22983 * member of the �target node set� is also a member 22984 * of the �qualified node set� and vice versa. 22985 */ 22986 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22987 XML_SCHEMAV_CVC_IDC, NULL, 22988 WXS_BASIC_CAST idc, 22989 "Not all fields of %s evaluate to a node", 22990 xmlSchemaGetIDCDesignation(&str, idc), NULL); 22991 FREE_AND_NULL(str); 22992 } 22993selector_leave: 22994 /* 22995 * Free the key-sequence if not added to the IDC table. 22996 */ 22997 if ((keySeq != NULL) && (*keySeq != NULL)) { 22998 xmlFree(*keySeq); 22999 *keySeq = NULL; 23000 } 23001 } /* if selector */ 23002 23003 sto->nbHistory--; 23004 23005deregister_check: 23006 /* 23007 * Deregister state objects if they reach the depth of creation. 23008 */ 23009 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23010#ifdef DEBUG_IDC 23011 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23012 sto->sel->xpath); 23013#endif 23014 if (vctxt->xpathStates != sto) { 23015 VERROR_INT("xmlSchemaXPathProcessHistory", 23016 "The state object to be removed is not the first " 23017 "in the list"); 23018 } 23019 nextsto = sto->next; 23020 /* 23021 * Unlink from the list of active XPath state objects. 23022 */ 23023 vctxt->xpathStates = sto->next; 23024 sto->next = vctxt->xpathStatePool; 23025 /* 23026 * Link it to the pool of reusable state objects. 23027 */ 23028 vctxt->xpathStatePool = sto; 23029 sto = nextsto; 23030 } else 23031 sto = sto->next; 23032 } /* while (sto != NULL) */ 23033 return (0); 23034} 23035 23036/** 23037 * xmlSchemaIDCRegisterMatchers: 23038 * @vctxt: the WXS validation context 23039 * @elemDecl: the element declaration 23040 * 23041 * Creates helper objects to evaluate IDC selectors/fields 23042 * successively. 23043 * 23044 * Returns 0 if OK and -1 on internal errors. 23045 */ 23046static int 23047xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23048 xmlSchemaElementPtr elemDecl) 23049{ 23050 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23051 xmlSchemaIDCPtr idc, refIdc; 23052 xmlSchemaIDCAugPtr aidc; 23053 23054 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23055 if (idc == NULL) 23056 return (0); 23057 23058#ifdef DEBUG_IDC 23059 { 23060 xmlChar *str = NULL; 23061 xmlGenericError(xmlGenericErrorContext, 23062 "IDC: REGISTER on %s, depth %d\n", 23063 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23064 vctxt->inode->localName), vctxt->depth); 23065 FREE_AND_NULL(str) 23066 } 23067#endif 23068 if (vctxt->inode->idcMatchers != NULL) { 23069 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23070 "The chain of IDC matchers is expected to be empty"); 23071 return (-1); 23072 } 23073 do { 23074 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23075 /* 23076 * Since IDCs bubbles are expensive we need to know the 23077 * depth at which the bubbles should stop; this will be 23078 * the depth of the top-most keyref IDC. If no keyref 23079 * references a key/unique IDC, the keyrefDepth will 23080 * be -1, indicating that no bubbles are needed. 23081 */ 23082 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23083 if (refIdc != NULL) { 23084 /* 23085 * Remember that we have keyrefs on this node. 23086 */ 23087 vctxt->inode->hasKeyrefs = 1; 23088 /* 23089 * Lookup the referenced augmented IDC info. 23090 */ 23091 aidc = vctxt->aidcs; 23092 while (aidc != NULL) { 23093 if (aidc->def == refIdc) 23094 break; 23095 aidc = aidc->next; 23096 } 23097 if (aidc == NULL) { 23098 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23099 "Could not find an augmented IDC item for an IDC " 23100 "definition"); 23101 return (-1); 23102 } 23103 if ((aidc->keyrefDepth == -1) || 23104 (vctxt->depth < aidc->keyrefDepth)) 23105 aidc->keyrefDepth = vctxt->depth; 23106 } 23107 } 23108 /* 23109 * Lookup the augmented IDC item for the IDC definition. 23110 */ 23111 aidc = vctxt->aidcs; 23112 while (aidc != NULL) { 23113 if (aidc->def == idc) 23114 break; 23115 aidc = aidc->next; 23116 } 23117 if (aidc == NULL) { 23118 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23119 "Could not find an augmented IDC item for an IDC definition"); 23120 return (-1); 23121 } 23122 /* 23123 * Create an IDC matcher for every IDC definition. 23124 */ 23125 if (vctxt->idcMatcherCache != NULL) { 23126 /* 23127 * Reuse a cached matcher. 23128 */ 23129 matcher = vctxt->idcMatcherCache; 23130 vctxt->idcMatcherCache = matcher->nextCached; 23131 matcher->nextCached = NULL; 23132 } else { 23133 matcher = (xmlSchemaIDCMatcherPtr) 23134 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23135 if (matcher == NULL) { 23136 xmlSchemaVErrMemory(vctxt, 23137 "allocating an IDC matcher", NULL); 23138 return (-1); 23139 } 23140 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23141 } 23142 if (last == NULL) 23143 vctxt->inode->idcMatchers = matcher; 23144 else 23145 last->next = matcher; 23146 last = matcher; 23147 23148 matcher->type = IDC_MATCHER; 23149 matcher->depth = vctxt->depth; 23150 matcher->aidc = aidc; 23151 matcher->idcType = aidc->def->type; 23152#ifdef DEBUG_IDC 23153 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23154#endif 23155 /* 23156 * Init the automaton state object. 23157 */ 23158 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23159 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23160 return (-1); 23161 23162 idc = idc->next; 23163 } while (idc != NULL); 23164 return (0); 23165} 23166 23167static int 23168xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23169 xmlSchemaNodeInfoPtr ielem) 23170{ 23171 xmlSchemaPSVIIDCBindingPtr bind; 23172 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23173 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23174 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23175 23176 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23177 /* vctxt->createIDCNodeTables */ 23178 while (matcher != NULL) { 23179 /* 23180 * Skip keyref IDCs and empty IDC target-lists. 23181 */ 23182 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23183 WXS_ILIST_IS_EMPTY(matcher->targets)) 23184 { 23185 matcher = matcher->next; 23186 continue; 23187 } 23188 /* 23189 * If we _want_ the IDC node-table to be created in any case 23190 * then do so. Otherwise create them only if keyrefs need them. 23191 */ 23192 if ((! vctxt->createIDCNodeTables) && 23193 ((matcher->aidc->keyrefDepth == -1) || 23194 (matcher->aidc->keyrefDepth > vctxt->depth))) 23195 { 23196 matcher = matcher->next; 23197 continue; 23198 } 23199 /* 23200 * Get/create the IDC binding on this element for the IDC definition. 23201 */ 23202 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23203 23204 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23205 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23206 nbDupls = bind->dupls->nbItems; 23207 } else { 23208 dupls = NULL; 23209 nbDupls = 0; 23210 } 23211 if (bind->nodeTable != NULL) { 23212 nbNodeTable = bind->nbNodes; 23213 } else { 23214 nbNodeTable = 0; 23215 } 23216 23217 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23218 /* 23219 * Transfer all IDC target-nodes to the IDC node-table. 23220 */ 23221 bind->nodeTable = 23222 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23223 bind->sizeNodes = matcher->targets->sizeItems; 23224 bind->nbNodes = matcher->targets->nbItems; 23225 23226 matcher->targets->items = NULL; 23227 matcher->targets->sizeItems = 0; 23228 matcher->targets->nbItems = 0; 23229 } else { 23230 /* 23231 * Compare the key-sequences and add to the IDC node-table. 23232 */ 23233 nbTargets = matcher->targets->nbItems; 23234 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23235 nbFields = matcher->aidc->def->nbFields; 23236 i = 0; 23237 do { 23238 keys = targets[i]->keys; 23239 if (nbDupls) { 23240 /* 23241 * Search in already found duplicates first. 23242 */ 23243 j = 0; 23244 do { 23245 if (nbFields == 1) { 23246 res = xmlSchemaAreValuesEqual(keys[0]->val, 23247 dupls[j]->keys[0]->val); 23248 if (res == -1) 23249 goto internal_error; 23250 if (res == 1) { 23251 /* 23252 * Equal key-sequence. 23253 */ 23254 goto next_target; 23255 } 23256 } else { 23257 res = 0; 23258 ntkeys = dupls[j]->keys; 23259 for (k = 0; k < nbFields; k++) { 23260 res = xmlSchemaAreValuesEqual(keys[k]->val, 23261 ntkeys[k]->val); 23262 if (res == -1) 23263 goto internal_error; 23264 if (res == 0) { 23265 /* 23266 * One of the keys differs. 23267 */ 23268 break; 23269 } 23270 } 23271 if (res == 1) { 23272 /* 23273 * Equal key-sequence found. 23274 */ 23275 goto next_target; 23276 } 23277 } 23278 j++; 23279 } while (j < nbDupls); 23280 } 23281 if (nbNodeTable) { 23282 j = 0; 23283 do { 23284 if (nbFields == 1) { 23285 res = xmlSchemaAreValuesEqual(keys[0]->val, 23286 bind->nodeTable[j]->keys[0]->val); 23287 if (res == -1) 23288 goto internal_error; 23289 if (res == 0) { 23290 /* 23291 * The key-sequence differs. 23292 */ 23293 goto next_node_table_entry; 23294 } 23295 } else { 23296 res = 0; 23297 ntkeys = bind->nodeTable[j]->keys; 23298 for (k = 0; k < nbFields; k++) { 23299 res = xmlSchemaAreValuesEqual(keys[k]->val, 23300 ntkeys[k]->val); 23301 if (res == -1) 23302 goto internal_error; 23303 if (res == 0) { 23304 /* 23305 * One of the keys differs. 23306 */ 23307 goto next_node_table_entry; 23308 } 23309 } 23310 } 23311 /* 23312 * Add the duplicate to the list of duplicates. 23313 */ 23314 if (bind->dupls == NULL) { 23315 bind->dupls = xmlSchemaItemListCreate(); 23316 if (bind->dupls == NULL) 23317 goto internal_error; 23318 } 23319 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23320 goto internal_error; 23321 /* 23322 * Remove the duplicate entry from the IDC node-table. 23323 */ 23324 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23325 bind->nbNodes--; 23326 23327 goto next_target; 23328 23329next_node_table_entry: 23330 j++; 23331 } while (j < nbNodeTable); 23332 } 23333 /* 23334 * If everything is fine, then add the IDC target-node to 23335 * the IDC node-table. 23336 */ 23337 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23338 goto internal_error; 23339 23340next_target: 23341 i++; 23342 } while (i < nbTargets); 23343 } 23344 matcher = matcher->next; 23345 } 23346 return(0); 23347 23348internal_error: 23349 return(-1); 23350} 23351 23352/** 23353 * xmlSchemaBubbleIDCNodeTables: 23354 * @depth: the current tree depth 23355 * 23356 * Merges IDC bindings of an element at @depth into the corresponding IDC 23357 * bindings of its parent element. If a duplicate note-table entry is found, 23358 * both, the parent node-table entry and child entry are discarded from the 23359 * node-table of the parent. 23360 * 23361 * Returns 0 if OK and -1 on internal errors. 23362 */ 23363static int 23364xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23365{ 23366 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23367 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23368 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23369 xmlSchemaIDCAugPtr aidc; 23370 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23371 23372 bind = vctxt->inode->idcTable; 23373 if (bind == NULL) { 23374 /* Fine, no table, no bubbles. */ 23375 return (0); 23376 } 23377 23378 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23379 /* 23380 * Walk all bindings; create new or add to existing bindings. 23381 * Remove duplicate key-sequences. 23382 */ 23383 while (bind != NULL) { 23384 23385 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23386 goto next_binding; 23387 /* 23388 * Check if the key/unique IDC table needs to be bubbled. 23389 */ 23390 if (! vctxt->createIDCNodeTables) { 23391 aidc = vctxt->aidcs; 23392 do { 23393 if (aidc->def == bind->definition) { 23394 if ((aidc->keyrefDepth == -1) || 23395 (aidc->keyrefDepth >= vctxt->depth)) { 23396 goto next_binding; 23397 } 23398 break; 23399 } 23400 aidc = aidc->next; 23401 } while (aidc != NULL); 23402 } 23403 23404 if (parTable != NULL) 23405 parBind = *parTable; 23406 /* 23407 * Search a matching parent binding for the 23408 * IDC definition. 23409 */ 23410 while (parBind != NULL) { 23411 if (parBind->definition == bind->definition) 23412 break; 23413 parBind = parBind->next; 23414 } 23415 23416 if (parBind != NULL) { 23417 /* 23418 * Compare every node-table entry of the child node, 23419 * i.e. the key-sequence within, ... 23420 */ 23421 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23422 23423 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23424 oldDupls = parBind->dupls->nbItems; 23425 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23426 } else { 23427 dupls = NULL; 23428 oldDupls = 0; 23429 } 23430 23431 parNodes = parBind->nodeTable; 23432 nbFields = bind->definition->nbFields; 23433 23434 for (i = 0; i < bind->nbNodes; i++) { 23435 node = bind->nodeTable[i]; 23436 if (node == NULL) 23437 continue; 23438 /* 23439 * ...with every key-sequence of the parent node, already 23440 * evaluated to be a duplicate key-sequence. 23441 */ 23442 if (oldDupls) { 23443 j = 0; 23444 while (j < oldDupls) { 23445 if (nbFields == 1) { 23446 ret = xmlSchemaAreValuesEqual( 23447 node->keys[0]->val, 23448 dupls[j]->keys[0]->val); 23449 if (ret == -1) 23450 goto internal_error; 23451 if (ret == 0) { 23452 j++; 23453 continue; 23454 } 23455 } else { 23456 parNode = dupls[j]; 23457 for (k = 0; k < nbFields; k++) { 23458 ret = xmlSchemaAreValuesEqual( 23459 node->keys[k]->val, 23460 parNode->keys[k]->val); 23461 if (ret == -1) 23462 goto internal_error; 23463 if (ret == 0) 23464 break; 23465 } 23466 } 23467 if (ret == 1) 23468 /* Duplicate found. */ 23469 break; 23470 j++; 23471 } 23472 if (j != oldDupls) { 23473 /* Duplicate found. Skip this entry. */ 23474 continue; 23475 } 23476 } 23477 /* 23478 * ... and with every key-sequence of the parent node. 23479 */ 23480 if (oldNum) { 23481 j = 0; 23482 while (j < oldNum) { 23483 parNode = parNodes[j]; 23484 if (nbFields == 1) { 23485 ret = xmlSchemaAreValuesEqual( 23486 node->keys[0]->val, 23487 parNode->keys[0]->val); 23488 if (ret == -1) 23489 goto internal_error; 23490 if (ret == 0) { 23491 j++; 23492 continue; 23493 } 23494 } else { 23495 for (k = 0; k < nbFields; k++) { 23496 ret = xmlSchemaAreValuesEqual( 23497 node->keys[k]->val, 23498 parNode->keys[k]->val); 23499 if (ret == -1) 23500 goto internal_error; 23501 if (ret == 0) 23502 break; 23503 } 23504 } 23505 if (ret == 1) 23506 /* Duplicate found. */ 23507 break; 23508 j++; 23509 } 23510 if (j != oldNum) { 23511 /* 23512 * Handle duplicates. Move the duplicate in 23513 * the parent's node-table to the list of 23514 * duplicates. 23515 */ 23516 oldNum--; 23517 parBind->nbNodes--; 23518 /* 23519 * Move last old item to pos of duplicate. 23520 */ 23521 parNodes[j] = parNodes[oldNum]; 23522 23523 if (parBind->nbNodes != oldNum) { 23524 /* 23525 * If new items exist, move last new item to 23526 * last of old items. 23527 */ 23528 parNodes[oldNum] = 23529 parNodes[parBind->nbNodes]; 23530 } 23531 if (parBind->dupls == NULL) { 23532 parBind->dupls = xmlSchemaItemListCreate(); 23533 if (parBind->dupls == NULL) 23534 goto internal_error; 23535 } 23536 xmlSchemaItemListAdd(parBind->dupls, parNode); 23537 } else { 23538 /* 23539 * Add the node-table entry (node and key-sequence) of 23540 * the child node to the node table of the parent node. 23541 */ 23542 if (parBind->nodeTable == NULL) { 23543 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23544 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23545 if (parBind->nodeTable == NULL) { 23546 xmlSchemaVErrMemory(NULL, 23547 "allocating IDC list of node-table items", NULL); 23548 goto internal_error; 23549 } 23550 parBind->sizeNodes = 1; 23551 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23552 parBind->sizeNodes *= 2; 23553 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23554 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23555 sizeof(xmlSchemaPSVIIDCNodePtr)); 23556 if (parBind->nodeTable == NULL) { 23557 xmlSchemaVErrMemory(NULL, 23558 "re-allocating IDC list of node-table items", NULL); 23559 goto internal_error; 23560 } 23561 } 23562 parNodes = parBind->nodeTable; 23563 /* 23564 * Append the new node-table entry to the 'new node-table 23565 * entries' section. 23566 */ 23567 parNodes[parBind->nbNodes++] = node; 23568 } 23569 23570 } 23571 23572 } 23573 } else { 23574 /* 23575 * No binding for the IDC was found: create a new one and 23576 * copy all node-tables. 23577 */ 23578 parBind = xmlSchemaIDCNewBinding(bind->definition); 23579 if (parBind == NULL) 23580 goto internal_error; 23581 23582 /* 23583 * TODO: Hmm, how to optimize the initial number of 23584 * allocated entries? 23585 */ 23586 if (bind->nbNodes != 0) { 23587 /* 23588 * Add all IDC node-table entries. 23589 */ 23590 if (! vctxt->psviExposeIDCNodeTables) { 23591 /* 23592 * Just move the entries. 23593 * NOTE: this is quite save here, since 23594 * all the keyref lookups have already been 23595 * performed. 23596 */ 23597 parBind->nodeTable = bind->nodeTable; 23598 bind->nodeTable = NULL; 23599 parBind->sizeNodes = bind->sizeNodes; 23600 bind->sizeNodes = 0; 23601 parBind->nbNodes = bind->nbNodes; 23602 bind->nbNodes = 0; 23603 } else { 23604 /* 23605 * Copy the entries. 23606 */ 23607 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23608 xmlMalloc(bind->nbNodes * 23609 sizeof(xmlSchemaPSVIIDCNodePtr)); 23610 if (parBind->nodeTable == NULL) { 23611 xmlSchemaVErrMemory(NULL, 23612 "allocating an array of IDC node-table " 23613 "items", NULL); 23614 xmlSchemaIDCFreeBinding(parBind); 23615 goto internal_error; 23616 } 23617 parBind->sizeNodes = bind->nbNodes; 23618 parBind->nbNodes = bind->nbNodes; 23619 memcpy(parBind->nodeTable, bind->nodeTable, 23620 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23621 } 23622 } 23623 if (bind->dupls) { 23624 /* 23625 * Move the duplicates. 23626 */ 23627 if (parBind->dupls != NULL) 23628 xmlSchemaItemListFree(parBind->dupls); 23629 parBind->dupls = bind->dupls; 23630 bind->dupls = NULL; 23631 } 23632 if (*parTable == NULL) 23633 *parTable = parBind; 23634 else { 23635 parBind->next = *parTable; 23636 *parTable = parBind; 23637 } 23638 } 23639 23640next_binding: 23641 bind = bind->next; 23642 } 23643 return (0); 23644 23645internal_error: 23646 return(-1); 23647} 23648 23649/** 23650 * xmlSchemaCheckCVCIDCKeyRef: 23651 * @vctxt: the WXS validation context 23652 * @elemDecl: the element declaration 23653 * 23654 * Check the cvc-idc-keyref constraints. 23655 */ 23656static int 23657xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23658{ 23659 xmlSchemaIDCMatcherPtr matcher; 23660 xmlSchemaPSVIIDCBindingPtr bind; 23661 23662 matcher = vctxt->inode->idcMatchers; 23663 /* 23664 * Find a keyref. 23665 */ 23666 while (matcher != NULL) { 23667 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23668 matcher->targets && 23669 matcher->targets->nbItems) 23670 { 23671 int i, j, k, res, nbFields, hasDupls; 23672 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23673 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23674 23675 nbFields = matcher->aidc->def->nbFields; 23676 23677 /* 23678 * Find the IDC node-table for the referenced IDC key/unique. 23679 */ 23680 bind = vctxt->inode->idcTable; 23681 while (bind != NULL) { 23682 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23683 bind->definition) 23684 break; 23685 bind = bind->next; 23686 } 23687 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23688 /* 23689 * Search for a matching key-sequences. 23690 */ 23691 for (i = 0; i < matcher->targets->nbItems; i++) { 23692 res = 0; 23693 refNode = matcher->targets->items[i]; 23694 if (bind != NULL) { 23695 refKeys = refNode->keys; 23696 for (j = 0; j < bind->nbNodes; j++) { 23697 keys = bind->nodeTable[j]->keys; 23698 for (k = 0; k < nbFields; k++) { 23699 res = xmlSchemaAreValuesEqual(keys[k]->val, 23700 refKeys[k]->val); 23701 if (res == 0) 23702 break; 23703 else if (res == -1) { 23704 return (-1); 23705 } 23706 } 23707 if (res == 1) { 23708 /* 23709 * Match found. 23710 */ 23711 break; 23712 } 23713 } 23714 if ((res == 0) && hasDupls) { 23715 /* 23716 * Search in duplicates 23717 */ 23718 for (j = 0; j < bind->dupls->nbItems; j++) { 23719 keys = ((xmlSchemaPSVIIDCNodePtr) 23720 bind->dupls->items[j])->keys; 23721 for (k = 0; k < nbFields; k++) { 23722 res = xmlSchemaAreValuesEqual(keys[k]->val, 23723 refKeys[k]->val); 23724 if (res == 0) 23725 break; 23726 else if (res == -1) { 23727 return (-1); 23728 } 23729 } 23730 if (res == 1) { 23731 /* 23732 * Match in duplicates found. 23733 */ 23734 xmlChar *str = NULL, *strB = NULL; 23735 xmlSchemaKeyrefErr(vctxt, 23736 XML_SCHEMAV_CVC_IDC, refNode, 23737 (xmlSchemaTypePtr) matcher->aidc->def, 23738 "More than one match found for " 23739 "key-sequence %s of keyref '%s'", 23740 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23741 refNode->keys, nbFields), 23742 xmlSchemaGetComponentQName(&strB, 23743 matcher->aidc->def)); 23744 FREE_AND_NULL(str); 23745 FREE_AND_NULL(strB); 23746 break; 23747 } 23748 } 23749 } 23750 } 23751 23752 if (res == 0) { 23753 xmlChar *str = NULL, *strB = NULL; 23754 xmlSchemaKeyrefErr(vctxt, 23755 XML_SCHEMAV_CVC_IDC, refNode, 23756 (xmlSchemaTypePtr) matcher->aidc->def, 23757 "No match found for key-sequence %s of keyref '%s'", 23758 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23759 refNode->keys, nbFields), 23760 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23761 FREE_AND_NULL(str); 23762 FREE_AND_NULL(strB); 23763 } 23764 } 23765 } 23766 matcher = matcher->next; 23767 } 23768 /* TODO: Return an error if any error encountered. */ 23769 return (0); 23770} 23771 23772/************************************************************************ 23773 * * 23774 * XML Reader validation code * 23775 * * 23776 ************************************************************************/ 23777 23778static xmlSchemaAttrInfoPtr 23779xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23780{ 23781 xmlSchemaAttrInfoPtr iattr; 23782 /* 23783 * Grow/create list of attribute infos. 23784 */ 23785 if (vctxt->attrInfos == NULL) { 23786 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23787 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23788 vctxt->sizeAttrInfos = 1; 23789 if (vctxt->attrInfos == NULL) { 23790 xmlSchemaVErrMemory(vctxt, 23791 "allocating attribute info list", NULL); 23792 return (NULL); 23793 } 23794 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23795 vctxt->sizeAttrInfos++; 23796 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23797 xmlRealloc(vctxt->attrInfos, 23798 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23799 if (vctxt->attrInfos == NULL) { 23800 xmlSchemaVErrMemory(vctxt, 23801 "re-allocating attribute info list", NULL); 23802 return (NULL); 23803 } 23804 } else { 23805 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23806 if (iattr->localName != NULL) { 23807 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23808 "attr info not cleared"); 23809 return (NULL); 23810 } 23811 iattr->nodeType = XML_ATTRIBUTE_NODE; 23812 return (iattr); 23813 } 23814 /* 23815 * Create an attribute info. 23816 */ 23817 iattr = (xmlSchemaAttrInfoPtr) 23818 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23819 if (iattr == NULL) { 23820 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23821 return (NULL); 23822 } 23823 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23824 iattr->nodeType = XML_ATTRIBUTE_NODE; 23825 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23826 23827 return (iattr); 23828} 23829 23830static int 23831xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23832 xmlNodePtr attrNode, 23833 int nodeLine, 23834 const xmlChar *localName, 23835 const xmlChar *nsName, 23836 int ownedNames, 23837 xmlChar *value, 23838 int ownedValue) 23839{ 23840 xmlSchemaAttrInfoPtr attr; 23841 23842 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23843 if (attr == NULL) { 23844 VERROR_INT("xmlSchemaPushAttribute", 23845 "calling xmlSchemaGetFreshAttrInfo()"); 23846 return (-1); 23847 } 23848 attr->node = attrNode; 23849 attr->nodeLine = nodeLine; 23850 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 23851 attr->localName = localName; 23852 attr->nsName = nsName; 23853 if (ownedNames) 23854 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 23855 /* 23856 * Evaluate if it's an XSI attribute. 23857 */ 23858 if (nsName != NULL) { 23859 if (xmlStrEqual(localName, BAD_CAST "nil")) { 23860 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23861 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 23862 } 23863 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 23864 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23865 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 23866 } 23867 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 23868 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23869 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 23870 } 23871 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 23872 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23873 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 23874 } 23875 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 23876 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 23877 } 23878 } 23879 attr->value = value; 23880 if (ownedValue) 23881 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 23882 if (attr->metaType != 0) 23883 attr->state = XML_SCHEMAS_ATTR_META; 23884 return (0); 23885} 23886 23887/** 23888 * xmlSchemaClearElemInfo: 23889 * @vctxt: the WXS validation context 23890 * @ielem: the element information item 23891 */ 23892static void 23893xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 23894 xmlSchemaNodeInfoPtr ielem) 23895{ 23896 ielem->hasKeyrefs = 0; 23897 ielem->appliedXPath = 0; 23898 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 23899 FREE_AND_NULL(ielem->localName); 23900 FREE_AND_NULL(ielem->nsName); 23901 } else { 23902 ielem->localName = NULL; 23903 ielem->nsName = NULL; 23904 } 23905 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 23906 FREE_AND_NULL(ielem->value); 23907 } else { 23908 ielem->value = NULL; 23909 } 23910 if (ielem->val != NULL) { 23911 /* 23912 * PSVI TODO: Be careful not to free it when the value is 23913 * exposed via PSVI. 23914 */ 23915 xmlSchemaFreeValue(ielem->val); 23916 ielem->val = NULL; 23917 } 23918 if (ielem->idcMatchers != NULL) { 23919 /* 23920 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 23921 * Does it work? 23922 */ 23923 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 23924#if 0 23925 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 23926#endif 23927 ielem->idcMatchers = NULL; 23928 } 23929 if (ielem->idcTable != NULL) { 23930 /* 23931 * OPTIMIZE TODO: Use a pool of IDC tables??. 23932 */ 23933 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 23934 ielem->idcTable = NULL; 23935 } 23936 if (ielem->regexCtxt != NULL) { 23937 xmlRegFreeExecCtxt(ielem->regexCtxt); 23938 ielem->regexCtxt = NULL; 23939 } 23940 if (ielem->nsBindings != NULL) { 23941 xmlFree((xmlChar **)ielem->nsBindings); 23942 ielem->nsBindings = NULL; 23943 ielem->nbNsBindings = 0; 23944 ielem->sizeNsBindings = 0; 23945 } 23946} 23947 23948/** 23949 * xmlSchemaGetFreshElemInfo: 23950 * @vctxt: the schema validation context 23951 * 23952 * Creates/reuses and initializes the element info item for 23953 * the currect tree depth. 23954 * 23955 * Returns the element info item or NULL on API or internal errors. 23956 */ 23957static xmlSchemaNodeInfoPtr 23958xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 23959{ 23960 xmlSchemaNodeInfoPtr info = NULL; 23961 23962 if (vctxt->depth > vctxt->sizeElemInfos) { 23963 VERROR_INT("xmlSchemaGetFreshElemInfo", 23964 "inconsistent depth encountered"); 23965 return (NULL); 23966 } 23967 if (vctxt->elemInfos == NULL) { 23968 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 23969 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 23970 if (vctxt->elemInfos == NULL) { 23971 xmlSchemaVErrMemory(vctxt, 23972 "allocating the element info array", NULL); 23973 return (NULL); 23974 } 23975 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 23976 vctxt->sizeElemInfos = 10; 23977 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 23978 int i = vctxt->sizeElemInfos; 23979 23980 vctxt->sizeElemInfos *= 2; 23981 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 23982 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 23983 sizeof(xmlSchemaNodeInfoPtr)); 23984 if (vctxt->elemInfos == NULL) { 23985 xmlSchemaVErrMemory(vctxt, 23986 "re-allocating the element info array", NULL); 23987 return (NULL); 23988 } 23989 /* 23990 * We need the new memory to be NULLed. 23991 * TODO: Use memset instead? 23992 */ 23993 for (; i < vctxt->sizeElemInfos; i++) 23994 vctxt->elemInfos[i] = NULL; 23995 } else 23996 info = vctxt->elemInfos[vctxt->depth]; 23997 23998 if (info == NULL) { 23999 info = (xmlSchemaNodeInfoPtr) 24000 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24001 if (info == NULL) { 24002 xmlSchemaVErrMemory(vctxt, 24003 "allocating an element info", NULL); 24004 return (NULL); 24005 } 24006 vctxt->elemInfos[vctxt->depth] = info; 24007 } else { 24008 if (info->localName != NULL) { 24009 VERROR_INT("xmlSchemaGetFreshElemInfo", 24010 "elem info has not been cleared"); 24011 return (NULL); 24012 } 24013 } 24014 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24015 info->nodeType = XML_ELEMENT_NODE; 24016 info->depth = vctxt->depth; 24017 24018 return (info); 24019} 24020 24021#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24022#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24023#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24024 24025static int 24026xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24027 xmlNodePtr node, 24028 xmlSchemaTypePtr type, 24029 xmlSchemaValType valType, 24030 const xmlChar * value, 24031 xmlSchemaValPtr val, 24032 unsigned long length, 24033 int fireErrors) 24034{ 24035 int ret, error = 0; 24036 24037 xmlSchemaTypePtr tmpType; 24038 xmlSchemaFacetLinkPtr facetLink; 24039 xmlSchemaFacetPtr facet; 24040 unsigned long len = 0; 24041 xmlSchemaWhitespaceValueType ws; 24042 24043 /* 24044 * In Libxml2, derived built-in types have currently no explicit facets. 24045 */ 24046 if (type->type == XML_SCHEMA_TYPE_BASIC) 24047 return (0); 24048 24049 /* 24050 * NOTE: Do not jump away, if the facetSet of the given type is 24051 * empty: until now, "pattern" and "enumeration" facets of the 24052 * *base types* need to be checked as well. 24053 */ 24054 if (type->facetSet == NULL) 24055 goto pattern_and_enum; 24056 24057 if (! WXS_IS_ATOMIC(type)) { 24058 if (WXS_IS_LIST(type)) 24059 goto WXS_IS_LIST; 24060 else 24061 goto pattern_and_enum; 24062 } 24063 /* 24064 * Whitespace handling is only of importance for string-based 24065 * types. 24066 */ 24067 tmpType = xmlSchemaGetPrimitiveType(type); 24068 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24069 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24070 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24071 } else 24072 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24073 /* 24074 * If the value was not computed (for string or 24075 * anySimpleType based types), then use the provided 24076 * type. 24077 */ 24078 if (val == NULL) 24079 valType = valType; 24080 else 24081 valType = xmlSchemaGetValType(val); 24082 24083 ret = 0; 24084 for (facetLink = type->facetSet; facetLink != NULL; 24085 facetLink = facetLink->next) { 24086 /* 24087 * Skip the pattern "whiteSpace": it is used to 24088 * format the character content beforehand. 24089 */ 24090 switch (facetLink->facet->type) { 24091 case XML_SCHEMA_FACET_WHITESPACE: 24092 case XML_SCHEMA_FACET_PATTERN: 24093 case XML_SCHEMA_FACET_ENUMERATION: 24094 continue; 24095 case XML_SCHEMA_FACET_LENGTH: 24096 case XML_SCHEMA_FACET_MINLENGTH: 24097 case XML_SCHEMA_FACET_MAXLENGTH: 24098 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24099 valType, value, val, &len, ws); 24100 break; 24101 default: 24102 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24103 valType, value, val, ws); 24104 break; 24105 } 24106 if (ret < 0) { 24107 AERROR_INT("xmlSchemaValidateFacets", 24108 "validating against a atomic type facet"); 24109 return (-1); 24110 } else if (ret > 0) { 24111 if (fireErrors) 24112 xmlSchemaFacetErr(actxt, ret, node, 24113 value, len, type, facetLink->facet, NULL, NULL, NULL); 24114 else 24115 return (ret); 24116 if (error == 0) 24117 error = ret; 24118 } 24119 ret = 0; 24120 } 24121 24122WXS_IS_LIST: 24123 if (! WXS_IS_LIST(type)) 24124 goto pattern_and_enum; 24125 /* 24126 * "length", "minLength" and "maxLength" of list types. 24127 */ 24128 ret = 0; 24129 for (facetLink = type->facetSet; facetLink != NULL; 24130 facetLink = facetLink->next) { 24131 24132 switch (facetLink->facet->type) { 24133 case XML_SCHEMA_FACET_LENGTH: 24134 case XML_SCHEMA_FACET_MINLENGTH: 24135 case XML_SCHEMA_FACET_MAXLENGTH: 24136 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24137 value, length, NULL); 24138 break; 24139 default: 24140 continue; 24141 } 24142 if (ret < 0) { 24143 AERROR_INT("xmlSchemaValidateFacets", 24144 "validating against a list type facet"); 24145 return (-1); 24146 } else if (ret > 0) { 24147 if (fireErrors) 24148 xmlSchemaFacetErr(actxt, ret, node, 24149 value, length, type, facetLink->facet, NULL, NULL, NULL); 24150 else 24151 return (ret); 24152 if (error == 0) 24153 error = ret; 24154 } 24155 ret = 0; 24156 } 24157 24158pattern_and_enum: 24159 if (error >= 0) { 24160 int found = 0; 24161 /* 24162 * Process enumerations. Facet values are in the value space 24163 * of the defining type's base type. This seems to be a bug in the 24164 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24165 * Only the first set of enumerations in the ancestor-or-self axis 24166 * is used for validation. 24167 */ 24168 ret = 0; 24169 tmpType = type; 24170 do { 24171 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24172 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24173 continue; 24174 found = 1; 24175 ret = xmlSchemaAreValuesEqual(facet->val, val); 24176 if (ret == 1) 24177 break; 24178 else if (ret < 0) { 24179 AERROR_INT("xmlSchemaValidateFacets", 24180 "validating against an enumeration facet"); 24181 return (-1); 24182 } 24183 } 24184 if (ret != 0) 24185 break; 24186 /* 24187 * Break on the first set of enumerations. Any additional 24188 * enumerations which might be existent on the ancestors 24189 * of the current type are restricted by this set; thus 24190 * *must* *not* be taken into account. 24191 */ 24192 if (found) 24193 break; 24194 tmpType = tmpType->baseType; 24195 } while ((tmpType != NULL) && 24196 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24197 if (found && (ret == 0)) { 24198 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24199 if (fireErrors) { 24200 xmlSchemaFacetErr(actxt, ret, node, 24201 value, 0, type, NULL, NULL, NULL, NULL); 24202 } else 24203 return (ret); 24204 if (error == 0) 24205 error = ret; 24206 } 24207 } 24208 24209 if (error >= 0) { 24210 int found; 24211 /* 24212 * Process patters. Pattern facets are ORed at type level 24213 * and ANDed if derived. Walk the base type axis. 24214 */ 24215 tmpType = type; 24216 facet = NULL; 24217 do { 24218 found = 0; 24219 for (facetLink = tmpType->facetSet; facetLink != NULL; 24220 facetLink = facetLink->next) { 24221 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24222 continue; 24223 found = 1; 24224 /* 24225 * NOTE that for patterns, @value needs to be the 24226 * normalized vaule. 24227 */ 24228 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24229 if (ret == 1) 24230 break; 24231 else if (ret < 0) { 24232 AERROR_INT("xmlSchemaValidateFacets", 24233 "validating against a pattern facet"); 24234 return (-1); 24235 } else { 24236 /* 24237 * Save the last non-validating facet. 24238 */ 24239 facet = facetLink->facet; 24240 } 24241 } 24242 if (found && (ret != 1)) { 24243 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24244 if (fireErrors) { 24245 xmlSchemaFacetErr(actxt, ret, node, 24246 value, 0, type, facet, NULL, NULL, NULL); 24247 } else 24248 return (ret); 24249 if (error == 0) 24250 error = ret; 24251 break; 24252 } 24253 tmpType = tmpType->baseType; 24254 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24255 } 24256 24257 return (error); 24258} 24259 24260static xmlChar * 24261xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24262 const xmlChar *value) 24263{ 24264 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24265 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24266 return (xmlSchemaCollapseString(value)); 24267 case XML_SCHEMA_WHITESPACE_REPLACE: 24268 return (xmlSchemaWhiteSpaceReplace(value)); 24269 default: 24270 return (NULL); 24271 } 24272} 24273 24274static int 24275xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24276 const xmlChar *value, 24277 xmlSchemaValPtr *val, 24278 int valNeeded) 24279{ 24280 int ret; 24281 const xmlChar *nsName; 24282 xmlChar *local, *prefix = NULL; 24283 24284 ret = xmlValidateQName(value, 1); 24285 if (ret != 0) { 24286 if (ret == -1) { 24287 VERROR_INT("xmlSchemaValidateQName", 24288 "calling xmlValidateQName()"); 24289 return (-1); 24290 } 24291 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24292 } 24293 /* 24294 * NOTE: xmlSplitQName2 will always return a duplicated 24295 * strings. 24296 */ 24297 local = xmlSplitQName2(value, &prefix); 24298 if (local == NULL) 24299 local = xmlStrdup(value); 24300 /* 24301 * OPTIMIZE TODO: Use flags for: 24302 * - is there any namespace binding? 24303 * - is there a default namespace? 24304 */ 24305 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24306 24307 if (prefix != NULL) { 24308 xmlFree(prefix); 24309 /* 24310 * A namespace must be found if the prefix is 24311 * NOT NULL. 24312 */ 24313 if (nsName == NULL) { 24314 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24315 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24316 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24317 "The QName value '%s' has no " 24318 "corresponding namespace declaration in " 24319 "scope", value, NULL); 24320 if (local != NULL) 24321 xmlFree(local); 24322 return (ret); 24323 } 24324 } 24325 if (valNeeded && val) { 24326 if (nsName != NULL) 24327 *val = xmlSchemaNewQNameValue( 24328 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24329 else 24330 *val = xmlSchemaNewQNameValue(NULL, 24331 BAD_CAST local); 24332 } else 24333 xmlFree(local); 24334 return (0); 24335} 24336 24337/* 24338* cvc-simple-type 24339*/ 24340static int 24341xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24342 xmlNodePtr node, 24343 xmlSchemaTypePtr type, 24344 const xmlChar *value, 24345 xmlSchemaValPtr *retVal, 24346 int fireErrors, 24347 int normalize, 24348 int isNormalized) 24349{ 24350 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24351 xmlSchemaValPtr val = NULL; 24352 /* xmlSchemaWhitespaceValueType ws; */ 24353 xmlChar *normValue = NULL; 24354 24355#define NORMALIZE(atype) \ 24356 if ((! isNormalized) && \ 24357 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24358 normValue = xmlSchemaNormalizeValue(atype, value); \ 24359 if (normValue != NULL) \ 24360 value = normValue; \ 24361 isNormalized = 1; \ 24362 } 24363 24364 if ((retVal != NULL) && (*retVal != NULL)) { 24365 xmlSchemaFreeValue(*retVal); 24366 *retVal = NULL; 24367 } 24368 /* 24369 * 3.14.4 Simple Type Definition Validation Rules 24370 * Validation Rule: String Valid 24371 */ 24372 /* 24373 * 1 It is schema-valid with respect to that definition as defined 24374 * by Datatype Valid in [XML Schemas: Datatypes]. 24375 */ 24376 /* 24377 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24378 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then 24379 * the string must be a �declared entity name�. 24380 */ 24381 /* 24382 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24383 * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), 24384 * then every whitespace-delimited substring of the string must be a �declared 24385 * entity name�. 24386 */ 24387 /* 24388 * 2.3 otherwise no further condition applies. 24389 */ 24390 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24391 valNeeded = 1; 24392 if (value == NULL) 24393 value = BAD_CAST ""; 24394 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24395 xmlSchemaTypePtr biType; /* The built-in type. */ 24396 /* 24397 * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match� 24398 * a literal in the �lexical space� of {base type definition}" 24399 */ 24400 /* 24401 * Whitespace-normalize. 24402 */ 24403 NORMALIZE(type); 24404 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24405 /* 24406 * Get the built-in type. 24407 */ 24408 biType = type->baseType; 24409 while ((biType != NULL) && 24410 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24411 biType = biType->baseType; 24412 24413 if (biType == NULL) { 24414 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24415 "could not get the built-in type"); 24416 goto internal_error; 24417 } 24418 } else 24419 biType = type; 24420 /* 24421 * NOTATIONs need to be processed here, since they need 24422 * to lookup in the hashtable of NOTATION declarations of the schema. 24423 */ 24424 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24425 switch (biType->builtInType) { 24426 case XML_SCHEMAS_NOTATION: 24427 ret = xmlSchemaValidateNotation( 24428 (xmlSchemaValidCtxtPtr) actxt, 24429 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24430 NULL, value, &val, valNeeded); 24431 break; 24432 case XML_SCHEMAS_QNAME: 24433 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24434 value, &val, valNeeded); 24435 break; 24436 default: 24437 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24438 if (valNeeded) 24439 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24440 value, &val, NULL); 24441 else 24442 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24443 value, NULL, NULL); 24444 break; 24445 } 24446 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24447 switch (biType->builtInType) { 24448 case XML_SCHEMAS_NOTATION: 24449 ret = xmlSchemaValidateNotation(NULL, 24450 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24451 value, &val, valNeeded); 24452 break; 24453 default: 24454 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24455 if (valNeeded) 24456 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24457 value, &val, node); 24458 else 24459 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24460 value, NULL, node); 24461 break; 24462 } 24463 } else { 24464 /* 24465 * Validation via a public API is not implemented yet. 24466 */ 24467 TODO 24468 goto internal_error; 24469 } 24470 if (ret != 0) { 24471 if (ret < 0) { 24472 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24473 "validating against a built-in type"); 24474 goto internal_error; 24475 } 24476 if (WXS_IS_LIST(type)) 24477 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24478 else 24479 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24480 } 24481 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24482 /* 24483 * Check facets. 24484 */ 24485 ret = xmlSchemaValidateFacets(actxt, node, type, 24486 (xmlSchemaValType) biType->builtInType, value, val, 24487 0, fireErrors); 24488 if (ret != 0) { 24489 if (ret < 0) { 24490 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24491 "validating facets of atomic simple type"); 24492 goto internal_error; 24493 } 24494 if (WXS_IS_LIST(type)) 24495 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24496 else 24497 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24498 } 24499 } 24500 if (fireErrors && (ret > 0)) 24501 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24502 } else if (WXS_IS_LIST(type)) { 24503 24504 xmlSchemaTypePtr itemType; 24505 const xmlChar *cur, *end; 24506 xmlChar *tmpValue = NULL; 24507 unsigned long len = 0; 24508 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24509 /* 1.2.2 if {variety} is �list� then the string must be a sequence 24510 * of white space separated tokens, each of which �match�es a literal 24511 * in the �lexical space� of {item type definition} 24512 */ 24513 /* 24514 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24515 * the list type has an enum or pattern facet. 24516 */ 24517 NORMALIZE(type); 24518 /* 24519 * VAL TODO: Optimize validation of empty values. 24520 * VAL TODO: We do not have computed values for lists. 24521 */ 24522 itemType = WXS_LIST_ITEMTYPE(type); 24523 cur = value; 24524 do { 24525 while (IS_BLANK_CH(*cur)) 24526 cur++; 24527 end = cur; 24528 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24529 end++; 24530 if (end == cur) 24531 break; 24532 tmpValue = xmlStrndup(cur, end - cur); 24533 len++; 24534 24535 if (valNeeded) 24536 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24537 tmpValue, &curVal, fireErrors, 0, 1); 24538 else 24539 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24540 tmpValue, NULL, fireErrors, 0, 1); 24541 FREE_AND_NULL(tmpValue); 24542 if (curVal != NULL) { 24543 /* 24544 * Add to list of computed values. 24545 */ 24546 if (val == NULL) 24547 val = curVal; 24548 else 24549 xmlSchemaValueAppend(prevVal, curVal); 24550 prevVal = curVal; 24551 curVal = NULL; 24552 } 24553 if (ret != 0) { 24554 if (ret < 0) { 24555 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24556 "validating an item of list simple type"); 24557 goto internal_error; 24558 } 24559 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24560 break; 24561 } 24562 cur = end; 24563 } while (*cur != 0); 24564 FREE_AND_NULL(tmpValue); 24565 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24566 /* 24567 * Apply facets (pattern, enumeration). 24568 */ 24569 ret = xmlSchemaValidateFacets(actxt, node, type, 24570 XML_SCHEMAS_UNKNOWN, value, val, 24571 len, fireErrors); 24572 if (ret != 0) { 24573 if (ret < 0) { 24574 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24575 "validating facets of list simple type"); 24576 goto internal_error; 24577 } 24578 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24579 } 24580 } 24581 if (fireErrors && (ret > 0)) { 24582 /* 24583 * Report the normalized value. 24584 */ 24585 normalize = 1; 24586 NORMALIZE(type); 24587 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24588 } 24589 } else if (WXS_IS_UNION(type)) { 24590 xmlSchemaTypeLinkPtr memberLink; 24591 /* 24592 * TODO: For all datatypes �derived� by �union� whiteSpace does 24593 * not apply directly; however, the normalization behavior of �union� 24594 * types is controlled by the value of whiteSpace on that one of the 24595 * �memberTypes� against which the �union� is successfully validated. 24596 * 24597 * This means that the value is normalized by the first validating 24598 * member type, then the facets of the union type are applied. This 24599 * needs changing of the value! 24600 */ 24601 24602 /* 24603 * 1.2.3 if {variety} is �union� then the string must �match� a 24604 * literal in the �lexical space� of at least one member of 24605 * {member type definitions} 24606 */ 24607 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24608 if (memberLink == NULL) { 24609 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24610 "union simple type has no member types"); 24611 goto internal_error; 24612 } 24613 /* 24614 * Always normalize union type values, since we currently 24615 * cannot store the whitespace information with the value 24616 * itself; otherwise a later value-comparison would be 24617 * not possible. 24618 */ 24619 while (memberLink != NULL) { 24620 if (valNeeded) 24621 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24622 memberLink->type, value, &val, 0, 1, 0); 24623 else 24624 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24625 memberLink->type, value, NULL, 0, 1, 0); 24626 if (ret <= 0) 24627 break; 24628 memberLink = memberLink->next; 24629 } 24630 if (ret != 0) { 24631 if (ret < 0) { 24632 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24633 "validating members of union simple type"); 24634 goto internal_error; 24635 } 24636 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24637 } 24638 /* 24639 * Apply facets (pattern, enumeration). 24640 */ 24641 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24642 /* 24643 * The normalization behavior of �union� types is controlled by 24644 * the value of whiteSpace on that one of the �memberTypes� 24645 * against which the �union� is successfully validated. 24646 */ 24647 NORMALIZE(memberLink->type); 24648 ret = xmlSchemaValidateFacets(actxt, node, type, 24649 XML_SCHEMAS_UNKNOWN, value, val, 24650 0, fireErrors); 24651 if (ret != 0) { 24652 if (ret < 0) { 24653 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24654 "validating facets of union simple type"); 24655 goto internal_error; 24656 } 24657 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24658 } 24659 } 24660 if (fireErrors && (ret > 0)) 24661 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24662 } 24663 24664 if (normValue != NULL) 24665 xmlFree(normValue); 24666 if (ret == 0) { 24667 if (retVal != NULL) 24668 *retVal = val; 24669 else if (val != NULL) 24670 xmlSchemaFreeValue(val); 24671 } else if (val != NULL) 24672 xmlSchemaFreeValue(val); 24673 return (ret); 24674internal_error: 24675 if (normValue != NULL) 24676 xmlFree(normValue); 24677 if (val != NULL) 24678 xmlSchemaFreeValue(val); 24679 return (-1); 24680} 24681 24682static int 24683xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24684 const xmlChar *value, 24685 const xmlChar **nsName, 24686 const xmlChar **localName) 24687{ 24688 int ret = 0; 24689 24690 if ((nsName == NULL) || (localName == NULL)) 24691 return (-1); 24692 *nsName = NULL; 24693 *localName = NULL; 24694 24695 ret = xmlValidateQName(value, 1); 24696 if (ret == -1) 24697 return (-1); 24698 if (ret > 0) { 24699 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24700 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24701 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24702 return (1); 24703 } 24704 { 24705 xmlChar *local = NULL; 24706 xmlChar *prefix; 24707 24708 /* 24709 * NOTE: xmlSplitQName2 will return a duplicated 24710 * string. 24711 */ 24712 local = xmlSplitQName2(value, &prefix); 24713 if (local == NULL) 24714 *localName = xmlDictLookup(vctxt->dict, value, -1); 24715 else { 24716 *localName = xmlDictLookup(vctxt->dict, local, -1); 24717 xmlFree(local); 24718 } 24719 24720 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24721 24722 if (prefix != NULL) { 24723 xmlFree(prefix); 24724 /* 24725 * A namespace must be found if the prefix is NOT NULL. 24726 */ 24727 if (*nsName == NULL) { 24728 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24729 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24730 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24731 "The QName value '%s' has no " 24732 "corresponding namespace declaration in scope", 24733 value, NULL); 24734 return (2); 24735 } 24736 } 24737 } 24738 return (0); 24739} 24740 24741static int 24742xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24743 xmlSchemaAttrInfoPtr iattr, 24744 xmlSchemaTypePtr *localType, 24745 xmlSchemaElementPtr elemDecl) 24746{ 24747 int ret = 0; 24748 /* 24749 * cvc-elt (3.3.4) : (4) 24750 * AND 24751 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24752 * (1.2.1.2.1) - (1.2.1.2.4) 24753 * Handle 'xsi:type'. 24754 */ 24755 if (localType == NULL) 24756 return (-1); 24757 *localType = NULL; 24758 if (iattr == NULL) 24759 return (0); 24760 else { 24761 const xmlChar *nsName = NULL, *local = NULL; 24762 /* 24763 * TODO: We should report a *warning* that the type was overriden 24764 * by the instance. 24765 */ 24766 ACTIVATE_ATTRIBUTE(iattr); 24767 /* 24768 * (cvc-elt) (3.3.4) : (4.1) 24769 * (cvc-assess-elt) (1.2.1.2.2) 24770 */ 24771 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24772 &nsName, &local); 24773 if (ret != 0) { 24774 if (ret < 0) { 24775 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24776 "calling xmlSchemaQNameExpand() to validate the " 24777 "attribute 'xsi:type'"); 24778 goto internal_error; 24779 } 24780 goto exit; 24781 } 24782 /* 24783 * (cvc-elt) (3.3.4) : (4.2) 24784 * (cvc-assess-elt) (1.2.1.2.3) 24785 */ 24786 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24787 if (*localType == NULL) { 24788 xmlChar *str = NULL; 24789 24790 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24791 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24792 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24793 "The QName value '%s' of the xsi:type attribute does not " 24794 "resolve to a type definition", 24795 xmlSchemaFormatQName(&str, nsName, local), NULL); 24796 FREE_AND_NULL(str); 24797 ret = vctxt->err; 24798 goto exit; 24799 } 24800 if (elemDecl != NULL) { 24801 int set = 0; 24802 24803 /* 24804 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24805 * "The �local type definition� must be validly 24806 * derived from the {type definition} given the union of 24807 * the {disallowed substitutions} and the {type definition}'s 24808 * {prohibited substitutions}, as defined in 24809 * Type Derivation OK (Complex) (�3.4.6) 24810 * (if it is a complex type definition), 24811 * or given {disallowed substitutions} as defined in Type 24812 * Derivation OK (Simple) (�3.14.6) (if it is a simple type 24813 * definition)." 24814 * 24815 * {disallowed substitutions}: the "block" on the element decl. 24816 * {prohibited substitutions}: the "block" on the type def. 24817 */ 24818 /* 24819 * OPTIMIZE TODO: We could map types already evaluated 24820 * to be validly derived from other types to avoid checking 24821 * this over and over for the same types. 24822 */ 24823 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24824 (elemDecl->subtypes->flags & 24825 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24826 set |= SUBSET_EXTENSION; 24827 24828 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24829 (elemDecl->subtypes->flags & 24830 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24831 set |= SUBSET_RESTRICTION; 24832 24833 /* 24834 * REMOVED and CHANGED since this produced a parser context 24835 * which adds to the string dict of the schema. So this would 24836 * change the schema and we don't want this. We don't need 24837 * the parser context anymore. 24838 * 24839 * if ((vctxt->pctxt == NULL) && 24840 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24841 * return (-1); 24842 */ 24843 24844 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24845 elemDecl->subtypes, set) != 0) { 24846 xmlChar *str = NULL; 24847 24848 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24849 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 24850 "The type definition '%s', specified by xsi:type, is " 24851 "blocked or not validly derived from the type definition " 24852 "of the element declaration", 24853 xmlSchemaFormatQName(&str, 24854 (*localType)->targetNamespace, 24855 (*localType)->name), 24856 NULL); 24857 FREE_AND_NULL(str); 24858 ret = vctxt->err; 24859 *localType = NULL; 24860 } 24861 } 24862 } 24863exit: 24864 ACTIVATE_ELEM; 24865 return (ret); 24866internal_error: 24867 ACTIVATE_ELEM; 24868 return (-1); 24869} 24870 24871static int 24872xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 24873{ 24874 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 24875 xmlSchemaTypePtr actualType; 24876 24877 /* 24878 * cvc-elt (3.3.4) : 1 24879 */ 24880 if (elemDecl == NULL) { 24881 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 24882 "No matching declaration available"); 24883 return (vctxt->err); 24884 } 24885 actualType = WXS_ELEM_TYPEDEF(elemDecl); 24886 /* 24887 * cvc-elt (3.3.4) : 2 24888 */ 24889 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 24890 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 24891 "The element declaration is abstract"); 24892 return (vctxt->err); 24893 } 24894 if (actualType == NULL) { 24895 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 24896 "The type definition is absent"); 24897 return (XML_SCHEMAV_CVC_TYPE_1); 24898 } 24899 if (vctxt->nbAttrInfos != 0) { 24900 int ret; 24901 xmlSchemaAttrInfoPtr iattr; 24902 /* 24903 * cvc-elt (3.3.4) : 3 24904 * Handle 'xsi:nil'. 24905 */ 24906 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 24907 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 24908 if (iattr) { 24909 ACTIVATE_ATTRIBUTE(iattr); 24910 /* 24911 * Validate the value. 24912 */ 24913 ret = xmlSchemaVCheckCVCSimpleType( 24914 ACTXT_CAST vctxt, NULL, 24915 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 24916 iattr->value, &(iattr->val), 1, 0, 0); 24917 ACTIVATE_ELEM; 24918 if (ret < 0) { 24919 VERROR_INT("xmlSchemaValidateElemDecl", 24920 "calling xmlSchemaVCheckCVCSimpleType() to " 24921 "validate the attribute 'xsi:nil'"); 24922 return (-1); 24923 } 24924 if (ret == 0) { 24925 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 24926 /* 24927 * cvc-elt (3.3.4) : 3.1 24928 */ 24929 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 24930 "The element is not 'nillable'"); 24931 /* Does not return an error on purpose. */ 24932 } else { 24933 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 24934 /* 24935 * cvc-elt (3.3.4) : 3.2.2 24936 */ 24937 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 24938 (elemDecl->value != NULL)) { 24939 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 24940 "The element cannot be 'nilled' because " 24941 "there is a fixed value constraint defined " 24942 "for it"); 24943 /* Does not return an error on purpose. */ 24944 } else 24945 vctxt->inode->flags |= 24946 XML_SCHEMA_ELEM_INFO_NILLED; 24947 } 24948 } 24949 } 24950 } 24951 /* 24952 * cvc-elt (3.3.4) : 4 24953 * Handle 'xsi:type'. 24954 */ 24955 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 24956 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 24957 if (iattr) { 24958 xmlSchemaTypePtr localType = NULL; 24959 24960 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 24961 elemDecl); 24962 if (ret != 0) { 24963 if (ret == -1) { 24964 VERROR_INT("xmlSchemaValidateElemDecl", 24965 "calling xmlSchemaProcessXSIType() to " 24966 "process the attribute 'xsi:type'"); 24967 return (-1); 24968 } 24969 /* Does not return an error on purpose. */ 24970 } 24971 if (localType != NULL) { 24972 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 24973 actualType = localType; 24974 } 24975 } 24976 } 24977 /* 24978 * IDC: Register identity-constraint XPath matchers. 24979 */ 24980 if ((elemDecl->idcs != NULL) && 24981 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 24982 return (-1); 24983 /* 24984 * No actual type definition. 24985 */ 24986 if (actualType == NULL) { 24987 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 24988 "The type definition is absent"); 24989 return (XML_SCHEMAV_CVC_TYPE_1); 24990 } 24991 /* 24992 * Remember the actual type definition. 24993 */ 24994 vctxt->inode->typeDef = actualType; 24995 24996 return (0); 24997} 24998 24999static int 25000xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25001{ 25002 xmlSchemaAttrInfoPtr iattr; 25003 int ret = 0, i; 25004 25005 /* 25006 * SPEC cvc-type (3.1.1) 25007 * "The attributes of must be empty, excepting those whose namespace 25008 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25009 * whose local name is one of type, nil, schemaLocation or 25010 * noNamespaceSchemaLocation." 25011 */ 25012 if (vctxt->nbAttrInfos == 0) 25013 return (0); 25014 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25015 iattr = vctxt->attrInfos[i]; 25016 if (! iattr->metaType) { 25017 ACTIVATE_ATTRIBUTE(iattr) 25018 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25019 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25020 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25021 } 25022 } 25023 ACTIVATE_ELEM 25024 return (ret); 25025} 25026 25027/* 25028* Cleanup currently used attribute infos. 25029*/ 25030static void 25031xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25032{ 25033 int i; 25034 xmlSchemaAttrInfoPtr attr; 25035 25036 if (vctxt->nbAttrInfos == 0) 25037 return; 25038 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25039 attr = vctxt->attrInfos[i]; 25040 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25041 if (attr->localName != NULL) 25042 xmlFree((xmlChar *) attr->localName); 25043 if (attr->nsName != NULL) 25044 xmlFree((xmlChar *) attr->nsName); 25045 } 25046 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25047 if (attr->value != NULL) 25048 xmlFree((xmlChar *) attr->value); 25049 } 25050 if (attr->val != NULL) { 25051 xmlSchemaFreeValue(attr->val); 25052 attr->val = NULL; 25053 } 25054 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25055 } 25056 vctxt->nbAttrInfos = 0; 25057} 25058 25059/* 25060* 3.4.4 Complex Type Definition Validation Rules 25061* Element Locally Valid (Complex Type) (cvc-complex-type) 25062* 3.2.4 Attribute Declaration Validation Rules 25063* Validation Rule: Attribute Locally Valid (cvc-attribute) 25064* Attribute Locally Valid (Use) (cvc-au) 25065* 25066* Only "assessed" attribute information items will be visible to 25067* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25068*/ 25069static int 25070xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25071{ 25072 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25073 xmlSchemaItemListPtr attrUseList; 25074 xmlSchemaAttributeUsePtr attrUse = NULL; 25075 xmlSchemaAttributePtr attrDecl = NULL; 25076 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25077 int i, j, found, nbAttrs, nbUses; 25078 int xpathRes = 0, res, wildIDs = 0, fixed; 25079 xmlNodePtr defAttrOwnerElem = NULL; 25080 25081 /* 25082 * SPEC (cvc-attribute) 25083 * (1) "The declaration must not be �absent� (see Missing 25084 * Sub-components (�5.3) for how this can fail to be 25085 * the case)." 25086 * (2) "Its {type definition} must not be absent." 25087 * 25088 * NOTE (1) + (2): This is not handled here, since we currently do not 25089 * allow validation against schemas which have missing sub-components. 25090 * 25091 * SPEC (cvc-complex-type) 25092 * (3) "For each attribute information item in the element information 25093 * item's [attributes] excepting those whose [namespace name] is 25094 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25095 * [local name] is one of type, nil, schemaLocation or 25096 * noNamespaceSchemaLocation, the appropriate case among the following 25097 * must be true: 25098 * 25099 */ 25100 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25101 /* 25102 * @nbAttrs is the number of attributes present in the instance. 25103 */ 25104 nbAttrs = vctxt->nbAttrInfos; 25105 if (attrUseList != NULL) 25106 nbUses = attrUseList->nbItems; 25107 else 25108 nbUses = 0; 25109 for (i = 0; i < nbUses; i++) { 25110 found = 0; 25111 attrUse = attrUseList->items[i]; 25112 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25113 for (j = 0; j < nbAttrs; j++) { 25114 iattr = vctxt->attrInfos[j]; 25115 /* 25116 * SPEC (cvc-complex-type) (3) 25117 * Skip meta attributes. 25118 */ 25119 if (iattr->metaType) 25120 continue; 25121 if (iattr->localName[0] != attrDecl->name[0]) 25122 continue; 25123 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25124 continue; 25125 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25126 continue; 25127 found = 1; 25128 /* 25129 * SPEC (cvc-complex-type) 25130 * (3.1) "If there is among the {attribute uses} an attribute 25131 * use with an {attribute declaration} whose {name} matches 25132 * the attribute information item's [local name] and whose 25133 * {target namespace} is identical to the attribute information 25134 * item's [namespace name] (where an �absent� {target namespace} 25135 * is taken to be identical to a [namespace name] with no value), 25136 * then the attribute information must be �valid� with respect 25137 * to that attribute use as per Attribute Locally Valid (Use) 25138 * (�3.5.4). In this case the {attribute declaration} of that 25139 * attribute use is the �context-determined declaration� for the 25140 * attribute information item with respect to Schema-Validity 25141 * Assessment (Attribute) (�3.2.4) and 25142 * Assessment Outcome (Attribute) (�3.2.5). 25143 */ 25144 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25145 iattr->use = attrUse; 25146 /* 25147 * Context-determined declaration. 25148 */ 25149 iattr->decl = attrDecl; 25150 iattr->typeDef = attrDecl->subtypes; 25151 break; 25152 } 25153 25154 if (found) 25155 continue; 25156 25157 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25158 /* 25159 * Handle non-existent, required attributes. 25160 * 25161 * SPEC (cvc-complex-type) 25162 * (4) "The {attribute declaration} of each attribute use in 25163 * the {attribute uses} whose {required} is true matches one 25164 * of the attribute information items in the element information 25165 * item's [attributes] as per clause 3.1 above." 25166 */ 25167 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25168 if (tmpiattr == NULL) { 25169 VERROR_INT( 25170 "xmlSchemaVAttributesComplex", 25171 "calling xmlSchemaGetFreshAttrInfo()"); 25172 return (-1); 25173 } 25174 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25175 tmpiattr->use = attrUse; 25176 tmpiattr->decl = attrDecl; 25177 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25178 ((attrUse->defValue != NULL) || 25179 (attrDecl->defValue != NULL))) { 25180 /* 25181 * Handle non-existent, optional, default/fixed attributes. 25182 */ 25183 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25184 if (tmpiattr == NULL) { 25185 VERROR_INT( 25186 "xmlSchemaVAttributesComplex", 25187 "calling xmlSchemaGetFreshAttrInfo()"); 25188 return (-1); 25189 } 25190 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25191 tmpiattr->use = attrUse; 25192 tmpiattr->decl = attrDecl; 25193 tmpiattr->typeDef = attrDecl->subtypes; 25194 tmpiattr->localName = attrDecl->name; 25195 tmpiattr->nsName = attrDecl->targetNamespace; 25196 } 25197 } 25198 25199 if (vctxt->nbAttrInfos == 0) 25200 return (0); 25201 nbUses = vctxt->nbAttrInfos; 25202 /* 25203 * Validate against the wildcard. 25204 */ 25205 if (type->attributeWildcard != NULL) { 25206 /* 25207 * SPEC (cvc-complex-type) 25208 * (3.2.1) "There must be an {attribute wildcard}." 25209 */ 25210 for (i = 0; i < nbAttrs; i++) { 25211 iattr = vctxt->attrInfos[i]; 25212 /* 25213 * SPEC (cvc-complex-type) (3) 25214 * Skip meta attributes. 25215 */ 25216 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25217 continue; 25218 /* 25219 * SPEC (cvc-complex-type) 25220 * (3.2.2) "The attribute information item must be �valid� with 25221 * respect to it as defined in Item Valid (Wildcard) (�3.10.4)." 25222 * 25223 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25224 * "... its [namespace name] must be �valid� with respect to 25225 * the wildcard constraint, as defined in Wildcard allows 25226 * Namespace Name (�3.10.4)." 25227 */ 25228 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25229 iattr->nsName) == 0) { 25230 /* 25231 * Handle processContents. 25232 * 25233 * SPEC (cvc-wildcard): 25234 * processContents | context-determined declaration: 25235 * "strict" "mustFind" 25236 * "lax" "none" 25237 * "skip" "skip" 25238 */ 25239 if (type->attributeWildcard->processContents == 25240 XML_SCHEMAS_ANY_SKIP) { 25241 /* 25242 * context-determined declaration = "skip" 25243 * 25244 * SPEC PSVI Assessment Outcome (Attribute) 25245 * [validity] = "notKnown" 25246 * [validation attempted] = "none" 25247 */ 25248 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25249 continue; 25250 } 25251 /* 25252 * Find an attribute declaration. 25253 */ 25254 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25255 iattr->localName, iattr->nsName); 25256 if (iattr->decl != NULL) { 25257 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25258 /* 25259 * SPEC (cvc-complex-type) 25260 * (5) "Let [Definition:] the wild IDs be the set of 25261 * all attribute information item to which clause 3.2 25262 * applied and whose �validation� resulted in a 25263 * �context-determined declaration� of mustFind or no 25264 * �context-determined declaration� at all, and whose 25265 * [local name] and [namespace name] resolve (as 25266 * defined by QName resolution (Instance) (�3.15.4)) to 25267 * an attribute declaration whose {type definition} is 25268 * or is derived from ID. Then all of the following 25269 * must be true:" 25270 */ 25271 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25272 if (xmlSchemaIsDerivedFromBuiltInType( 25273 iattr->typeDef, XML_SCHEMAS_ID)) { 25274 /* 25275 * SPEC (5.1) "There must be no more than one 25276 * item in �wild IDs�." 25277 */ 25278 if (wildIDs != 0) { 25279 /* VAL TODO */ 25280 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25281 TODO 25282 continue; 25283 } 25284 wildIDs++; 25285 /* 25286 * SPEC (cvc-complex-type) 25287 * (5.2) "If �wild IDs� is non-empty, there must not 25288 * be any attribute uses among the {attribute uses} 25289 * whose {attribute declaration}'s {type definition} 25290 * is or is derived from ID." 25291 */ 25292 for (j = 0; j < attrUseList->nbItems; j++) { 25293 if (xmlSchemaIsDerivedFromBuiltInType( 25294 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25295 XML_SCHEMAS_ID)) { 25296 /* URGENT VAL TODO: implement */ 25297 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25298 TODO 25299 break; 25300 } 25301 } 25302 } 25303 } else if (type->attributeWildcard->processContents == 25304 XML_SCHEMAS_ANY_LAX) { 25305 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25306 /* 25307 * SPEC PSVI Assessment Outcome (Attribute) 25308 * [validity] = "notKnown" 25309 * [validation attempted] = "none" 25310 */ 25311 } else { 25312 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25313 } 25314 } 25315 } 25316 } 25317 25318 if (vctxt->nbAttrInfos == 0) 25319 return (0); 25320 25321 /* 25322 * Get the owner element; needed for creation of default attributes. 25323 * This fixes bug #341337, reported by David Grohmann. 25324 */ 25325 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25326 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25327 if (ielem && ielem->node && ielem->node->doc) 25328 defAttrOwnerElem = ielem->node; 25329 } 25330 /* 25331 * Validate values, create default attributes, evaluate IDCs. 25332 */ 25333 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25334 iattr = vctxt->attrInfos[i]; 25335 /* 25336 * VAL TODO: Note that we won't try to resolve IDCs to 25337 * "lax" and "skip" validated attributes. Check what to 25338 * do in this case. 25339 */ 25340 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25341 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25342 continue; 25343 /* 25344 * VAL TODO: What to do if the type definition is missing? 25345 */ 25346 if (iattr->typeDef == NULL) { 25347 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25348 continue; 25349 } 25350 25351 ACTIVATE_ATTRIBUTE(iattr); 25352 fixed = 0; 25353 xpathRes = 0; 25354 25355 if (vctxt->xpathStates != NULL) { 25356 /* 25357 * Evaluate IDCs. 25358 */ 25359 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25360 XML_ATTRIBUTE_NODE); 25361 if (xpathRes == -1) { 25362 VERROR_INT("xmlSchemaVAttributesComplex", 25363 "calling xmlSchemaXPathEvaluate()"); 25364 goto internal_error; 25365 } 25366 } 25367 25368 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25369 /* 25370 * Default/fixed attributes. 25371 * We need the value only if we need to resolve IDCs or 25372 * will create default attributes. 25373 */ 25374 if ((xpathRes) || (defAttrOwnerElem)) { 25375 if (iattr->use->defValue != NULL) { 25376 iattr->value = (xmlChar *) iattr->use->defValue; 25377 iattr->val = iattr->use->defVal; 25378 } else { 25379 iattr->value = (xmlChar *) iattr->decl->defValue; 25380 iattr->val = iattr->decl->defVal; 25381 } 25382 /* 25383 * IDCs will consume the precomputed default value, 25384 * so we need to clone it. 25385 */ 25386 if (iattr->val == NULL) { 25387 VERROR_INT("xmlSchemaVAttributesComplex", 25388 "default/fixed value on an attribute use was " 25389 "not precomputed"); 25390 goto internal_error; 25391 } 25392 iattr->val = xmlSchemaCopyValue(iattr->val); 25393 if (iattr->val == NULL) { 25394 VERROR_INT("xmlSchemaVAttributesComplex", 25395 "calling xmlSchemaCopyValue()"); 25396 goto internal_error; 25397 } 25398 } 25399 /* 25400 * PSVI: Add the default attribute to the current element. 25401 * VAL TODO: Should we use the *normalized* value? This currently 25402 * uses the *initial* value. 25403 */ 25404 25405 if (defAttrOwnerElem) { 25406 xmlChar *normValue; 25407 const xmlChar *value; 25408 25409 value = iattr->value; 25410 /* 25411 * Normalize the value. 25412 */ 25413 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25414 iattr->value); 25415 if (normValue != NULL) 25416 value = BAD_CAST normValue; 25417 25418 if (iattr->nsName == NULL) { 25419 if (xmlNewProp(defAttrOwnerElem, 25420 iattr->localName, value) == NULL) { 25421 VERROR_INT("xmlSchemaVAttributesComplex", 25422 "callling xmlNewProp()"); 25423 if (normValue != NULL) 25424 xmlFree(normValue); 25425 goto internal_error; 25426 } 25427 } else { 25428 xmlNsPtr ns; 25429 25430 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25431 defAttrOwnerElem, iattr->nsName); 25432 if (ns == NULL) { 25433 xmlChar prefix[12]; 25434 int counter = 0; 25435 25436 /* 25437 * Create a namespace declaration on the validation 25438 * root node if no namespace declaration is in scope. 25439 */ 25440 do { 25441 snprintf((char *) prefix, 12, "p%d", counter++); 25442 ns = xmlSearchNs(defAttrOwnerElem->doc, 25443 defAttrOwnerElem, BAD_CAST prefix); 25444 if (counter > 1000) { 25445 VERROR_INT( 25446 "xmlSchemaVAttributesComplex", 25447 "could not compute a ns prefix for a " 25448 "default/fixed attribute"); 25449 if (normValue != NULL) 25450 xmlFree(normValue); 25451 goto internal_error; 25452 } 25453 } while (ns != NULL); 25454 ns = xmlNewNs(vctxt->validationRoot, 25455 iattr->nsName, BAD_CAST prefix); 25456 } 25457 /* 25458 * TODO: 25459 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25460 * If we have QNames: do we need to ensure there's a 25461 * prefix defined for the QName? 25462 */ 25463 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25464 } 25465 if (normValue != NULL) 25466 xmlFree(normValue); 25467 } 25468 /* 25469 * Go directly to IDC evaluation. 25470 */ 25471 goto eval_idcs; 25472 } 25473 /* 25474 * Validate the value. 25475 */ 25476 if (vctxt->value != NULL) { 25477 /* 25478 * Free last computed value; just for safety reasons. 25479 */ 25480 xmlSchemaFreeValue(vctxt->value); 25481 vctxt->value = NULL; 25482 } 25483 /* 25484 * Note that the attribute *use* can be unavailable, if 25485 * the attribute was a wild attribute. 25486 */ 25487 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25488 ((iattr->use != NULL) && 25489 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25490 fixed = 1; 25491 else 25492 fixed = 0; 25493 /* 25494 * SPEC (cvc-attribute) 25495 * (3) "The item's �normalized value� must be locally �valid� 25496 * with respect to that {type definition} as per 25497 * String Valid (�3.14.4)." 25498 * 25499 * VAL TODO: Do we already have the 25500 * "normalized attribute value" here? 25501 */ 25502 if (xpathRes || fixed) { 25503 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25504 /* 25505 * Request a computed value. 25506 */ 25507 res = xmlSchemaVCheckCVCSimpleType( 25508 ACTXT_CAST vctxt, 25509 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25510 1, 1, 0); 25511 } else { 25512 res = xmlSchemaVCheckCVCSimpleType( 25513 ACTXT_CAST vctxt, 25514 iattr->node, iattr->typeDef, iattr->value, NULL, 25515 1, 0, 0); 25516 } 25517 25518 if (res != 0) { 25519 if (res == -1) { 25520 VERROR_INT("xmlSchemaVAttributesComplex", 25521 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25522 goto internal_error; 25523 } 25524 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25525 /* 25526 * SPEC PSVI Assessment Outcome (Attribute) 25527 * [validity] = "invalid" 25528 */ 25529 goto eval_idcs; 25530 } 25531 25532 if (fixed) { 25533 /* 25534 * SPEC Attribute Locally Valid (Use) (cvc-au) 25535 * "For an attribute information item to be�valid� 25536 * with respect to an attribute use its *normalized* 25537 * value� must match the *canonical* lexical 25538 * representation of the attribute use's {value 25539 * constraint}value, if it is present and fixed." 25540 * 25541 * VAL TODO: The requirement for the *canonical* value 25542 * will be removed in XML Schema 1.1. 25543 */ 25544 /* 25545 * SPEC Attribute Locally Valid (cvc-attribute) 25546 * (4) "The item's *actual* value� must match the *value* of 25547 * the {value constraint}, if it is present and fixed." 25548 */ 25549 if (iattr->val == NULL) { 25550 /* VAL TODO: A value was not precomputed. */ 25551 TODO 25552 goto eval_idcs; 25553 } 25554 if ((iattr->use != NULL) && 25555 (iattr->use->defValue != NULL)) { 25556 if (iattr->use->defVal == NULL) { 25557 /* VAL TODO: A default value was not precomputed. */ 25558 TODO 25559 goto eval_idcs; 25560 } 25561 iattr->vcValue = iattr->use->defValue; 25562 /* 25563 if (xmlSchemaCompareValuesWhtsp(attr->val, 25564 (xmlSchemaWhitespaceValueType) ws, 25565 attr->use->defVal, 25566 (xmlSchemaWhitespaceValueType) ws) != 0) { 25567 */ 25568 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25569 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25570 } else { 25571 if (iattr->decl->defVal == NULL) { 25572 /* VAL TODO: A default value was not precomputed. */ 25573 TODO 25574 goto eval_idcs; 25575 } 25576 iattr->vcValue = iattr->decl->defValue; 25577 /* 25578 if (xmlSchemaCompareValuesWhtsp(attr->val, 25579 (xmlSchemaWhitespaceValueType) ws, 25580 attrDecl->defVal, 25581 (xmlSchemaWhitespaceValueType) ws) != 0) { 25582 */ 25583 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25584 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25585 } 25586 /* 25587 * [validity] = "valid" 25588 */ 25589 } 25590eval_idcs: 25591 /* 25592 * Evaluate IDCs. 25593 */ 25594 if (xpathRes) { 25595 if (xmlSchemaXPathProcessHistory(vctxt, 25596 vctxt->depth +1) == -1) { 25597 VERROR_INT("xmlSchemaVAttributesComplex", 25598 "calling xmlSchemaXPathEvaluate()"); 25599 goto internal_error; 25600 } 25601 } else if (vctxt->xpathStates != NULL) 25602 xmlSchemaXPathPop(vctxt); 25603 } 25604 25605 /* 25606 * Report errors. 25607 */ 25608 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25609 iattr = vctxt->attrInfos[i]; 25610 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25611 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25612 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25613 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25614 continue; 25615 ACTIVATE_ATTRIBUTE(iattr); 25616 switch (iattr->state) { 25617 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25618 xmlChar *str = NULL; 25619 ACTIVATE_ELEM; 25620 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25621 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25622 "The attribute '%s' is required but missing", 25623 xmlSchemaFormatQName(&str, 25624 iattr->decl->targetNamespace, 25625 iattr->decl->name), 25626 NULL); 25627 FREE_AND_NULL(str) 25628 break; 25629 } 25630 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25631 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25632 "The type definition is absent"); 25633 break; 25634 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25635 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25636 XML_SCHEMAV_CVC_AU, NULL, NULL, 25637 "The value '%s' does not match the fixed " 25638 "value constraint '%s'", 25639 iattr->value, iattr->vcValue); 25640 break; 25641 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25642 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25643 "No matching global attribute declaration available, but " 25644 "demanded by the strict wildcard"); 25645 break; 25646 case XML_SCHEMAS_ATTR_UNKNOWN: 25647 if (iattr->metaType) 25648 break; 25649 /* 25650 * MAYBE VAL TODO: One might report different error messages 25651 * for the following errors. 25652 */ 25653 if (type->attributeWildcard == NULL) { 25654 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25655 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25656 } else { 25657 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25658 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25659 } 25660 break; 25661 default: 25662 break; 25663 } 25664 } 25665 25666 ACTIVATE_ELEM; 25667 return (0); 25668internal_error: 25669 ACTIVATE_ELEM; 25670 return (-1); 25671} 25672 25673static int 25674xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25675 int *skip) 25676{ 25677 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25678 /* 25679 * The namespace of the element was already identified to be 25680 * matching the wildcard. 25681 */ 25682 if ((skip == NULL) || (wild == NULL) || 25683 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25684 VERROR_INT("xmlSchemaValidateElemWildcard", 25685 "bad arguments"); 25686 return (-1); 25687 } 25688 *skip = 0; 25689 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25690 /* 25691 * URGENT VAL TODO: Either we need to position the stream to the 25692 * next sibling, or walk the whole subtree. 25693 */ 25694 *skip = 1; 25695 return (0); 25696 } 25697 { 25698 xmlSchemaElementPtr decl = NULL; 25699 25700 decl = xmlSchemaGetElem(vctxt->schema, 25701 vctxt->inode->localName, vctxt->inode->nsName); 25702 if (decl != NULL) { 25703 vctxt->inode->decl = decl; 25704 return (0); 25705 } 25706 } 25707 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25708 /* VAL TODO: Change to proper error code. */ 25709 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25710 "No matching global element declaration available, but " 25711 "demanded by the strict wildcard"); 25712 return (vctxt->err); 25713 } 25714 if (vctxt->nbAttrInfos != 0) { 25715 xmlSchemaAttrInfoPtr iattr; 25716 /* 25717 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25718 * (1.2.1.2.1) - (1.2.1.2.3 ) 25719 * 25720 * Use the xsi:type attribute for the type definition. 25721 */ 25722 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25723 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25724 if (iattr != NULL) { 25725 if (xmlSchemaProcessXSIType(vctxt, iattr, 25726 &(vctxt->inode->typeDef), NULL) == -1) { 25727 VERROR_INT("xmlSchemaValidateElemWildcard", 25728 "calling xmlSchemaProcessXSIType() to " 25729 "process the attribute 'xsi:nil'"); 25730 return (-1); 25731 } 25732 /* 25733 * Don't return an error on purpose. 25734 */ 25735 return (0); 25736 } 25737 } 25738 /* 25739 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25740 * 25741 * Fallback to "anyType". 25742 */ 25743 vctxt->inode->typeDef = 25744 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25745 return (0); 25746} 25747 25748/* 25749* xmlSchemaCheckCOSValidDefault: 25750* 25751* This will be called if: not nilled, no content and a default/fixed 25752* value is provided. 25753*/ 25754 25755static int 25756xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25757 const xmlChar *value, 25758 xmlSchemaValPtr *val) 25759{ 25760 int ret = 0; 25761 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25762 25763 /* 25764 * cos-valid-default: 25765 * Schema Component Constraint: Element Default Valid (Immediate) 25766 * For a string to be a valid default with respect to a type 25767 * definition the appropriate case among the following must be true: 25768 */ 25769 if WXS_IS_COMPLEX(inode->typeDef) { 25770 /* 25771 * Complex type. 25772 * 25773 * SPEC (2.1) "its {content type} must be a simple type definition 25774 * or mixed." 25775 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25776 * type}'s particle must be �emptiable� as defined by 25777 * Particle Emptiable (�3.9.6)." 25778 */ 25779 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25780 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25781 (! WXS_EMPTIABLE(inode->typeDef)))) { 25782 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25783 /* NOTE that this covers (2.2.2) as well. */ 25784 VERROR(ret, NULL, 25785 "For a string to be a valid default, the type definition " 25786 "must be a simple type or a complex type with simple content " 25787 "or mixed content and a particle emptiable"); 25788 return(ret); 25789 } 25790 } 25791 /* 25792 * 1 If the type definition is a simple type definition, then the string 25793 * must be �valid� with respect to that definition as defined by String 25794 * Valid (�3.14.4). 25795 * 25796 * AND 25797 * 25798 * 2.2.1 If the {content type} is a simple type definition, then the 25799 * string must be �valid� with respect to that simple type definition 25800 * as defined by String Valid (�3.14.4). 25801 */ 25802 if (WXS_IS_SIMPLE(inode->typeDef)) { 25803 25804 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25805 NULL, inode->typeDef, value, val, 1, 1, 0); 25806 25807 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25808 25809 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25810 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25811 } 25812 if (ret < 0) { 25813 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25814 "calling xmlSchemaVCheckCVCSimpleType()"); 25815 } 25816 return (ret); 25817} 25818 25819static void 25820xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 25821 const xmlChar * name ATTRIBUTE_UNUSED, 25822 xmlSchemaElementPtr item, 25823 xmlSchemaNodeInfoPtr inode) 25824{ 25825 inode->decl = item; 25826#ifdef DEBUG_CONTENT 25827 { 25828 xmlChar *str = NULL; 25829 25830 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25831 xmlGenericError(xmlGenericErrorContext, 25832 "AUTOMATON callback for '%s' [declaration]\n", 25833 xmlSchemaFormatQName(&str, 25834 inode->localName, inode->nsName)); 25835 } else { 25836 xmlGenericError(xmlGenericErrorContext, 25837 "AUTOMATON callback for '%s' [wildcard]\n", 25838 xmlSchemaFormatQName(&str, 25839 inode->localName, inode->nsName)); 25840 25841 } 25842 FREE_AND_NULL(str) 25843 } 25844#endif 25845} 25846 25847static int 25848xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 25849{ 25850 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 25851 if (vctxt->inode == NULL) { 25852 VERROR_INT("xmlSchemaValidatorPushElem", 25853 "calling xmlSchemaGetFreshElemInfo()"); 25854 return (-1); 25855 } 25856 vctxt->nbAttrInfos = 0; 25857 return (0); 25858} 25859 25860static int 25861xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 25862 xmlSchemaNodeInfoPtr inode, 25863 xmlSchemaTypePtr type, 25864 const xmlChar *value) 25865{ 25866 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 25867 return (xmlSchemaVCheckCVCSimpleType( 25868 ACTXT_CAST vctxt, NULL, 25869 type, value, &(inode->val), 1, 1, 0)); 25870 else 25871 return (xmlSchemaVCheckCVCSimpleType( 25872 ACTXT_CAST vctxt, NULL, 25873 type, value, NULL, 1, 0, 0)); 25874} 25875 25876 25877 25878/* 25879* Process END of element. 25880*/ 25881static int 25882xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 25883{ 25884 int ret = 0; 25885 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25886 25887 if (vctxt->nbAttrInfos != 0) 25888 xmlSchemaClearAttrInfos(vctxt); 25889 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 25890 /* 25891 * This element was not expected; 25892 * we will not validate child elements of broken parents. 25893 * Skip validation of all content of the parent. 25894 */ 25895 vctxt->skipDepth = vctxt->depth -1; 25896 goto end_elem; 25897 } 25898 if ((inode->typeDef == NULL) || 25899 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 25900 /* 25901 * 1. the type definition might be missing if the element was 25902 * error prone 25903 * 2. it might be abstract. 25904 */ 25905 goto end_elem; 25906 } 25907 /* 25908 * Check the content model. 25909 */ 25910 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 25911 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 25912 25913 /* 25914 * Workaround for "anyType". 25915 */ 25916 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 25917 goto character_content; 25918 25919 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 25920 xmlChar *values[10]; 25921 int terminal, nbval = 10, nbneg; 25922 25923 if (inode->regexCtxt == NULL) { 25924 /* 25925 * Create the regex context. 25926 */ 25927 inode->regexCtxt = 25928 xmlRegNewExecCtxt(inode->typeDef->contModel, 25929 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 25930 vctxt); 25931 if (inode->regexCtxt == NULL) { 25932 VERROR_INT("xmlSchemaValidatorPopElem", 25933 "failed to create a regex context"); 25934 goto internal_error; 25935 } 25936#ifdef DEBUG_AUTOMATA 25937 xmlGenericError(xmlGenericErrorContext, 25938 "AUTOMATON create on '%s'\n", inode->localName); 25939#endif 25940 } 25941 /* 25942 * Get hold of the still expected content, since a further 25943 * call to xmlRegExecPushString() will loose this information. 25944 */ 25945 xmlRegExecNextValues(inode->regexCtxt, 25946 &nbval, &nbneg, &values[0], &terminal); 25947 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 25948 if (ret <= 0) { 25949 /* 25950 * Still missing something. 25951 */ 25952 ret = 1; 25953 inode->flags |= 25954 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 25955 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 25956 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 25957 "Missing child element(s)", 25958 nbval, nbneg, values); 25959#ifdef DEBUG_AUTOMATA 25960 xmlGenericError(xmlGenericErrorContext, 25961 "AUTOMATON missing ERROR on '%s'\n", 25962 inode->localName); 25963#endif 25964 } else { 25965 /* 25966 * Content model is satisfied. 25967 */ 25968 ret = 0; 25969#ifdef DEBUG_AUTOMATA 25970 xmlGenericError(xmlGenericErrorContext, 25971 "AUTOMATON succeeded on '%s'\n", 25972 inode->localName); 25973#endif 25974 } 25975 25976 } 25977 } 25978 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 25979 goto end_elem; 25980 25981character_content: 25982 25983 if (vctxt->value != NULL) { 25984 xmlSchemaFreeValue(vctxt->value); 25985 vctxt->value = NULL; 25986 } 25987 /* 25988 * Check character content. 25989 */ 25990 if (inode->decl == NULL) { 25991 /* 25992 * Speedup if no declaration exists. 25993 */ 25994 if (WXS_IS_SIMPLE(inode->typeDef)) { 25995 ret = xmlSchemaVCheckINodeDataType(vctxt, 25996 inode, inode->typeDef, inode->value); 25997 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25998 ret = xmlSchemaVCheckINodeDataType(vctxt, 25999 inode, inode->typeDef->contentTypeDef, 26000 inode->value); 26001 } 26002 if (ret < 0) { 26003 VERROR_INT("xmlSchemaValidatorPopElem", 26004 "calling xmlSchemaVCheckCVCSimpleType()"); 26005 goto internal_error; 26006 } 26007 goto end_elem; 26008 } 26009 /* 26010 * cvc-elt (3.3.4) : 5 26011 * The appropriate case among the following must be true: 26012 */ 26013 /* 26014 * cvc-elt (3.3.4) : 5.1 26015 * If the declaration has a {value constraint}, 26016 * the item has neither element nor character [children] and 26017 * clause 3.2 has not applied, then all of the following must be true: 26018 */ 26019 if ((inode->decl->value != NULL) && 26020 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26021 (! INODE_NILLED(inode))) { 26022 /* 26023 * cvc-elt (3.3.4) : 5.1.1 26024 * If the �actual type definition� is a �local type definition� 26025 * then the canonical lexical representation of the {value constraint} 26026 * value must be a valid default for the �actual type definition� as 26027 * defined in Element Default Valid (Immediate) (�3.3.6). 26028 */ 26029 /* 26030 * NOTE: 'local' above means types acquired by xsi:type. 26031 * NOTE: Although the *canonical* value is stated, it is not 26032 * relevant if canonical or not. Additionally XML Schema 1.1 26033 * will removed this requirement as well. 26034 */ 26035 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26036 26037 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26038 inode->decl->value, &(inode->val)); 26039 if (ret != 0) { 26040 if (ret < 0) { 26041 VERROR_INT("xmlSchemaValidatorPopElem", 26042 "calling xmlSchemaCheckCOSValidDefault()"); 26043 goto internal_error; 26044 } 26045 goto end_elem; 26046 } 26047 /* 26048 * Stop here, to avoid redundant validation of the value 26049 * (see following). 26050 */ 26051 goto default_psvi; 26052 } 26053 /* 26054 * cvc-elt (3.3.4) : 5.1.2 26055 * The element information item with the canonical lexical 26056 * representation of the {value constraint} value used as its 26057 * �normalized value� must be �valid� with respect to the 26058 * �actual type definition� as defined by Element Locally Valid (Type) 26059 * (�3.3.4). 26060 */ 26061 if (WXS_IS_SIMPLE(inode->typeDef)) { 26062 ret = xmlSchemaVCheckINodeDataType(vctxt, 26063 inode, inode->typeDef, inode->decl->value); 26064 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26065 ret = xmlSchemaVCheckINodeDataType(vctxt, 26066 inode, inode->typeDef->contentTypeDef, 26067 inode->decl->value); 26068 } 26069 if (ret != 0) { 26070 if (ret < 0) { 26071 VERROR_INT("xmlSchemaValidatorPopElem", 26072 "calling xmlSchemaVCheckCVCSimpleType()"); 26073 goto internal_error; 26074 } 26075 goto end_elem; 26076 } 26077 26078default_psvi: 26079 /* 26080 * PSVI: Create a text node on the instance element. 26081 */ 26082 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26083 (inode->node != NULL)) { 26084 xmlNodePtr textChild; 26085 xmlChar *normValue; 26086 /* 26087 * VAL TODO: Normalize the value. 26088 */ 26089 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26090 inode->decl->value); 26091 if (normValue != NULL) { 26092 textChild = xmlNewText(BAD_CAST normValue); 26093 xmlFree(normValue); 26094 } else 26095 textChild = xmlNewText(inode->decl->value); 26096 if (textChild == NULL) { 26097 VERROR_INT("xmlSchemaValidatorPopElem", 26098 "calling xmlNewText()"); 26099 goto internal_error; 26100 } else 26101 xmlAddChild(inode->node, textChild); 26102 } 26103 26104 } else if (! INODE_NILLED(inode)) { 26105 /* 26106 * 5.2.1 The element information item must be �valid� with respect 26107 * to the �actual type definition� as defined by Element Locally 26108 * Valid (Type) (�3.3.4). 26109 */ 26110 if (WXS_IS_SIMPLE(inode->typeDef)) { 26111 /* 26112 * SPEC (cvc-type) (3.1) 26113 * "If the type definition is a simple type definition, ..." 26114 * (3.1.3) "If clause 3.2 of Element Locally Valid 26115 * (Element) (�3.3.4) did not apply, then the �normalized value� 26116 * must be �valid� with respect to the type definition as defined 26117 * by String Valid (�3.14.4). 26118 */ 26119 ret = xmlSchemaVCheckINodeDataType(vctxt, 26120 inode, inode->typeDef, inode->value); 26121 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26122 /* 26123 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26124 * definition, then the element information item must be 26125 * �valid� with respect to the type definition as per 26126 * Element Locally Valid (Complex Type) (�3.4.4);" 26127 * 26128 * SPEC (cvc-complex-type) (2.2) 26129 * "If the {content type} is a simple type definition, ... 26130 * the �normalized value� of the element information item is 26131 * �valid� with respect to that simple type definition as 26132 * defined by String Valid (�3.14.4)." 26133 */ 26134 ret = xmlSchemaVCheckINodeDataType(vctxt, 26135 inode, inode->typeDef->contentTypeDef, inode->value); 26136 } 26137 if (ret != 0) { 26138 if (ret < 0) { 26139 VERROR_INT("xmlSchemaValidatorPopElem", 26140 "calling xmlSchemaVCheckCVCSimpleType()"); 26141 goto internal_error; 26142 } 26143 goto end_elem; 26144 } 26145 /* 26146 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26147 * not applied, all of the following must be true: 26148 */ 26149 if ((inode->decl->value != NULL) && 26150 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26151 26152 /* 26153 * TODO: We will need a computed value, when comparison is 26154 * done on computed values. 26155 */ 26156 /* 26157 * 5.2.2.1 The element information item must have no element 26158 * information item [children]. 26159 */ 26160 if (inode->flags & 26161 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26162 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26163 VERROR(ret, NULL, 26164 "The content must not containt element nodes since " 26165 "there is a fixed value constraint"); 26166 goto end_elem; 26167 } else { 26168 /* 26169 * 5.2.2.2 The appropriate case among the following must 26170 * be true: 26171 */ 26172 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26173 /* 26174 * 5.2.2.2.1 If the {content type} of the �actual type 26175 * definition� is mixed, then the *initial value* of the 26176 * item must match the canonical lexical representation 26177 * of the {value constraint} value. 26178 * 26179 * ... the *initial value* of an element information 26180 * item is the string composed of, in order, the 26181 * [character code] of each character information item in 26182 * the [children] of that element information item. 26183 */ 26184 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26185 /* 26186 * VAL TODO: Report invalid & expected values as well. 26187 * VAL TODO: Implement the canonical stuff. 26188 */ 26189 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26190 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26191 ret, NULL, NULL, 26192 "The initial value '%s' does not match the fixed " 26193 "value constraint '%s'", 26194 inode->value, inode->decl->value); 26195 goto end_elem; 26196 } 26197 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26198 /* 26199 * 5.2.2.2.2 If the {content type} of the �actual type 26200 * definition� is a simple type definition, then the 26201 * *actual value* of the item must match the canonical 26202 * lexical representation of the {value constraint} value. 26203 */ 26204 /* 26205 * VAL TODO: *actual value* is the normalized value, impl. 26206 * this. 26207 * VAL TODO: Report invalid & expected values as well. 26208 * VAL TODO: Implement a comparison with the computed values. 26209 */ 26210 if (! xmlStrEqual(inode->value, 26211 inode->decl->value)) { 26212 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26213 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26214 ret, NULL, NULL, 26215 "The actual value '%s' does not match the fixed " 26216 "value constraint '%s'", 26217 inode->value, 26218 inode->decl->value); 26219 goto end_elem; 26220 } 26221 } 26222 } 26223 } 26224 } 26225 26226end_elem: 26227 if (vctxt->depth < 0) { 26228 /* TODO: raise error? */ 26229 return (0); 26230 } 26231 if (vctxt->depth == vctxt->skipDepth) 26232 vctxt->skipDepth = -1; 26233 /* 26234 * Evaluate the history of XPath state objects. 26235 */ 26236 if (inode->appliedXPath && 26237 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26238 goto internal_error; 26239 /* 26240 * MAYBE TODO: 26241 * SPEC (6) "The element information item must be �valid� with 26242 * respect to each of the {identity-constraint definitions} as per 26243 * Identity-constraint Satisfied (�3.11.4)." 26244 */ 26245 /* 26246 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26247 * need to be built in any case. 26248 * We will currently build IDC node-tables and bubble them only if 26249 * keyrefs do exist. 26250 */ 26251 26252 /* 26253 * Add the current IDC target-nodes to the IDC node-tables. 26254 */ 26255 if ((inode->idcMatchers != NULL) && 26256 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26257 { 26258 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26259 goto internal_error; 26260 } 26261 /* 26262 * Validate IDC keyrefs. 26263 */ 26264 if (vctxt->inode->hasKeyrefs) 26265 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26266 goto internal_error; 26267 /* 26268 * Merge/free the IDC table. 26269 */ 26270 if (inode->idcTable != NULL) { 26271#ifdef DEBUG_IDC_NODE_TABLE 26272 xmlSchemaDebugDumpIDCTable(stdout, 26273 inode->nsName, 26274 inode->localName, 26275 inode->idcTable); 26276#endif 26277 if ((vctxt->depth > 0) && 26278 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26279 { 26280 /* 26281 * Merge the IDC node table with the table of the parent node. 26282 */ 26283 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26284 goto internal_error; 26285 } 26286 } 26287 /* 26288 * Clear the current ielem. 26289 * VAL TODO: Don't free the PSVI IDC tables if they are 26290 * requested for the PSVI. 26291 */ 26292 xmlSchemaClearElemInfo(vctxt, inode); 26293 /* 26294 * Skip further processing if we are on the validation root. 26295 */ 26296 if (vctxt->depth == 0) { 26297 vctxt->depth--; 26298 vctxt->inode = NULL; 26299 return (0); 26300 } 26301 /* 26302 * Reset the keyrefDepth if needed. 26303 */ 26304 if (vctxt->aidcs != NULL) { 26305 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26306 do { 26307 if (aidc->keyrefDepth == vctxt->depth) { 26308 /* 26309 * A 'keyrefDepth' of a key/unique IDC matches the current 26310 * depth, this means that we are leaving the scope of the 26311 * top-most keyref IDC which refers to this IDC. 26312 */ 26313 aidc->keyrefDepth = -1; 26314 } 26315 aidc = aidc->next; 26316 } while (aidc != NULL); 26317 } 26318 vctxt->depth--; 26319 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26320 /* 26321 * VAL TODO: 7 If the element information item is the �validation root�, it must be 26322 * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4). 26323 */ 26324 return (ret); 26325 26326internal_error: 26327 vctxt->err = -1; 26328 return (-1); 26329} 26330 26331/* 26332* 3.4.4 Complex Type Definition Validation Rules 26333* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26334*/ 26335static int 26336xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26337{ 26338 xmlSchemaNodeInfoPtr pielem; 26339 xmlSchemaTypePtr ptype; 26340 int ret = 0; 26341 26342 if (vctxt->depth <= 0) { 26343 VERROR_INT("xmlSchemaValidateChildElem", 26344 "not intended for the validation root"); 26345 return (-1); 26346 } 26347 pielem = vctxt->elemInfos[vctxt->depth -1]; 26348 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26349 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26350 /* 26351 * Handle 'nilled' elements. 26352 */ 26353 if (INODE_NILLED(pielem)) { 26354 /* 26355 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26356 */ 26357 ACTIVATE_PARENT_ELEM; 26358 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26359 VERROR(ret, NULL, 26360 "Neither character nor element content is allowed, " 26361 "because the element was 'nilled'"); 26362 ACTIVATE_ELEM; 26363 goto unexpected_elem; 26364 } 26365 26366 ptype = pielem->typeDef; 26367 26368 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26369 /* 26370 * Workaround for "anyType": we have currently no content model 26371 * assigned for "anyType", so handle it explicitely. 26372 * "anyType" has an unbounded, lax "any" wildcard. 26373 */ 26374 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26375 vctxt->inode->localName, 26376 vctxt->inode->nsName); 26377 26378 if (vctxt->inode->decl == NULL) { 26379 xmlSchemaAttrInfoPtr iattr; 26380 /* 26381 * Process "xsi:type". 26382 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26383 */ 26384 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26385 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26386 if (iattr != NULL) { 26387 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26388 &(vctxt->inode->typeDef), NULL); 26389 if (ret != 0) { 26390 if (ret == -1) { 26391 VERROR_INT("xmlSchemaValidateChildElem", 26392 "calling xmlSchemaProcessXSIType() to " 26393 "process the attribute 'xsi:nil'"); 26394 return (-1); 26395 } 26396 return (ret); 26397 } 26398 } else { 26399 /* 26400 * Fallback to "anyType". 26401 * 26402 * SPEC (cvc-assess-elt) 26403 * "If the item cannot be �strictly assessed�, [...] 26404 * an element information item's schema validity may be laxly 26405 * assessed if its �context-determined declaration� is not 26406 * skip by �validating� with respect to the �ur-type 26407 * definition� as per Element Locally Valid (Type) (�3.3.4)." 26408 */ 26409 vctxt->inode->typeDef = 26410 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26411 } 26412 } 26413 return (0); 26414 } 26415 26416 switch (ptype->contentType) { 26417 case XML_SCHEMA_CONTENT_EMPTY: 26418 /* 26419 * SPEC (2.1) "If the {content type} is empty, then the 26420 * element information item has no character or element 26421 * information item [children]." 26422 */ 26423 ACTIVATE_PARENT_ELEM 26424 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26425 VERROR(ret, NULL, 26426 "Element content is not allowed, " 26427 "because the content type is empty"); 26428 ACTIVATE_ELEM 26429 goto unexpected_elem; 26430 break; 26431 26432 case XML_SCHEMA_CONTENT_MIXED: 26433 case XML_SCHEMA_CONTENT_ELEMENTS: { 26434 xmlRegExecCtxtPtr regexCtxt; 26435 xmlChar *values[10]; 26436 int terminal, nbval = 10, nbneg; 26437 26438 /* VAL TODO: Optimized "anyType" validation.*/ 26439 26440 if (ptype->contModel == NULL) { 26441 VERROR_INT("xmlSchemaValidateChildElem", 26442 "type has elem content but no content model"); 26443 return (-1); 26444 } 26445 /* 26446 * Safety belf for evaluation if the cont. model was already 26447 * examined to be invalid. 26448 */ 26449 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26450 VERROR_INT("xmlSchemaValidateChildElem", 26451 "validating elem, but elem content is already invalid"); 26452 return (-1); 26453 } 26454 26455 regexCtxt = pielem->regexCtxt; 26456 if (regexCtxt == NULL) { 26457 /* 26458 * Create the regex context. 26459 */ 26460 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26461 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26462 vctxt); 26463 if (regexCtxt == NULL) { 26464 VERROR_INT("xmlSchemaValidateChildElem", 26465 "failed to create a regex context"); 26466 return (-1); 26467 } 26468 pielem->regexCtxt = regexCtxt; 26469#ifdef DEBUG_AUTOMATA 26470 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26471 pielem->localName); 26472#endif 26473 } 26474 26475 /* 26476 * SPEC (2.4) "If the {content type} is element-only or mixed, 26477 * then the sequence of the element information item's 26478 * element information item [children], if any, taken in 26479 * order, is �valid� with respect to the {content type}'s 26480 * particle, as defined in Element Sequence Locally Valid 26481 * (Particle) (�3.9.4)." 26482 */ 26483 ret = xmlRegExecPushString2(regexCtxt, 26484 vctxt->inode->localName, 26485 vctxt->inode->nsName, 26486 vctxt->inode); 26487#ifdef DEBUG_AUTOMATA 26488 if (ret < 0) 26489 xmlGenericError(xmlGenericErrorContext, 26490 "AUTOMATON push ERROR for '%s' on '%s'\n", 26491 vctxt->inode->localName, pielem->localName); 26492 else 26493 xmlGenericError(xmlGenericErrorContext, 26494 "AUTOMATON push OK for '%s' on '%s'\n", 26495 vctxt->inode->localName, pielem->localName); 26496#endif 26497 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26498 VERROR_INT("xmlSchemaValidateChildElem", 26499 "calling xmlRegExecPushString2()"); 26500 return (-1); 26501 } 26502 if (ret < 0) { 26503 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26504 &values[0], &terminal); 26505 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26506 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26507 "This element is not expected", 26508 nbval, nbneg, values); 26509 ret = vctxt->err; 26510 goto unexpected_elem; 26511 } else 26512 ret = 0; 26513 } 26514 break; 26515 case XML_SCHEMA_CONTENT_SIMPLE: 26516 case XML_SCHEMA_CONTENT_BASIC: 26517 ACTIVATE_PARENT_ELEM 26518 if (WXS_IS_COMPLEX(ptype)) { 26519 /* 26520 * SPEC (cvc-complex-type) (2.2) 26521 * "If the {content type} is a simple type definition, then 26522 * the element information item has no element information 26523 * item [children], ..." 26524 */ 26525 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26526 VERROR(ret, NULL, "Element content is not allowed, " 26527 "because the content type is a simple type definition"); 26528 } else { 26529 /* 26530 * SPEC (cvc-type) (3.1.2) "The element information item must 26531 * have no element information item [children]." 26532 */ 26533 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26534 VERROR(ret, NULL, "Element content is not allowed, " 26535 "because the type definition is simple"); 26536 } 26537 ACTIVATE_ELEM 26538 ret = vctxt->err; 26539 goto unexpected_elem; 26540 break; 26541 26542 default: 26543 break; 26544 } 26545 return (ret); 26546unexpected_elem: 26547 /* 26548 * Pop this element and set the skipDepth to skip 26549 * all further content of the parent element. 26550 */ 26551 vctxt->skipDepth = vctxt->depth; 26552 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26553 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26554 return (ret); 26555} 26556 26557#define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26558#define XML_SCHEMA_PUSH_TEXT_CREATED 2 26559#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26560 26561static int 26562xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26563 int nodeType, const xmlChar *value, int len, 26564 int mode, int *consumed) 26565{ 26566 /* 26567 * Unfortunately we have to duplicate the text sometimes. 26568 * OPTIMIZE: Maybe we could skip it, if: 26569 * 1. content type is simple 26570 * 2. whitespace is "collapse" 26571 * 3. it consists of whitespace only 26572 * 26573 * Process character content. 26574 */ 26575 if (consumed != NULL) 26576 *consumed = 0; 26577 if (INODE_NILLED(vctxt->inode)) { 26578 /* 26579 * SPEC cvc-elt (3.3.4 - 3.2.1) 26580 * "The element information item must have no character or 26581 * element information item [children]." 26582 */ 26583 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26584 "Neither character nor element content is allowed " 26585 "because the element is 'nilled'"); 26586 return (vctxt->err); 26587 } 26588 /* 26589 * SPEC (2.1) "If the {content type} is empty, then the 26590 * element information item has no character or element 26591 * information item [children]." 26592 */ 26593 if (vctxt->inode->typeDef->contentType == 26594 XML_SCHEMA_CONTENT_EMPTY) { 26595 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26596 "Character content is not allowed, " 26597 "because the content type is empty"); 26598 return (vctxt->err); 26599 } 26600 26601 if (vctxt->inode->typeDef->contentType == 26602 XML_SCHEMA_CONTENT_ELEMENTS) { 26603 if ((nodeType != XML_TEXT_NODE) || 26604 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26605 /* 26606 * SPEC cvc-complex-type (2.3) 26607 * "If the {content type} is element-only, then the 26608 * element information item has no character information 26609 * item [children] other than those whose [character 26610 * code] is defined as a white space in [XML 1.0 (Second 26611 * Edition)]." 26612 */ 26613 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26614 "Character content other than whitespace is not allowed " 26615 "because the content type is 'element-only'"); 26616 return (vctxt->err); 26617 } 26618 return (0); 26619 } 26620 26621 if ((value == NULL) || (value[0] == 0)) 26622 return (0); 26623 /* 26624 * Save the value. 26625 * NOTE that even if the content type is *mixed*, we need the 26626 * *initial value* for default/fixed value constraints. 26627 */ 26628 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26629 ((vctxt->inode->decl == NULL) || 26630 (vctxt->inode->decl->value == NULL))) 26631 return (0); 26632 26633 if (vctxt->inode->value == NULL) { 26634 /* 26635 * Set the value. 26636 */ 26637 switch (mode) { 26638 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26639 /* 26640 * When working on a tree. 26641 */ 26642 vctxt->inode->value = value; 26643 break; 26644 case XML_SCHEMA_PUSH_TEXT_CREATED: 26645 /* 26646 * When working with the reader. 26647 * The value will be freed by the element info. 26648 */ 26649 vctxt->inode->value = value; 26650 if (consumed != NULL) 26651 *consumed = 1; 26652 vctxt->inode->flags |= 26653 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26654 break; 26655 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26656 /* 26657 * When working with SAX. 26658 * The value will be freed by the element info. 26659 */ 26660 if (len != -1) 26661 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26662 else 26663 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26664 vctxt->inode->flags |= 26665 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26666 break; 26667 default: 26668 break; 26669 } 26670 } else { 26671 if (len < 0) 26672 len = xmlStrlen(value); 26673 /* 26674 * Concat the value. 26675 */ 26676 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26677 vctxt->inode->value = BAD_CAST xmlStrncat( 26678 (xmlChar *) vctxt->inode->value, value, len); 26679 } else { 26680 vctxt->inode->value = 26681 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26682 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26683 } 26684 } 26685 26686 return (0); 26687} 26688 26689static int 26690xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26691{ 26692 int ret = 0; 26693 26694 if ((vctxt->skipDepth != -1) && 26695 (vctxt->depth >= vctxt->skipDepth)) { 26696 VERROR_INT("xmlSchemaValidateElem", 26697 "in skip-state"); 26698 goto internal_error; 26699 } 26700 if (vctxt->xsiAssemble) { 26701 /* 26702 * We will stop validation if there was an error during 26703 * dynamic schema construction. 26704 * Note that we simply set @skipDepth to 0, this could 26705 * mean that a streaming document via SAX would be 26706 * still read to the end but it won't be validated any more. 26707 * TODO: If we are sure how to stop the validation at once 26708 * for all input scenarios, then this should be changed to 26709 * instantly stop the validation. 26710 */ 26711 ret = xmlSchemaAssembleByXSI(vctxt); 26712 if (ret != 0) { 26713 if (ret == -1) 26714 goto internal_error; 26715 vctxt->skipDepth = 0; 26716 return(ret); 26717 } 26718 } 26719 if (vctxt->depth > 0) { 26720 /* 26721 * Validate this element against the content model 26722 * of the parent. 26723 */ 26724 ret = xmlSchemaValidateChildElem(vctxt); 26725 if (ret != 0) { 26726 if (ret < 0) { 26727 VERROR_INT("xmlSchemaValidateElem", 26728 "calling xmlSchemaStreamValidateChildElement()"); 26729 goto internal_error; 26730 } 26731 goto exit; 26732 } 26733 if (vctxt->depth == vctxt->skipDepth) 26734 goto exit; 26735 if ((vctxt->inode->decl == NULL) && 26736 (vctxt->inode->typeDef == NULL)) { 26737 VERROR_INT("xmlSchemaValidateElem", 26738 "the child element was valid but neither the " 26739 "declaration nor the type was set"); 26740 goto internal_error; 26741 } 26742 } else { 26743 /* 26744 * Get the declaration of the validation root. 26745 */ 26746 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26747 vctxt->inode->localName, 26748 vctxt->inode->nsName); 26749 if (vctxt->inode->decl == NULL) { 26750 ret = XML_SCHEMAV_CVC_ELT_1; 26751 VERROR(ret, NULL, 26752 "No matching global declaration available " 26753 "for the validation root"); 26754 goto exit; 26755 } 26756 } 26757 26758 if (vctxt->inode->decl == NULL) 26759 goto type_validation; 26760 26761 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26762 int skip; 26763 /* 26764 * Wildcards. 26765 */ 26766 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26767 if (ret != 0) { 26768 if (ret < 0) { 26769 VERROR_INT("xmlSchemaValidateElem", 26770 "calling xmlSchemaValidateElemWildcard()"); 26771 goto internal_error; 26772 } 26773 goto exit; 26774 } 26775 if (skip) { 26776 vctxt->skipDepth = vctxt->depth; 26777 goto exit; 26778 } 26779 /* 26780 * The declaration might be set by the wildcard validation, 26781 * when the processContents is "lax" or "strict". 26782 */ 26783 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26784 /* 26785 * Clear the "decl" field to not confuse further processing. 26786 */ 26787 vctxt->inode->decl = NULL; 26788 goto type_validation; 26789 } 26790 } 26791 /* 26792 * Validate against the declaration. 26793 */ 26794 ret = xmlSchemaValidateElemDecl(vctxt); 26795 if (ret != 0) { 26796 if (ret < 0) { 26797 VERROR_INT("xmlSchemaValidateElem", 26798 "calling xmlSchemaValidateElemDecl()"); 26799 goto internal_error; 26800 } 26801 goto exit; 26802 } 26803 /* 26804 * Validate against the type definition. 26805 */ 26806type_validation: 26807 26808 if (vctxt->inode->typeDef == NULL) { 26809 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26810 ret = XML_SCHEMAV_CVC_TYPE_1; 26811 VERROR(ret, NULL, 26812 "The type definition is absent"); 26813 goto exit; 26814 } 26815 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26816 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26817 ret = XML_SCHEMAV_CVC_TYPE_2; 26818 VERROR(ret, NULL, 26819 "The type definition is abstract"); 26820 goto exit; 26821 } 26822 /* 26823 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26824 * during validation against the declaration. This must be done 26825 * _before_ attribute validation. 26826 */ 26827 if (vctxt->xpathStates != NULL) { 26828 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 26829 vctxt->inode->appliedXPath = 1; 26830 if (ret == -1) { 26831 VERROR_INT("xmlSchemaValidateElem", 26832 "calling xmlSchemaXPathEvaluate()"); 26833 goto internal_error; 26834 } 26835 } 26836 /* 26837 * Validate attributes. 26838 */ 26839 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 26840 if ((vctxt->nbAttrInfos != 0) || 26841 (vctxt->inode->typeDef->attrUses != NULL)) { 26842 26843 ret = xmlSchemaVAttributesComplex(vctxt); 26844 } 26845 } else if (vctxt->nbAttrInfos != 0) { 26846 26847 ret = xmlSchemaVAttributesSimple(vctxt); 26848 } 26849 /* 26850 * Clear registered attributes. 26851 */ 26852 if (vctxt->nbAttrInfos != 0) 26853 xmlSchemaClearAttrInfos(vctxt); 26854 if (ret == -1) { 26855 VERROR_INT("xmlSchemaValidateElem", 26856 "calling attributes validation"); 26857 goto internal_error; 26858 } 26859 /* 26860 * Don't return an error if attributes are invalid on purpose. 26861 */ 26862 ret = 0; 26863 26864exit: 26865 if (ret != 0) 26866 vctxt->skipDepth = vctxt->depth; 26867 return (ret); 26868internal_error: 26869 return (-1); 26870} 26871 26872#ifdef XML_SCHEMA_READER_ENABLED 26873static int 26874xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 26875{ 26876 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 26877 int depth, nodeType, ret = 0, consumed; 26878 xmlSchemaNodeInfoPtr ielem; 26879 26880 vctxt->depth = -1; 26881 ret = xmlTextReaderRead(vctxt->reader); 26882 /* 26883 * Move to the document element. 26884 */ 26885 while (ret == 1) { 26886 nodeType = xmlTextReaderNodeType(vctxt->reader); 26887 if (nodeType == XML_ELEMENT_NODE) 26888 goto root_found; 26889 ret = xmlTextReaderRead(vctxt->reader); 26890 } 26891 goto exit; 26892 26893root_found: 26894 26895 do { 26896 depth = xmlTextReaderDepth(vctxt->reader); 26897 nodeType = xmlTextReaderNodeType(vctxt->reader); 26898 26899 if (nodeType == XML_ELEMENT_NODE) { 26900 26901 vctxt->depth++; 26902 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 26903 VERROR_INT("xmlSchemaVReaderWalk", 26904 "calling xmlSchemaValidatorPushElem()"); 26905 goto internal_error; 26906 } 26907 ielem = vctxt->inode; 26908 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 26909 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 26910 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 26911 /* 26912 * Is the element empty? 26913 */ 26914 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 26915 if (ret == -1) { 26916 VERROR_INT("xmlSchemaVReaderWalk", 26917 "calling xmlTextReaderIsEmptyElement()"); 26918 goto internal_error; 26919 } 26920 if (ret) { 26921 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 26922 } 26923 /* 26924 * Register attributes. 26925 */ 26926 vctxt->nbAttrInfos = 0; 26927 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 26928 if (ret == -1) { 26929 VERROR_INT("xmlSchemaVReaderWalk", 26930 "calling xmlTextReaderMoveToFirstAttribute()"); 26931 goto internal_error; 26932 } 26933 if (ret == 1) { 26934 do { 26935 /* 26936 * VAL TODO: How do we know that the reader works on a 26937 * node tree, to be able to pass a node here? 26938 */ 26939 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 26940 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 26941 xmlTextReaderNamespaceUri(vctxt->reader), 1, 26942 xmlTextReaderValue(vctxt->reader), 1) == -1) { 26943 26944 VERROR_INT("xmlSchemaVReaderWalk", 26945 "calling xmlSchemaValidatorPushAttribute()"); 26946 goto internal_error; 26947 } 26948 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 26949 if (ret == -1) { 26950 VERROR_INT("xmlSchemaVReaderWalk", 26951 "calling xmlTextReaderMoveToFirstAttribute()"); 26952 goto internal_error; 26953 } 26954 } while (ret == 1); 26955 /* 26956 * Back to element position. 26957 */ 26958 ret = xmlTextReaderMoveToElement(vctxt->reader); 26959 if (ret == -1) { 26960 VERROR_INT("xmlSchemaVReaderWalk", 26961 "calling xmlTextReaderMoveToElement()"); 26962 goto internal_error; 26963 } 26964 } 26965 /* 26966 * Validate the element. 26967 */ 26968 ret= xmlSchemaValidateElem(vctxt); 26969 if (ret != 0) { 26970 if (ret == -1) { 26971 VERROR_INT("xmlSchemaVReaderWalk", 26972 "calling xmlSchemaValidateElem()"); 26973 goto internal_error; 26974 } 26975 goto exit; 26976 } 26977 if (vctxt->depth == vctxt->skipDepth) { 26978 int curDepth; 26979 /* 26980 * Skip all content. 26981 */ 26982 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 26983 ret = xmlTextReaderRead(vctxt->reader); 26984 curDepth = xmlTextReaderDepth(vctxt->reader); 26985 while ((ret == 1) && (curDepth != depth)) { 26986 ret = xmlTextReaderRead(vctxt->reader); 26987 curDepth = xmlTextReaderDepth(vctxt->reader); 26988 } 26989 if (ret < 0) { 26990 /* 26991 * VAL TODO: A reader error occured; what to do here? 26992 */ 26993 ret = 1; 26994 goto exit; 26995 } 26996 } 26997 goto leave_elem; 26998 } 26999 /* 27000 * READER VAL TODO: Is an END_ELEM really never called 27001 * if the elem is empty? 27002 */ 27003 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27004 goto leave_elem; 27005 } else if (nodeType == END_ELEM) { 27006 /* 27007 * Process END of element. 27008 */ 27009leave_elem: 27010 ret = xmlSchemaValidatorPopElem(vctxt); 27011 if (ret != 0) { 27012 if (ret < 0) { 27013 VERROR_INT("xmlSchemaVReaderWalk", 27014 "calling xmlSchemaValidatorPopElem()"); 27015 goto internal_error; 27016 } 27017 goto exit; 27018 } 27019 if (vctxt->depth >= 0) 27020 ielem = vctxt->inode; 27021 else 27022 ielem = NULL; 27023 } else if ((nodeType == XML_TEXT_NODE) || 27024 (nodeType == XML_CDATA_SECTION_NODE) || 27025 (nodeType == WHTSP) || 27026 (nodeType == SIGN_WHTSP)) { 27027 /* 27028 * Process character content. 27029 */ 27030 xmlChar *value; 27031 27032 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27033 nodeType = XML_TEXT_NODE; 27034 27035 value = xmlTextReaderValue(vctxt->reader); 27036 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27037 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27038 if (! consumed) 27039 xmlFree(value); 27040 if (ret == -1) { 27041 VERROR_INT("xmlSchemaVReaderWalk", 27042 "calling xmlSchemaVPushText()"); 27043 goto internal_error; 27044 } 27045 } else if ((nodeType == XML_ENTITY_NODE) || 27046 (nodeType == XML_ENTITY_REF_NODE)) { 27047 /* 27048 * VAL TODO: What to do with entities? 27049 */ 27050 TODO 27051 } 27052 /* 27053 * Read next node. 27054 */ 27055 ret = xmlTextReaderRead(vctxt->reader); 27056 } while (ret == 1); 27057 27058exit: 27059 return (ret); 27060internal_error: 27061 return (-1); 27062} 27063#endif 27064 27065/************************************************************************ 27066 * * 27067 * SAX validation handlers * 27068 * * 27069 ************************************************************************/ 27070 27071/* 27072* Process text content. 27073*/ 27074static void 27075xmlSchemaSAXHandleText(void *ctx, 27076 const xmlChar * ch, 27077 int len) 27078{ 27079 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27080 27081 if (vctxt->depth < 0) 27082 return; 27083 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27084 return; 27085 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27086 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27087 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27088 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27089 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27090 "calling xmlSchemaVPushText()"); 27091 vctxt->err = -1; 27092 xmlStopParser(vctxt->parserCtxt); 27093 } 27094} 27095 27096/* 27097* Process CDATA content. 27098*/ 27099static void 27100xmlSchemaSAXHandleCDataSection(void *ctx, 27101 const xmlChar * ch, 27102 int len) 27103{ 27104 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27105 27106 if (vctxt->depth < 0) 27107 return; 27108 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27109 return; 27110 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27111 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27112 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27113 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27114 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27115 "calling xmlSchemaVPushText()"); 27116 vctxt->err = -1; 27117 xmlStopParser(vctxt->parserCtxt); 27118 } 27119} 27120 27121static void 27122xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27123 const xmlChar * name ATTRIBUTE_UNUSED) 27124{ 27125 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27126 27127 if (vctxt->depth < 0) 27128 return; 27129 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27130 return; 27131 /* SAX VAL TODO: What to do here? */ 27132 TODO 27133} 27134 27135static void 27136xmlSchemaSAXHandleStartElementNs(void *ctx, 27137 const xmlChar * localname, 27138 const xmlChar * prefix ATTRIBUTE_UNUSED, 27139 const xmlChar * URI, 27140 int nb_namespaces, 27141 const xmlChar ** namespaces, 27142 int nb_attributes, 27143 int nb_defaulted ATTRIBUTE_UNUSED, 27144 const xmlChar ** attributes) 27145{ 27146 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27147 int ret; 27148 xmlSchemaNodeInfoPtr ielem; 27149 int i, j; 27150 27151 /* 27152 * SAX VAL TODO: What to do with nb_defaulted? 27153 */ 27154 /* 27155 * Skip elements if inside a "skip" wildcard or invalid. 27156 */ 27157 vctxt->depth++; 27158 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27159 return; 27160 /* 27161 * Push the element. 27162 */ 27163 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27164 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27165 "calling xmlSchemaValidatorPushElem()"); 27166 goto internal_error; 27167 } 27168 ielem = vctxt->inode; 27169 /* 27170 * TODO: Is this OK? 27171 */ 27172 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27173 ielem->localName = localname; 27174 ielem->nsName = URI; 27175 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27176 /* 27177 * Register namespaces on the elem info. 27178 */ 27179 if (nb_namespaces != 0) { 27180 /* 27181 * Although the parser builds its own namespace list, 27182 * we have no access to it, so we'll use an own one. 27183 */ 27184 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27185 /* 27186 * Store prefix and namespace name. 27187 */ 27188 if (ielem->nsBindings == NULL) { 27189 ielem->nsBindings = 27190 (const xmlChar **) xmlMalloc(10 * 27191 sizeof(const xmlChar *)); 27192 if (ielem->nsBindings == NULL) { 27193 xmlSchemaVErrMemory(vctxt, 27194 "allocating namespace bindings for SAX validation", 27195 NULL); 27196 goto internal_error; 27197 } 27198 ielem->nbNsBindings = 0; 27199 ielem->sizeNsBindings = 5; 27200 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27201 ielem->sizeNsBindings *= 2; 27202 ielem->nsBindings = 27203 (const xmlChar **) xmlRealloc( 27204 (void *) ielem->nsBindings, 27205 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27206 if (ielem->nsBindings == NULL) { 27207 xmlSchemaVErrMemory(vctxt, 27208 "re-allocating namespace bindings for SAX validation", 27209 NULL); 27210 goto internal_error; 27211 } 27212 } 27213 27214 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27215 if (namespaces[j+1][0] == 0) { 27216 /* 27217 * Handle xmlns="". 27218 */ 27219 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27220 } else 27221 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27222 namespaces[j+1]; 27223 ielem->nbNsBindings++; 27224 } 27225 } 27226 /* 27227 * Register attributes. 27228 * SAX VAL TODO: We are not adding namespace declaration 27229 * attributes yet. 27230 */ 27231 if (nb_attributes != 0) { 27232 xmlChar *value; 27233 27234 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27235 /* 27236 * Duplicate the value. 27237 */ 27238 value = xmlStrndup(attributes[j+3], 27239 attributes[j+4] - attributes[j+3]); 27240 /* 27241 * TODO: Set the node line. 27242 */ 27243 ret = xmlSchemaValidatorPushAttribute(vctxt, 27244 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27245 value, 1); 27246 if (ret == -1) { 27247 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27248 "calling xmlSchemaValidatorPushAttribute()"); 27249 goto internal_error; 27250 } 27251 } 27252 } 27253 /* 27254 * Validate the element. 27255 */ 27256 ret = xmlSchemaValidateElem(vctxt); 27257 if (ret != 0) { 27258 if (ret == -1) { 27259 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27260 "calling xmlSchemaValidateElem()"); 27261 goto internal_error; 27262 } 27263 goto exit; 27264 } 27265 27266exit: 27267 return; 27268internal_error: 27269 vctxt->err = -1; 27270 xmlStopParser(vctxt->parserCtxt); 27271 return; 27272} 27273 27274static void 27275xmlSchemaSAXHandleEndElementNs(void *ctx, 27276 const xmlChar * localname ATTRIBUTE_UNUSED, 27277 const xmlChar * prefix ATTRIBUTE_UNUSED, 27278 const xmlChar * URI ATTRIBUTE_UNUSED) 27279{ 27280 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27281 int res; 27282 27283 /* 27284 * Skip elements if inside a "skip" wildcard or if invalid. 27285 */ 27286 if (vctxt->skipDepth != -1) { 27287 if (vctxt->depth > vctxt->skipDepth) { 27288 vctxt->depth--; 27289 return; 27290 } else 27291 vctxt->skipDepth = -1; 27292 } 27293 /* 27294 * SAX VAL TODO: Just a temporary check. 27295 */ 27296 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27297 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27298 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27299 "elem pop mismatch"); 27300 } 27301 res = xmlSchemaValidatorPopElem(vctxt); 27302 if (res != 0) { 27303 if (res < 0) { 27304 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27305 "calling xmlSchemaValidatorPopElem()"); 27306 goto internal_error; 27307 } 27308 goto exit; 27309 } 27310exit: 27311 return; 27312internal_error: 27313 vctxt->err = -1; 27314 xmlStopParser(vctxt->parserCtxt); 27315 return; 27316} 27317 27318/************************************************************************ 27319 * * 27320 * Validation interfaces * 27321 * * 27322 ************************************************************************/ 27323 27324/** 27325 * xmlSchemaNewValidCtxt: 27326 * @schema: a precompiled XML Schemas 27327 * 27328 * Create an XML Schemas validation context based on the given schema. 27329 * 27330 * Returns the validation context or NULL in case of error 27331 */ 27332xmlSchemaValidCtxtPtr 27333xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27334{ 27335 xmlSchemaValidCtxtPtr ret; 27336 27337 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27338 if (ret == NULL) { 27339 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27340 return (NULL); 27341 } 27342 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27343 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27344 ret->dict = xmlDictCreate(); 27345 ret->nodeQNames = xmlSchemaItemListCreate(); 27346 ret->schema = schema; 27347 return (ret); 27348} 27349 27350/** 27351 * xmlSchemaClearValidCtxt: 27352 * @ctxt: the schema validation context 27353 * 27354 * Free the resources associated to the schema validation context; 27355 * leaves some fields alive intended for reuse of the context. 27356 */ 27357static void 27358xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27359{ 27360 if (vctxt == NULL) 27361 return; 27362 27363 /* 27364 * TODO: Should we clear the flags? 27365 * Might be problematic if one reuses the context 27366 * and assumes that the options remain the same. 27367 */ 27368 vctxt->flags = 0; 27369 vctxt->validationRoot = NULL; 27370 vctxt->doc = NULL; 27371#ifdef LIBXML_READER_ENABLED 27372 vctxt->reader = NULL; 27373#endif 27374 vctxt->hasKeyrefs = 0; 27375 27376 if (vctxt->value != NULL) { 27377 xmlSchemaFreeValue(vctxt->value); 27378 vctxt->value = NULL; 27379 } 27380 /* 27381 * Augmented IDC information. 27382 */ 27383 if (vctxt->aidcs != NULL) { 27384 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27385 do { 27386 next = cur->next; 27387 xmlFree(cur); 27388 cur = next; 27389 } while (cur != NULL); 27390 vctxt->aidcs = NULL; 27391 } 27392 if (vctxt->idcMatcherCache != NULL) { 27393 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27394 27395 while (matcher) { 27396 tmp = matcher; 27397 matcher = matcher->nextCached; 27398 xmlSchemaIDCFreeMatcherList(tmp); 27399 } 27400 vctxt->idcMatcherCache = NULL; 27401 } 27402 27403 27404 if (vctxt->idcNodes != NULL) { 27405 int i; 27406 xmlSchemaPSVIIDCNodePtr item; 27407 27408 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27409 item = vctxt->idcNodes[i]; 27410 xmlFree(item->keys); 27411 xmlFree(item); 27412 } 27413 xmlFree(vctxt->idcNodes); 27414 vctxt->idcNodes = NULL; 27415 vctxt->nbIdcNodes = 0; 27416 vctxt->sizeIdcNodes = 0; 27417 } 27418 /* 27419 * Note that we won't delete the XPath state pool here. 27420 */ 27421 if (vctxt->xpathStates != NULL) { 27422 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27423 vctxt->xpathStates = NULL; 27424 } 27425 /* 27426 * Attribute info. 27427 */ 27428 if (vctxt->nbAttrInfos != 0) { 27429 xmlSchemaClearAttrInfos(vctxt); 27430 } 27431 /* 27432 * Element info. 27433 */ 27434 if (vctxt->elemInfos != NULL) { 27435 int i; 27436 xmlSchemaNodeInfoPtr ei; 27437 27438 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27439 ei = vctxt->elemInfos[i]; 27440 if (ei == NULL) 27441 break; 27442 xmlSchemaClearElemInfo(vctxt, ei); 27443 } 27444 } 27445 xmlSchemaItemListClear(vctxt->nodeQNames); 27446 /* Recreate the dict. */ 27447 xmlDictFree(vctxt->dict); 27448 /* 27449 * TODO: Is is save to recreate it? Do we have a scenario 27450 * where the user provides the dict? 27451 */ 27452 vctxt->dict = xmlDictCreate(); 27453} 27454 27455/** 27456 * xmlSchemaFreeValidCtxt: 27457 * @ctxt: the schema validation context 27458 * 27459 * Free the resources associated to the schema validation context 27460 */ 27461void 27462xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27463{ 27464 if (ctxt == NULL) 27465 return; 27466 if (ctxt->value != NULL) 27467 xmlSchemaFreeValue(ctxt->value); 27468 if (ctxt->pctxt != NULL) 27469 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27470 if (ctxt->idcNodes != NULL) { 27471 int i; 27472 xmlSchemaPSVIIDCNodePtr item; 27473 27474 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27475 item = ctxt->idcNodes[i]; 27476 xmlFree(item->keys); 27477 xmlFree(item); 27478 } 27479 xmlFree(ctxt->idcNodes); 27480 } 27481 if (ctxt->idcKeys != NULL) { 27482 int i; 27483 for (i = 0; i < ctxt->nbIdcKeys; i++) 27484 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27485 xmlFree(ctxt->idcKeys); 27486 } 27487 27488 if (ctxt->xpathStates != NULL) { 27489 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27490 ctxt->xpathStates = NULL; 27491 } 27492 if (ctxt->xpathStatePool != NULL) { 27493 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27494 ctxt->xpathStatePool = NULL; 27495 } 27496 27497 /* 27498 * Augmented IDC information. 27499 */ 27500 if (ctxt->aidcs != NULL) { 27501 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27502 do { 27503 next = cur->next; 27504 xmlFree(cur); 27505 cur = next; 27506 } while (cur != NULL); 27507 } 27508 if (ctxt->attrInfos != NULL) { 27509 int i; 27510 xmlSchemaAttrInfoPtr attr; 27511 27512 /* Just a paranoid call to the cleanup. */ 27513 if (ctxt->nbAttrInfos != 0) 27514 xmlSchemaClearAttrInfos(ctxt); 27515 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27516 attr = ctxt->attrInfos[i]; 27517 xmlFree(attr); 27518 } 27519 xmlFree(ctxt->attrInfos); 27520 } 27521 if (ctxt->elemInfos != NULL) { 27522 int i; 27523 xmlSchemaNodeInfoPtr ei; 27524 27525 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27526 ei = ctxt->elemInfos[i]; 27527 if (ei == NULL) 27528 break; 27529 xmlSchemaClearElemInfo(ctxt, ei); 27530 xmlFree(ei); 27531 } 27532 xmlFree(ctxt->elemInfos); 27533 } 27534 if (ctxt->nodeQNames != NULL) 27535 xmlSchemaItemListFree(ctxt->nodeQNames); 27536 if (ctxt->dict != NULL) 27537 xmlDictFree(ctxt->dict); 27538 xmlFree(ctxt); 27539} 27540 27541/** 27542 * xmlSchemaIsValid: 27543 * @ctxt: the schema validation context 27544 * 27545 * Check if any error was detected during validation. 27546 * 27547 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27548 * of internal error. 27549 */ 27550int 27551xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27552{ 27553 if (ctxt == NULL) 27554 return(-1); 27555 return(ctxt->err == 0); 27556} 27557 27558/** 27559 * xmlSchemaSetValidErrors: 27560 * @ctxt: a schema validation context 27561 * @err: the error function 27562 * @warn: the warning function 27563 * @ctx: the functions context 27564 * 27565 * Set the error and warning callback informations 27566 */ 27567void 27568xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27569 xmlSchemaValidityErrorFunc err, 27570 xmlSchemaValidityWarningFunc warn, void *ctx) 27571{ 27572 if (ctxt == NULL) 27573 return; 27574 ctxt->error = err; 27575 ctxt->warning = warn; 27576 ctxt->errCtxt = ctx; 27577 if (ctxt->pctxt != NULL) 27578 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27579} 27580 27581/** 27582 * xmlSchemaSetValidStructuredErrors: 27583 * @ctxt: a schema validation context 27584 * @serror: the structured error function 27585 * @ctx: the functions context 27586 * 27587 * Set the structured error callback 27588 */ 27589void 27590xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27591 xmlStructuredErrorFunc serror, void *ctx) 27592{ 27593 if (ctxt == NULL) 27594 return; 27595 ctxt->serror = serror; 27596 ctxt->error = NULL; 27597 ctxt->warning = NULL; 27598 ctxt->errCtxt = ctx; 27599 if (ctxt->pctxt != NULL) 27600 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27601} 27602 27603/** 27604 * xmlSchemaGetValidErrors: 27605 * @ctxt: a XML-Schema validation context 27606 * @err: the error function result 27607 * @warn: the warning function result 27608 * @ctx: the functions context result 27609 * 27610 * Get the error and warning callback informations 27611 * 27612 * Returns -1 in case of error and 0 otherwise 27613 */ 27614int 27615xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27616 xmlSchemaValidityErrorFunc * err, 27617 xmlSchemaValidityWarningFunc * warn, void **ctx) 27618{ 27619 if (ctxt == NULL) 27620 return (-1); 27621 if (err != NULL) 27622 *err = ctxt->error; 27623 if (warn != NULL) 27624 *warn = ctxt->warning; 27625 if (ctx != NULL) 27626 *ctx = ctxt->errCtxt; 27627 return (0); 27628} 27629 27630 27631/** 27632 * xmlSchemaSetValidOptions: 27633 * @ctxt: a schema validation context 27634 * @options: a combination of xmlSchemaValidOption 27635 * 27636 * Sets the options to be used during the validation. 27637 * 27638 * Returns 0 in case of success, -1 in case of an 27639 * API error. 27640 */ 27641int 27642xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27643 int options) 27644 27645{ 27646 int i; 27647 27648 if (ctxt == NULL) 27649 return (-1); 27650 /* 27651 * WARNING: Change the start value if adding to the 27652 * xmlSchemaValidOption. 27653 * TODO: Is there an other, more easy to maintain, 27654 * way? 27655 */ 27656 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27657 if (options & 1<<i) 27658 return (-1); 27659 } 27660 ctxt->options = options; 27661 return (0); 27662} 27663 27664/** 27665 * xmlSchemaValidCtxtGetOptions: 27666 * @ctxt: a schema validation context 27667 * 27668 * Get the validation context options. 27669 * 27670 * Returns the option combination or -1 on error. 27671 */ 27672int 27673xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27674 27675{ 27676 if (ctxt == NULL) 27677 return (-1); 27678 else 27679 return (ctxt->options); 27680} 27681 27682static int 27683xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27684{ 27685 xmlAttrPtr attr; 27686 int ret = 0; 27687 xmlSchemaNodeInfoPtr ielem = NULL; 27688 xmlNodePtr node, valRoot; 27689 const xmlChar *nsName; 27690 27691 /* DOC VAL TODO: Move this to the start function. */ 27692 valRoot = xmlDocGetRootElement(vctxt->doc); 27693 if (valRoot == NULL) { 27694 /* VAL TODO: Error code? */ 27695 VERROR(1, NULL, "The document has no document element"); 27696 return (1); 27697 } 27698 vctxt->depth = -1; 27699 vctxt->validationRoot = valRoot; 27700 node = valRoot; 27701 while (node != NULL) { 27702 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27703 goto next_sibling; 27704 if (node->type == XML_ELEMENT_NODE) { 27705 27706 /* 27707 * Init the node-info. 27708 */ 27709 vctxt->depth++; 27710 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27711 goto internal_error; 27712 ielem = vctxt->inode; 27713 ielem->node = node; 27714 ielem->nodeLine = node->line; 27715 ielem->localName = node->name; 27716 if (node->ns != NULL) 27717 ielem->nsName = node->ns->href; 27718 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27719 /* 27720 * Register attributes. 27721 * DOC VAL TODO: We do not register namespace declaration 27722 * attributes yet. 27723 */ 27724 vctxt->nbAttrInfos = 0; 27725 if (node->properties != NULL) { 27726 attr = node->properties; 27727 do { 27728 if (attr->ns != NULL) 27729 nsName = attr->ns->href; 27730 else 27731 nsName = NULL; 27732 ret = xmlSchemaValidatorPushAttribute(vctxt, 27733 (xmlNodePtr) attr, 27734 /* 27735 * Note that we give it the line number of the 27736 * parent element. 27737 */ 27738 ielem->nodeLine, 27739 attr->name, nsName, 0, 27740 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27741 if (ret == -1) { 27742 VERROR_INT("xmlSchemaDocWalk", 27743 "calling xmlSchemaValidatorPushAttribute()"); 27744 goto internal_error; 27745 } 27746 attr = attr->next; 27747 } while (attr); 27748 } 27749 /* 27750 * Validate the element. 27751 */ 27752 ret = xmlSchemaValidateElem(vctxt); 27753 if (ret != 0) { 27754 if (ret == -1) { 27755 VERROR_INT("xmlSchemaDocWalk", 27756 "calling xmlSchemaValidateElem()"); 27757 goto internal_error; 27758 } 27759 /* 27760 * Don't stop validation; just skip the content 27761 * of this element. 27762 */ 27763 goto leave_node; 27764 } 27765 if ((vctxt->skipDepth != -1) && 27766 (vctxt->depth >= vctxt->skipDepth)) 27767 goto leave_node; 27768 } else if ((node->type == XML_TEXT_NODE) || 27769 (node->type == XML_CDATA_SECTION_NODE)) { 27770 /* 27771 * Process character content. 27772 */ 27773 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 27774 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27775 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 27776 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 27777 if (ret < 0) { 27778 VERROR_INT("xmlSchemaVDocWalk", 27779 "calling xmlSchemaVPushText()"); 27780 goto internal_error; 27781 } 27782 /* 27783 * DOC VAL TODO: Should we skip further validation of the 27784 * element content here? 27785 */ 27786 } else if ((node->type == XML_ENTITY_NODE) || 27787 (node->type == XML_ENTITY_REF_NODE)) { 27788 /* 27789 * DOC VAL TODO: What to do with entities? 27790 */ 27791 VERROR_INT("xmlSchemaVDocWalk", 27792 "there is at least one entity reference in the node-tree " 27793 "currently being validated. Processing of entities with " 27794 "this XML Schema processor is not supported (yet). Please " 27795 "substitute entities before validation."); 27796 goto internal_error; 27797 } else { 27798 goto leave_node; 27799 /* 27800 * DOC VAL TODO: XInclude nodes, etc. 27801 */ 27802 } 27803 /* 27804 * Walk the doc. 27805 */ 27806 if (node->children != NULL) { 27807 node = node->children; 27808 continue; 27809 } 27810leave_node: 27811 if (node->type == XML_ELEMENT_NODE) { 27812 /* 27813 * Leaving the scope of an element. 27814 */ 27815 if (node != vctxt->inode->node) { 27816 VERROR_INT("xmlSchemaVDocWalk", 27817 "element position mismatch"); 27818 goto internal_error; 27819 } 27820 ret = xmlSchemaValidatorPopElem(vctxt); 27821 if (ret != 0) { 27822 if (ret < 0) { 27823 VERROR_INT("xmlSchemaVDocWalk", 27824 "calling xmlSchemaValidatorPopElem()"); 27825 goto internal_error; 27826 } 27827 } 27828 if (node == valRoot) 27829 goto exit; 27830 } 27831next_sibling: 27832 if (node->next != NULL) 27833 node = node->next; 27834 else { 27835 node = node->parent; 27836 goto leave_node; 27837 } 27838 } 27839 27840exit: 27841 return (ret); 27842internal_error: 27843 return (-1); 27844} 27845 27846static int 27847xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 27848 /* 27849 * Some initialization. 27850 */ 27851 vctxt->err = 0; 27852 vctxt->nberrors = 0; 27853 vctxt->depth = -1; 27854 vctxt->skipDepth = -1; 27855 vctxt->xsiAssemble = 0; 27856 vctxt->hasKeyrefs = 0; 27857#ifdef ENABLE_IDC_NODE_TABLES_TEST 27858 vctxt->createIDCNodeTables = 1; 27859#else 27860 vctxt->createIDCNodeTables = 0; 27861#endif 27862 /* 27863 * Create a schema + parser if necessary. 27864 */ 27865 if (vctxt->schema == NULL) { 27866 xmlSchemaParserCtxtPtr pctxt; 27867 27868 vctxt->xsiAssemble = 1; 27869 /* 27870 * If not schema was given then we will create a schema 27871 * dynamically using XSI schema locations. 27872 * 27873 * Create the schema parser context. 27874 */ 27875 if ((vctxt->pctxt == NULL) && 27876 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 27877 return (-1); 27878 pctxt = vctxt->pctxt; 27879 pctxt->xsiAssemble = 1; 27880 /* 27881 * Create the schema. 27882 */ 27883 vctxt->schema = xmlSchemaNewSchema(pctxt); 27884 if (vctxt->schema == NULL) 27885 return (-1); 27886 /* 27887 * Create the schema construction context. 27888 */ 27889 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 27890 if (pctxt->constructor == NULL) 27891 return(-1); 27892 pctxt->constructor->mainSchema = vctxt->schema; 27893 /* 27894 * Take ownership of the constructor to be able to free it. 27895 */ 27896 pctxt->ownsConstructor = 1; 27897 } 27898 /* 27899 * Augment the IDC definitions. 27900 */ 27901 if (vctxt->schema->idcDef != NULL) { 27902 xmlHashScan(vctxt->schema->idcDef, 27903 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); 27904 } 27905 return(0); 27906} 27907 27908static void 27909xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 27910 if (vctxt->xsiAssemble) { 27911 if (vctxt->schema != NULL) { 27912 xmlSchemaFree(vctxt->schema); 27913 vctxt->schema = NULL; 27914 } 27915 } 27916 xmlSchemaClearValidCtxt(vctxt); 27917} 27918 27919static int 27920xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 27921{ 27922 int ret = 0; 27923 27924 if (xmlSchemaPreRun(vctxt) < 0) 27925 return(-1); 27926 27927 if (vctxt->doc != NULL) { 27928 /* 27929 * Tree validation. 27930 */ 27931 ret = xmlSchemaVDocWalk(vctxt); 27932#ifdef LIBXML_READER_ENABLED 27933 } else if (vctxt->reader != NULL) { 27934 /* 27935 * XML Reader validation. 27936 */ 27937#ifdef XML_SCHEMA_READER_ENABLED 27938 ret = xmlSchemaVReaderWalk(vctxt); 27939#endif 27940#endif 27941 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 27942 /* 27943 * SAX validation. 27944 */ 27945 ret = xmlParseDocument(vctxt->parserCtxt); 27946 } else { 27947 VERROR_INT("xmlSchemaVStart", 27948 "no instance to validate"); 27949 ret = -1; 27950 } 27951 27952 xmlSchemaPostRun(vctxt); 27953 if (ret == 0) 27954 ret = vctxt->err; 27955 return (ret); 27956} 27957 27958/** 27959 * xmlSchemaValidateOneElement: 27960 * @ctxt: a schema validation context 27961 * @elem: an element node 27962 * 27963 * Validate a branch of a tree, starting with the given @elem. 27964 * 27965 * Returns 0 if the element and its subtree is valid, a positive error 27966 * code number otherwise and -1 in case of an internal or API error. 27967 */ 27968int 27969xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 27970{ 27971 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 27972 return (-1); 27973 27974 if (ctxt->schema == NULL) 27975 return (-1); 27976 27977 ctxt->doc = elem->doc; 27978 ctxt->node = elem; 27979 ctxt->validationRoot = elem; 27980 return(xmlSchemaVStart(ctxt)); 27981} 27982 27983/** 27984 * xmlSchemaValidateDoc: 27985 * @ctxt: a schema validation context 27986 * @doc: a parsed document tree 27987 * 27988 * Validate a document tree in memory. 27989 * 27990 * Returns 0 if the document is schemas valid, a positive error code 27991 * number otherwise and -1 in case of internal or API error. 27992 */ 27993int 27994xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 27995{ 27996 if ((ctxt == NULL) || (doc == NULL)) 27997 return (-1); 27998 27999 ctxt->doc = doc; 28000 ctxt->node = xmlDocGetRootElement(doc); 28001 if (ctxt->node == NULL) { 28002 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28003 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28004 (xmlNodePtr) doc, NULL, 28005 "The document has no document element", NULL, NULL); 28006 return (ctxt->err); 28007 } 28008 ctxt->validationRoot = ctxt->node; 28009 return (xmlSchemaVStart(ctxt)); 28010} 28011 28012 28013/************************************************************************ 28014 * * 28015 * Function and data for SAX streaming API * 28016 * * 28017 ************************************************************************/ 28018typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28019typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28020 28021struct _xmlSchemaSplitSAXData { 28022 xmlSAXHandlerPtr user_sax; 28023 void *user_data; 28024 xmlSchemaValidCtxtPtr ctxt; 28025 xmlSAXHandlerPtr schemas_sax; 28026}; 28027 28028#define XML_SAX_PLUG_MAGIC 0xdc43ba21 28029 28030struct _xmlSchemaSAXPlug { 28031 unsigned int magic; 28032 28033 /* the original callbacks informations */ 28034 xmlSAXHandlerPtr *user_sax_ptr; 28035 xmlSAXHandlerPtr user_sax; 28036 void **user_data_ptr; 28037 void *user_data; 28038 28039 /* the block plugged back and validation informations */ 28040 xmlSAXHandler schemas_sax; 28041 xmlSchemaValidCtxtPtr ctxt; 28042}; 28043 28044/* All those functions just bounces to the user provided SAX handlers */ 28045static void 28046internalSubsetSplit(void *ctx, const xmlChar *name, 28047 const xmlChar *ExternalID, const xmlChar *SystemID) 28048{ 28049 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28050 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28051 (ctxt->user_sax->internalSubset != NULL)) 28052 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28053 SystemID); 28054} 28055 28056static int 28057isStandaloneSplit(void *ctx) 28058{ 28059 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28060 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28061 (ctxt->user_sax->isStandalone != NULL)) 28062 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28063 return(0); 28064} 28065 28066static int 28067hasInternalSubsetSplit(void *ctx) 28068{ 28069 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28070 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28071 (ctxt->user_sax->hasInternalSubset != NULL)) 28072 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28073 return(0); 28074} 28075 28076static int 28077hasExternalSubsetSplit(void *ctx) 28078{ 28079 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28080 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28081 (ctxt->user_sax->hasExternalSubset != NULL)) 28082 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28083 return(0); 28084} 28085 28086static void 28087externalSubsetSplit(void *ctx, const xmlChar *name, 28088 const xmlChar *ExternalID, const xmlChar *SystemID) 28089{ 28090 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28091 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28092 (ctxt->user_sax->internalSubset != NULL)) 28093 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28094 SystemID); 28095} 28096 28097static xmlParserInputPtr 28098resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28099{ 28100 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28101 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28102 (ctxt->user_sax->resolveEntity != NULL)) 28103 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28104 systemId)); 28105 return(NULL); 28106} 28107 28108static xmlEntityPtr 28109getEntitySplit(void *ctx, const xmlChar *name) 28110{ 28111 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28112 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28113 (ctxt->user_sax->getEntity != NULL)) 28114 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28115 return(NULL); 28116} 28117 28118static xmlEntityPtr 28119getParameterEntitySplit(void *ctx, const xmlChar *name) 28120{ 28121 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28122 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28123 (ctxt->user_sax->getParameterEntity != NULL)) 28124 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28125 return(NULL); 28126} 28127 28128 28129static void 28130entityDeclSplit(void *ctx, const xmlChar *name, int type, 28131 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28132{ 28133 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28134 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28135 (ctxt->user_sax->entityDecl != NULL)) 28136 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28137 systemId, content); 28138} 28139 28140static void 28141attributeDeclSplit(void *ctx, const xmlChar * elem, 28142 const xmlChar * name, int type, int def, 28143 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28144{ 28145 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28146 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28147 (ctxt->user_sax->attributeDecl != NULL)) { 28148 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28149 def, defaultValue, tree); 28150 } else { 28151 xmlFreeEnumeration(tree); 28152 } 28153} 28154 28155static void 28156elementDeclSplit(void *ctx, const xmlChar *name, int type, 28157 xmlElementContentPtr content) 28158{ 28159 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28160 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28161 (ctxt->user_sax->elementDecl != NULL)) 28162 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28163} 28164 28165static void 28166notationDeclSplit(void *ctx, const xmlChar *name, 28167 const xmlChar *publicId, const xmlChar *systemId) 28168{ 28169 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28170 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28171 (ctxt->user_sax->notationDecl != NULL)) 28172 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28173 systemId); 28174} 28175 28176static void 28177unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28178 const xmlChar *publicId, const xmlChar *systemId, 28179 const xmlChar *notationName) 28180{ 28181 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28182 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28183 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28184 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28185 systemId, notationName); 28186} 28187 28188static void 28189setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28190{ 28191 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28192 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28193 (ctxt->user_sax->setDocumentLocator != NULL)) 28194 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28195} 28196 28197static void 28198startDocumentSplit(void *ctx) 28199{ 28200 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28201 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28202 (ctxt->user_sax->startDocument != NULL)) 28203 ctxt->user_sax->startDocument(ctxt->user_data); 28204} 28205 28206static void 28207endDocumentSplit(void *ctx) 28208{ 28209 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28210 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28211 (ctxt->user_sax->endDocument != NULL)) 28212 ctxt->user_sax->endDocument(ctxt->user_data); 28213} 28214 28215static void 28216processingInstructionSplit(void *ctx, const xmlChar *target, 28217 const xmlChar *data) 28218{ 28219 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28220 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28221 (ctxt->user_sax->processingInstruction != NULL)) 28222 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28223} 28224 28225static void 28226commentSplit(void *ctx, const xmlChar *value) 28227{ 28228 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28229 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28230 (ctxt->user_sax->comment != NULL)) 28231 ctxt->user_sax->comment(ctxt->user_data, value); 28232} 28233 28234/* 28235 * Varargs error callbacks to the user application, harder ... 28236 */ 28237 28238static void XMLCDECL 28239warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28240 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28241 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28242 (ctxt->user_sax->warning != NULL)) { 28243 TODO 28244 } 28245} 28246static void XMLCDECL 28247errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28248 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28249 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28250 (ctxt->user_sax->error != NULL)) { 28251 TODO 28252 } 28253} 28254static void XMLCDECL 28255fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28256 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28257 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28258 (ctxt->user_sax->fatalError != NULL)) { 28259 TODO 28260 } 28261} 28262 28263/* 28264 * Those are function where both the user handler and the schemas handler 28265 * need to be called. 28266 */ 28267static void 28268charactersSplit(void *ctx, const xmlChar *ch, int len) 28269{ 28270 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28271 if (ctxt == NULL) 28272 return; 28273 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28274 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28275 if (ctxt->ctxt != NULL) 28276 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28277} 28278 28279static void 28280ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28281{ 28282 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28283 if (ctxt == NULL) 28284 return; 28285 if ((ctxt->user_sax != NULL) && 28286 (ctxt->user_sax->ignorableWhitespace != NULL)) 28287 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28288 if (ctxt->ctxt != NULL) 28289 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28290} 28291 28292static void 28293cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28294{ 28295 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28296 if (ctxt == NULL) 28297 return; 28298 if ((ctxt->user_sax != NULL) && 28299 (ctxt->user_sax->ignorableWhitespace != NULL)) 28300 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, value, len); 28301 if (ctxt->ctxt != NULL) 28302 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28303} 28304 28305static void 28306referenceSplit(void *ctx, const xmlChar *name) 28307{ 28308 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28309 if (ctxt == NULL) 28310 return; 28311 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28312 (ctxt->user_sax->reference != NULL)) 28313 ctxt->user_sax->reference(ctxt->user_data, name); 28314 if (ctxt->ctxt != NULL) 28315 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28316} 28317 28318static void 28319startElementNsSplit(void *ctx, const xmlChar * localname, 28320 const xmlChar * prefix, const xmlChar * URI, 28321 int nb_namespaces, const xmlChar ** namespaces, 28322 int nb_attributes, int nb_defaulted, 28323 const xmlChar ** attributes) { 28324 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28325 if (ctxt == NULL) 28326 return; 28327 if ((ctxt->user_sax != NULL) && 28328 (ctxt->user_sax->startElementNs != NULL)) 28329 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28330 URI, nb_namespaces, namespaces, 28331 nb_attributes, nb_defaulted, 28332 attributes); 28333 if (ctxt->ctxt != NULL) 28334 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28335 URI, nb_namespaces, namespaces, 28336 nb_attributes, nb_defaulted, 28337 attributes); 28338} 28339 28340static void 28341endElementNsSplit(void *ctx, const xmlChar * localname, 28342 const xmlChar * prefix, const xmlChar * URI) { 28343 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28344 if (ctxt == NULL) 28345 return; 28346 if ((ctxt->user_sax != NULL) && 28347 (ctxt->user_sax->endElementNs != NULL)) 28348 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28349 if (ctxt->ctxt != NULL) 28350 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28351} 28352 28353/** 28354 * xmlSchemaSAXPlug: 28355 * @ctxt: a schema validation context 28356 * @sax: a pointer to the original xmlSAXHandlerPtr 28357 * @user_data: a pointer to the original SAX user data pointer 28358 * 28359 * Plug a SAX based validation layer in a SAX parsing event flow. 28360 * The original @saxptr and @dataptr data are replaced by new pointers 28361 * but the calls to the original will be maintained. 28362 * 28363 * Returns a pointer to a data structure needed to unplug the validation layer 28364 * or NULL in case of errors. 28365 */ 28366xmlSchemaSAXPlugPtr 28367xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28368 xmlSAXHandlerPtr *sax, void **user_data) 28369{ 28370 xmlSchemaSAXPlugPtr ret; 28371 xmlSAXHandlerPtr old_sax; 28372 28373 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28374 return(NULL); 28375 28376 /* 28377 * We only allow to plug into SAX2 event streams 28378 */ 28379 old_sax = *sax; 28380 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28381 return(NULL); 28382 if ((old_sax != NULL) && 28383 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28384 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28385 return(NULL); 28386 28387 /* 28388 * everything seems right allocate the local data needed for that layer 28389 */ 28390 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28391 if (ret == NULL) { 28392 return(NULL); 28393 } 28394 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28395 ret->magic = XML_SAX_PLUG_MAGIC; 28396 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28397 ret->ctxt = ctxt; 28398 ret->user_sax_ptr = sax; 28399 ret->user_sax = old_sax; 28400 if (old_sax == NULL) { 28401 /* 28402 * go direct, no need for the split block and functions. 28403 */ 28404 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28405 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28406 /* 28407 * Note that we use the same text-function for both, to prevent 28408 * the parser from testing for ignorable whitespace. 28409 */ 28410 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28411 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28412 28413 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28414 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28415 28416 ret->user_data = ctxt; 28417 *user_data = ctxt; 28418 } else { 28419 /* 28420 * for each callback unused by Schemas initialize it to the Split 28421 * routine only if non NULL in the user block, this can speed up 28422 * things at the SAX level. 28423 */ 28424 if (old_sax->internalSubset != NULL) 28425 ret->schemas_sax.internalSubset = internalSubsetSplit; 28426 if (old_sax->isStandalone != NULL) 28427 ret->schemas_sax.isStandalone = isStandaloneSplit; 28428 if (old_sax->hasInternalSubset != NULL) 28429 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28430 if (old_sax->hasExternalSubset != NULL) 28431 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28432 if (old_sax->resolveEntity != NULL) 28433 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28434 if (old_sax->getEntity != NULL) 28435 ret->schemas_sax.getEntity = getEntitySplit; 28436 if (old_sax->entityDecl != NULL) 28437 ret->schemas_sax.entityDecl = entityDeclSplit; 28438 if (old_sax->notationDecl != NULL) 28439 ret->schemas_sax.notationDecl = notationDeclSplit; 28440 if (old_sax->attributeDecl != NULL) 28441 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28442 if (old_sax->elementDecl != NULL) 28443 ret->schemas_sax.elementDecl = elementDeclSplit; 28444 if (old_sax->unparsedEntityDecl != NULL) 28445 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28446 if (old_sax->setDocumentLocator != NULL) 28447 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28448 if (old_sax->startDocument != NULL) 28449 ret->schemas_sax.startDocument = startDocumentSplit; 28450 if (old_sax->endDocument != NULL) 28451 ret->schemas_sax.endDocument = endDocumentSplit; 28452 if (old_sax->processingInstruction != NULL) 28453 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28454 if (old_sax->comment != NULL) 28455 ret->schemas_sax.comment = commentSplit; 28456 if (old_sax->warning != NULL) 28457 ret->schemas_sax.warning = warningSplit; 28458 if (old_sax->error != NULL) 28459 ret->schemas_sax.error = errorSplit; 28460 if (old_sax->fatalError != NULL) 28461 ret->schemas_sax.fatalError = fatalErrorSplit; 28462 if (old_sax->getParameterEntity != NULL) 28463 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28464 if (old_sax->externalSubset != NULL) 28465 ret->schemas_sax.externalSubset = externalSubsetSplit; 28466 28467 /* 28468 * the 6 schemas callback have to go to the splitter functions 28469 * Note that we use the same text-function for ignorableWhitespace 28470 * if possible, to prevent the parser from testing for ignorable 28471 * whitespace. 28472 */ 28473 ret->schemas_sax.characters = charactersSplit; 28474 if ((old_sax->ignorableWhitespace != NULL) && 28475 (old_sax->ignorableWhitespace != old_sax->characters)) 28476 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28477 else 28478 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28479 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28480 ret->schemas_sax.reference = referenceSplit; 28481 ret->schemas_sax.startElementNs = startElementNsSplit; 28482 ret->schemas_sax.endElementNs = endElementNsSplit; 28483 28484 ret->user_data_ptr = user_data; 28485 ret->user_data = *user_data; 28486 *user_data = ret; 28487 } 28488 28489 /* 28490 * plug the pointers back. 28491 */ 28492 *sax = &(ret->schemas_sax); 28493 ctxt->sax = *sax; 28494 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28495 xmlSchemaPreRun(ctxt); 28496 return(ret); 28497} 28498 28499/** 28500 * xmlSchemaSAXUnplug: 28501 * @plug: a data structure returned by xmlSchemaSAXPlug 28502 * 28503 * Unplug a SAX based validation layer in a SAX parsing event flow. 28504 * The original pointers used in the call are restored. 28505 * 28506 * Returns 0 in case of success and -1 in case of failure. 28507 */ 28508int 28509xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28510{ 28511 xmlSAXHandlerPtr *sax; 28512 void **user_data; 28513 28514 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28515 return(-1); 28516 plug->magic = 0; 28517 28518 xmlSchemaPostRun(plug->ctxt); 28519 /* restore the data */ 28520 sax = plug->user_sax_ptr; 28521 *sax = plug->user_sax; 28522 if (plug->user_sax != NULL) { 28523 user_data = plug->user_data_ptr; 28524 *user_data = plug->user_data; 28525 } 28526 28527 /* free and return */ 28528 xmlFree(plug); 28529 return(0); 28530} 28531 28532/** 28533 * xmlSchemaValidateStream: 28534 * @ctxt: a schema validation context 28535 * @input: the input to use for reading the data 28536 * @enc: an optional encoding information 28537 * @sax: a SAX handler for the resulting events 28538 * @user_data: the context to provide to the SAX handler. 28539 * 28540 * Validate an input based on a flow of SAX event from the parser 28541 * and forward the events to the @sax handler with the provided @user_data 28542 * the user provided @sax handler must be a SAX2 one. 28543 * 28544 * Returns 0 if the document is schemas valid, a positive error code 28545 * number otherwise and -1 in case of internal or API error. 28546 */ 28547int 28548xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28549 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28550 xmlSAXHandlerPtr sax, void *user_data) 28551{ 28552 xmlSchemaSAXPlugPtr plug = NULL; 28553 xmlSAXHandlerPtr old_sax = NULL; 28554 xmlParserCtxtPtr pctxt = NULL; 28555 xmlParserInputPtr inputStream = NULL; 28556 int ret; 28557 28558 if ((ctxt == NULL) || (input == NULL)) 28559 return (-1); 28560 28561 /* 28562 * prepare the parser 28563 */ 28564 pctxt = xmlNewParserCtxt(); 28565 if (pctxt == NULL) 28566 return (-1); 28567 old_sax = pctxt->sax; 28568 pctxt->sax = sax; 28569 pctxt->userData = user_data; 28570#if 0 28571 if (options) 28572 xmlCtxtUseOptions(pctxt, options); 28573#endif 28574 pctxt->linenumbers = 1; 28575 28576 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28577 if (inputStream == NULL) { 28578 ret = -1; 28579 goto done; 28580 } 28581 inputPush(pctxt, inputStream); 28582 ctxt->parserCtxt = pctxt; 28583 ctxt->input = input; 28584 28585 /* 28586 * Plug the validation and launch the parsing 28587 */ 28588 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28589 if (plug == NULL) { 28590 ret = -1; 28591 goto done; 28592 } 28593 ctxt->input = input; 28594 ctxt->enc = enc; 28595 ctxt->sax = pctxt->sax; 28596 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28597 ret = xmlSchemaVStart(ctxt); 28598 28599 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28600 ret = ctxt->parserCtxt->errNo; 28601 if (ret == 0) 28602 ret = 1; 28603 } 28604 28605done: 28606 ctxt->parserCtxt = NULL; 28607 ctxt->sax = NULL; 28608 ctxt->input = NULL; 28609 if (plug != NULL) { 28610 xmlSchemaSAXUnplug(plug); 28611 } 28612 /* cleanup */ 28613 if (pctxt != NULL) { 28614 pctxt->sax = old_sax; 28615 xmlFreeParserCtxt(pctxt); 28616 } 28617 return (ret); 28618} 28619 28620/** 28621 * xmlSchemaValidateFile: 28622 * @ctxt: a schema validation context 28623 * @filename: the URI of the instance 28624 * @options: a future set of options, currently unused 28625 * 28626 * Do a schemas validation of the given resource, it will use the 28627 * SAX streamable validation internally. 28628 * 28629 * Returns 0 if the document is valid, a positive error code 28630 * number otherwise and -1 in case of an internal or API error. 28631 */ 28632int 28633xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28634 const char * filename, 28635 int options ATTRIBUTE_UNUSED) 28636{ 28637 int ret; 28638 xmlParserInputBufferPtr input; 28639 28640 if ((ctxt == NULL) || (filename == NULL)) 28641 return (-1); 28642 28643 input = xmlParserInputBufferCreateFilename(filename, 28644 XML_CHAR_ENCODING_NONE); 28645 if (input == NULL) 28646 return (-1); 28647 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28648 NULL, NULL); 28649 return (ret); 28650} 28651 28652#define bottom_xmlschemas 28653#include "elfgcchack.h" 28654#endif /* LIBXML_SCHEMAS_ENABLED */ 28655