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 char *filename; 979 980 int err; 981 int nberrors; 982 983 xmlNodePtr node; 984 xmlNodePtr cur; 985 /* xmlSchemaTypePtr type; */ 986 987 xmlRegExecCtxtPtr regexp; 988 xmlSchemaValPtr value; 989 990 int valueWS; 991 int options; 992 xmlNodePtr validationRoot; 993 xmlSchemaParserCtxtPtr pctxt; 994 int xsiAssemble; 995 996 int depth; 997 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 998 int sizeElemInfos; 999 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1000 1001 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1002 1003 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1004 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1005 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1006 1007 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1008 int nbIdcNodes; 1009 int sizeIdcNodes; 1010 1011 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1012 int nbIdcKeys; 1013 int sizeIdcKeys; 1014 1015 int flags; 1016 1017 xmlDictPtr dict; 1018 1019#ifdef LIBXML_READER_ENABLED 1020 xmlTextReaderPtr reader; 1021#endif 1022 1023 xmlSchemaAttrInfoPtr *attrInfos; 1024 int nbAttrInfos; 1025 int sizeAttrInfos; 1026 1027 int skipDepth; 1028 xmlSchemaItemListPtr nodeQNames; 1029 int hasKeyrefs; 1030 int createIDCNodeTables; 1031 int psviExposeIDCNodeTables; 1032 1033 /* Locator for error reporting in streaming mode */ 1034 xmlSchemaValidityLocatorFunc locFunc; 1035 void *locCtxt; 1036}; 1037 1038/** 1039 * xmlSchemaSubstGroup: 1040 * 1041 * 1042 */ 1043typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1044typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1045struct _xmlSchemaSubstGroup { 1046 xmlSchemaElementPtr head; 1047 xmlSchemaItemListPtr members; 1048}; 1049 1050/************************************************************************ 1051 * * 1052 * Some predeclarations * 1053 * * 1054 ************************************************************************/ 1055 1056static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1057 xmlSchemaPtr schema, 1058 xmlNodePtr node); 1059static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1060 xmlSchemaPtr schema, 1061 xmlNodePtr node); 1062static int 1063xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1064 xmlSchemaAbstractCtxtPtr ctxt); 1065static const xmlChar * 1066xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1067static int 1068xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070static int 1071xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1072 xmlSchemaParserCtxtPtr ctxt); 1073static void 1074xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1075static xmlSchemaWhitespaceValueType 1076xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1077static xmlSchemaTreeItemPtr 1078xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1079 xmlNodePtr node, xmlSchemaTypeType type, 1080 int withParticle); 1081static const xmlChar * 1082xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1083static xmlSchemaTypeLinkPtr 1084xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1085static void 1086xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1087 const char *funcName, 1088 const char *message); 1089static int 1090xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1091 xmlSchemaTypePtr type, 1092 xmlSchemaTypePtr baseType, 1093 int subset); 1094static void 1095xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1096 xmlSchemaParserCtxtPtr ctxt); 1097static void 1098xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1099static xmlSchemaQNameRefPtr 1100xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1101 xmlSchemaPtr schema, 1102 xmlNodePtr node); 1103 1104/************************************************************************ 1105 * * 1106 * Helper functions * 1107 * * 1108 ************************************************************************/ 1109 1110/** 1111 * xmlSchemaItemTypeToStr: 1112 * @type: the type of the schema item 1113 * 1114 * Returns the component name of a schema item. 1115 */ 1116static const xmlChar * 1117xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1118{ 1119 switch (type) { 1120 case XML_SCHEMA_TYPE_BASIC: 1121 return(BAD_CAST "simple type definition"); 1122 case XML_SCHEMA_TYPE_SIMPLE: 1123 return(BAD_CAST "simple type definition"); 1124 case XML_SCHEMA_TYPE_COMPLEX: 1125 return(BAD_CAST "complex type definition"); 1126 case XML_SCHEMA_TYPE_ELEMENT: 1127 return(BAD_CAST "element declaration"); 1128 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1129 return(BAD_CAST "attribute use"); 1130 case XML_SCHEMA_TYPE_ATTRIBUTE: 1131 return(BAD_CAST "attribute declaration"); 1132 case XML_SCHEMA_TYPE_GROUP: 1133 return(BAD_CAST "model group definition"); 1134 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1135 return(BAD_CAST "attribute group definition"); 1136 case XML_SCHEMA_TYPE_NOTATION: 1137 return(BAD_CAST "notation declaration"); 1138 case XML_SCHEMA_TYPE_SEQUENCE: 1139 return(BAD_CAST "model group (sequence)"); 1140 case XML_SCHEMA_TYPE_CHOICE: 1141 return(BAD_CAST "model group (choice)"); 1142 case XML_SCHEMA_TYPE_ALL: 1143 return(BAD_CAST "model group (all)"); 1144 case XML_SCHEMA_TYPE_PARTICLE: 1145 return(BAD_CAST "particle"); 1146 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1147 return(BAD_CAST "unique identity-constraint"); 1148 /* return(BAD_CAST "IDC (unique)"); */ 1149 case XML_SCHEMA_TYPE_IDC_KEY: 1150 return(BAD_CAST "key identity-constraint"); 1151 /* return(BAD_CAST "IDC (key)"); */ 1152 case XML_SCHEMA_TYPE_IDC_KEYREF: 1153 return(BAD_CAST "keyref identity-constraint"); 1154 /* return(BAD_CAST "IDC (keyref)"); */ 1155 case XML_SCHEMA_TYPE_ANY: 1156 return(BAD_CAST "wildcard (any)"); 1157 case XML_SCHEMA_EXTRA_QNAMEREF: 1158 return(BAD_CAST "[helper component] QName reference"); 1159 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1160 return(BAD_CAST "[helper component] attribute use prohibition"); 1161 default: 1162 return(BAD_CAST "Not a schema component"); 1163 } 1164} 1165 1166/** 1167 * xmlSchemaGetComponentTypeStr: 1168 * @type: the type of the schema item 1169 * 1170 * Returns the component name of a schema item. 1171 */ 1172static const xmlChar * 1173xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1174{ 1175 switch (item->type) { 1176 case XML_SCHEMA_TYPE_BASIC: 1177 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1178 return(BAD_CAST "complex type definition"); 1179 else 1180 return(BAD_CAST "simple type definition"); 1181 default: 1182 return(xmlSchemaItemTypeToStr(item->type)); 1183 } 1184} 1185 1186/** 1187 * xmlSchemaGetComponentNode: 1188 * @item: a schema component 1189 * 1190 * Returns node associated with the schema component. 1191 * NOTE that such a node need not be available; plus, a component's 1192 * node need not to reflect the component directly, since there is no 1193 * one-to-one relationship between the XML Schema representation and 1194 * the component representation. 1195 */ 1196static xmlNodePtr 1197xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1198{ 1199 switch (item->type) { 1200 case XML_SCHEMA_TYPE_ELEMENT: 1201 return (((xmlSchemaElementPtr) item)->node); 1202 case XML_SCHEMA_TYPE_ATTRIBUTE: 1203 return (((xmlSchemaAttributePtr) item)->node); 1204 case XML_SCHEMA_TYPE_COMPLEX: 1205 case XML_SCHEMA_TYPE_SIMPLE: 1206 return (((xmlSchemaTypePtr) item)->node); 1207 case XML_SCHEMA_TYPE_ANY: 1208 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1209 return (((xmlSchemaWildcardPtr) item)->node); 1210 case XML_SCHEMA_TYPE_PARTICLE: 1211 return (((xmlSchemaParticlePtr) item)->node); 1212 case XML_SCHEMA_TYPE_SEQUENCE: 1213 case XML_SCHEMA_TYPE_CHOICE: 1214 case XML_SCHEMA_TYPE_ALL: 1215 return (((xmlSchemaModelGroupPtr) item)->node); 1216 case XML_SCHEMA_TYPE_GROUP: 1217 return (((xmlSchemaModelGroupDefPtr) item)->node); 1218 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1219 return (((xmlSchemaAttributeGroupPtr) item)->node); 1220 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1221 case XML_SCHEMA_TYPE_IDC_KEY: 1222 case XML_SCHEMA_TYPE_IDC_KEYREF: 1223 return (((xmlSchemaIDCPtr) item)->node); 1224 case XML_SCHEMA_EXTRA_QNAMEREF: 1225 return(((xmlSchemaQNameRefPtr) item)->node); 1226 /* TODO: What to do with NOTATIONs? 1227 case XML_SCHEMA_TYPE_NOTATION: 1228 return (((xmlSchemaNotationPtr) item)->node); 1229 */ 1230 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1231 return (((xmlSchemaAttributeUsePtr) item)->node); 1232 default: 1233 return (NULL); 1234 } 1235} 1236 1237#if 0 1238/** 1239 * xmlSchemaGetNextComponent: 1240 * @item: a schema component 1241 * 1242 * Returns the next sibling of the schema component. 1243 */ 1244static xmlSchemaBasicItemPtr 1245xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1246{ 1247 switch (item->type) { 1248 case XML_SCHEMA_TYPE_ELEMENT: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1250 case XML_SCHEMA_TYPE_ATTRIBUTE: 1251 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1252 case XML_SCHEMA_TYPE_COMPLEX: 1253 case XML_SCHEMA_TYPE_SIMPLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1255 case XML_SCHEMA_TYPE_ANY: 1256 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1257 return (NULL); 1258 case XML_SCHEMA_TYPE_PARTICLE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1260 case XML_SCHEMA_TYPE_SEQUENCE: 1261 case XML_SCHEMA_TYPE_CHOICE: 1262 case XML_SCHEMA_TYPE_ALL: 1263 return (NULL); 1264 case XML_SCHEMA_TYPE_GROUP: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1268 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1269 case XML_SCHEMA_TYPE_IDC_KEY: 1270 case XML_SCHEMA_TYPE_IDC_KEYREF: 1271 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1272 default: 1273 return (NULL); 1274 } 1275} 1276#endif 1277 1278 1279/** 1280 * xmlSchemaFormatQName: 1281 * @buf: the string buffer 1282 * @namespaceName: the namespace name 1283 * @localName: the local name 1284 * 1285 * Returns the given QName in the format "{namespaceName}localName" or 1286 * just "localName" if @namespaceName is NULL. 1287 * 1288 * Returns the localName if @namespaceName is NULL, a formatted 1289 * string otherwise. 1290 */ 1291static const xmlChar* 1292xmlSchemaFormatQName(xmlChar **buf, 1293 const xmlChar *namespaceName, 1294 const xmlChar *localName) 1295{ 1296 FREE_AND_NULL(*buf) 1297 if (namespaceName != NULL) { 1298 *buf = xmlStrdup(BAD_CAST "{"); 1299 *buf = xmlStrcat(*buf, namespaceName); 1300 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1301 } 1302 if (localName != NULL) { 1303 if (namespaceName == NULL) 1304 return(localName); 1305 *buf = xmlStrcat(*buf, localName); 1306 } else { 1307 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1308 } 1309 return ((const xmlChar *) *buf); 1310} 1311 1312static const xmlChar* 1313xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1314{ 1315 if (ns != NULL) 1316 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1317 else 1318 return (xmlSchemaFormatQName(buf, NULL, localName)); 1319} 1320 1321static const xmlChar * 1322xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1323{ 1324 switch (item->type) { 1325 case XML_SCHEMA_TYPE_ELEMENT: 1326 return (((xmlSchemaElementPtr) item)->name); 1327 case XML_SCHEMA_TYPE_ATTRIBUTE: 1328 return (((xmlSchemaAttributePtr) item)->name); 1329 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1330 return (((xmlSchemaAttributeGroupPtr) item)->name); 1331 case XML_SCHEMA_TYPE_BASIC: 1332 case XML_SCHEMA_TYPE_SIMPLE: 1333 case XML_SCHEMA_TYPE_COMPLEX: 1334 return (((xmlSchemaTypePtr) item)->name); 1335 case XML_SCHEMA_TYPE_GROUP: 1336 return (((xmlSchemaModelGroupDefPtr) item)->name); 1337 case XML_SCHEMA_TYPE_IDC_KEY: 1338 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1339 case XML_SCHEMA_TYPE_IDC_KEYREF: 1340 return (((xmlSchemaIDCPtr) item)->name); 1341 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1342 if (WXS_ATTRUSE_DECL(item) != NULL) { 1343 return(xmlSchemaGetComponentName( 1344 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1345 } else 1346 return(NULL); 1347 case XML_SCHEMA_EXTRA_QNAMEREF: 1348 return (((xmlSchemaQNameRefPtr) item)->name); 1349 case XML_SCHEMA_TYPE_NOTATION: 1350 return (((xmlSchemaNotationPtr) item)->name); 1351 default: 1352 /* 1353 * Other components cannot have names. 1354 */ 1355 break; 1356 } 1357 return (NULL); 1358} 1359 1360#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1361#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1362/* 1363static const xmlChar * 1364xmlSchemaGetQNameRefName(void *ref) 1365{ 1366 return(((xmlSchemaQNameRefPtr) ref)->name); 1367} 1368 1369static const xmlChar * 1370xmlSchemaGetQNameRefTargetNs(void *ref) 1371{ 1372 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1373} 1374*/ 1375 1376static const xmlChar * 1377xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1378{ 1379 switch (item->type) { 1380 case XML_SCHEMA_TYPE_ELEMENT: 1381 return (((xmlSchemaElementPtr) item)->targetNamespace); 1382 case XML_SCHEMA_TYPE_ATTRIBUTE: 1383 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1384 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1385 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_BASIC: 1387 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1388 case XML_SCHEMA_TYPE_SIMPLE: 1389 case XML_SCHEMA_TYPE_COMPLEX: 1390 return (((xmlSchemaTypePtr) item)->targetNamespace); 1391 case XML_SCHEMA_TYPE_GROUP: 1392 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1393 case XML_SCHEMA_TYPE_IDC_KEY: 1394 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1395 case XML_SCHEMA_TYPE_IDC_KEYREF: 1396 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1397 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1398 if (WXS_ATTRUSE_DECL(item) != NULL) { 1399 return(xmlSchemaGetComponentTargetNs( 1400 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1401 } 1402 /* TODO: Will returning NULL break something? */ 1403 break; 1404 case XML_SCHEMA_EXTRA_QNAMEREF: 1405 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1406 case XML_SCHEMA_TYPE_NOTATION: 1407 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1408 default: 1409 /* 1410 * Other components cannot have names. 1411 */ 1412 break; 1413 } 1414 return (NULL); 1415} 1416 1417static const xmlChar* 1418xmlSchemaGetComponentQName(xmlChar **buf, 1419 void *item) 1420{ 1421 return (xmlSchemaFormatQName(buf, 1422 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1423 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1424} 1425 1426static const xmlChar* 1427xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1428{ 1429 xmlChar *str = NULL; 1430 1431 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1432 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1433 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1434 (xmlSchemaBasicItemPtr) item)); 1435 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1436 FREE_AND_NULL(str); 1437 return(*buf); 1438} 1439 1440static const xmlChar* 1441xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1442{ 1443 return(xmlSchemaGetComponentDesignation(buf, idc)); 1444} 1445 1446/** 1447 * xmlSchemaWildcardPCToString: 1448 * @pc: the type of processContents 1449 * 1450 * Returns a string representation of the type of 1451 * processContents. 1452 */ 1453static const xmlChar * 1454xmlSchemaWildcardPCToString(int pc) 1455{ 1456 switch (pc) { 1457 case XML_SCHEMAS_ANY_SKIP: 1458 return (BAD_CAST "skip"); 1459 case XML_SCHEMAS_ANY_LAX: 1460 return (BAD_CAST "lax"); 1461 case XML_SCHEMAS_ANY_STRICT: 1462 return (BAD_CAST "strict"); 1463 default: 1464 return (BAD_CAST "invalid process contents"); 1465 } 1466} 1467 1468/** 1469 * xmlSchemaGetCanonValueWhtspExt: 1470 * @val: the precomputed value 1471 * @retValue: the returned value 1472 * @ws: the whitespace type of the value 1473 * 1474 * Get a the canonical representation of the value. 1475 * The caller has to free the returned retValue. 1476 * 1477 * Returns 0 if the value could be built and -1 in case of 1478 * API errors or if the value type is not supported yet. 1479 */ 1480static int 1481xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1482 xmlSchemaWhitespaceValueType ws, 1483 xmlChar **retValue) 1484{ 1485 int list; 1486 xmlSchemaValType valType; 1487 const xmlChar *value, *value2 = NULL; 1488 1489 1490 if ((retValue == NULL) || (val == NULL)) 1491 return (-1); 1492 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1493 *retValue = NULL; 1494 do { 1495 value = NULL; 1496 valType = xmlSchemaGetValType(val); 1497 switch (valType) { 1498 case XML_SCHEMAS_STRING: 1499 case XML_SCHEMAS_NORMSTRING: 1500 case XML_SCHEMAS_ANYSIMPLETYPE: 1501 value = xmlSchemaValueGetAsString(val); 1502 if (value != NULL) { 1503 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1504 value2 = xmlSchemaCollapseString(value); 1505 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1506 value2 = xmlSchemaWhiteSpaceReplace(value); 1507 if (value2 != NULL) 1508 value = value2; 1509 } 1510 break; 1511 default: 1512 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1513 if (value2 != NULL) 1514 xmlFree((xmlChar *) value2); 1515 goto internal_error; 1516 } 1517 value = value2; 1518 } 1519 if (*retValue == NULL) 1520 if (value == NULL) { 1521 if (! list) 1522 *retValue = xmlStrdup(BAD_CAST ""); 1523 } else 1524 *retValue = xmlStrdup(value); 1525 else if (value != NULL) { 1526 /* List. */ 1527 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1528 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1529 } 1530 FREE_AND_NULL(value2) 1531 val = xmlSchemaValueGetNext(val); 1532 } while (val != NULL); 1533 1534 return (0); 1535internal_error: 1536 if (*retValue != NULL) 1537 xmlFree((xmlChar *) (*retValue)); 1538 if (value2 != NULL) 1539 xmlFree((xmlChar *) value2); 1540 return (-1); 1541} 1542 1543/** 1544 * xmlSchemaFormatItemForReport: 1545 * @buf: the string buffer 1546 * @itemDes: the designation of the item 1547 * @itemName: the name of the item 1548 * @item: the item as an object 1549 * @itemNode: the node of the item 1550 * @local: the local name 1551 * @parsing: if the function is used during the parse 1552 * 1553 * Returns a representation of the given item used 1554 * for error reports. 1555 * 1556 * The following order is used to build the resulting 1557 * designation if the arguments are not NULL: 1558 * 1a. If itemDes not NULL -> itemDes 1559 * 1b. If (itemDes not NULL) and (itemName not NULL) 1560 * -> itemDes + itemName 1561 * 2. If the preceding was NULL and (item not NULL) -> item 1562 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1563 * 1564 * If the itemNode is an attribute node, the name of the attribute 1565 * will be appended to the result. 1566 * 1567 * Returns the formatted string and sets @buf to the resulting value. 1568 */ 1569static xmlChar* 1570xmlSchemaFormatItemForReport(xmlChar **buf, 1571 const xmlChar *itemDes, 1572 xmlSchemaBasicItemPtr item, 1573 xmlNodePtr itemNode) 1574{ 1575 xmlChar *str = NULL; 1576 int named = 1; 1577 1578 if (*buf != NULL) { 1579 xmlFree(*buf); 1580 *buf = NULL; 1581 } 1582 1583 if (itemDes != NULL) { 1584 *buf = xmlStrdup(itemDes); 1585 } else if (item != NULL) { 1586 switch (item->type) { 1587 case XML_SCHEMA_TYPE_BASIC: { 1588 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1589 1590 if (WXS_IS_ATOMIC(type)) 1591 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1592 else if (WXS_IS_LIST(type)) 1593 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1594 else if (WXS_IS_UNION(type)) 1595 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1596 else 1597 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1598 *buf = xmlStrcat(*buf, type->name); 1599 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1600 } 1601 break; 1602 case XML_SCHEMA_TYPE_SIMPLE: { 1603 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1604 1605 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1606 *buf = xmlStrdup(BAD_CAST""); 1607 } else { 1608 *buf = xmlStrdup(BAD_CAST "local "); 1609 } 1610 if (WXS_IS_ATOMIC(type)) 1611 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1612 else if (WXS_IS_LIST(type)) 1613 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1614 else if (WXS_IS_UNION(type)) 1615 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1616 else 1617 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1618 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1619 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1620 *buf = xmlStrcat(*buf, type->name); 1621 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1622 } 1623 } 1624 break; 1625 case XML_SCHEMA_TYPE_COMPLEX: { 1626 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1627 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1629 *buf = xmlStrdup(BAD_CAST ""); 1630 else 1631 *buf = xmlStrdup(BAD_CAST "local "); 1632 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1633 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1634 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1635 *buf = xmlStrcat(*buf, type->name); 1636 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1637 } 1638 } 1639 break; 1640 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1641 xmlSchemaAttributeUsePtr ause; 1642 1643 ause = WXS_ATTR_USE_CAST item; 1644 *buf = xmlStrdup(BAD_CAST "attribute use "); 1645 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1646 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1647 *buf = xmlStrcat(*buf, 1648 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1649 FREE_AND_NULL(str) 1650 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1651 } else { 1652 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1653 } 1654 } 1655 break; 1656 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1657 xmlSchemaAttributePtr attr; 1658 1659 attr = (xmlSchemaAttributePtr) item; 1660 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1661 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1662 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1663 attr->targetNamespace, attr->name)); 1664 FREE_AND_NULL(str) 1665 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1666 } 1667 break; 1668 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1669 xmlSchemaGetComponentDesignation(buf, item); 1670 break; 1671 case XML_SCHEMA_TYPE_ELEMENT: { 1672 xmlSchemaElementPtr elem; 1673 1674 elem = (xmlSchemaElementPtr) item; 1675 *buf = xmlStrdup(BAD_CAST "element decl."); 1676 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1677 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1678 elem->targetNamespace, elem->name)); 1679 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1680 } 1681 break; 1682 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1683 case XML_SCHEMA_TYPE_IDC_KEY: 1684 case XML_SCHEMA_TYPE_IDC_KEYREF: 1685 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1686 *buf = xmlStrdup(BAD_CAST "unique '"); 1687 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1688 *buf = xmlStrdup(BAD_CAST "key '"); 1689 else 1690 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1691 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1692 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1693 break; 1694 case XML_SCHEMA_TYPE_ANY: 1695 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1696 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1697 ((xmlSchemaWildcardPtr) item)->processContents)); 1698 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1699 break; 1700 case XML_SCHEMA_FACET_MININCLUSIVE: 1701 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1702 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1703 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1704 case XML_SCHEMA_FACET_TOTALDIGITS: 1705 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1706 case XML_SCHEMA_FACET_PATTERN: 1707 case XML_SCHEMA_FACET_ENUMERATION: 1708 case XML_SCHEMA_FACET_WHITESPACE: 1709 case XML_SCHEMA_FACET_LENGTH: 1710 case XML_SCHEMA_FACET_MAXLENGTH: 1711 case XML_SCHEMA_FACET_MINLENGTH: 1712 *buf = xmlStrdup(BAD_CAST "facet '"); 1713 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1714 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1715 break; 1716 case XML_SCHEMA_TYPE_GROUP: { 1717 *buf = xmlStrdup(BAD_CAST "model group def."); 1718 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1719 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1720 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1721 FREE_AND_NULL(str) 1722 } 1723 break; 1724 case XML_SCHEMA_TYPE_SEQUENCE: 1725 case XML_SCHEMA_TYPE_CHOICE: 1726 case XML_SCHEMA_TYPE_ALL: 1727 case XML_SCHEMA_TYPE_PARTICLE: 1728 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1729 break; 1730 case XML_SCHEMA_TYPE_NOTATION: { 1731 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1732 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1733 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1734 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1735 FREE_AND_NULL(str); 1736 } 1737 default: 1738 named = 0; 1739 } 1740 } else 1741 named = 0; 1742 1743 if ((named == 0) && (itemNode != NULL)) { 1744 xmlNodePtr elem; 1745 1746 if (itemNode->type == XML_ATTRIBUTE_NODE) 1747 elem = itemNode->parent; 1748 else 1749 elem = itemNode; 1750 *buf = xmlStrdup(BAD_CAST "Element '"); 1751 if (elem->ns != NULL) { 1752 *buf = xmlStrcat(*buf, 1753 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1754 FREE_AND_NULL(str) 1755 } else 1756 *buf = xmlStrcat(*buf, elem->name); 1757 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1758 1759 } 1760 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1761 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1762 if (itemNode->ns != NULL) { 1763 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1764 itemNode->ns->href, itemNode->name)); 1765 FREE_AND_NULL(str) 1766 } else 1767 *buf = xmlStrcat(*buf, itemNode->name); 1768 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1769 } 1770 FREE_AND_NULL(str) 1771 1772 return (*buf); 1773} 1774 1775/** 1776 * xmlSchemaFormatFacetEnumSet: 1777 * @buf: the string buffer 1778 * @type: the type holding the enumeration facets 1779 * 1780 * Builds a string consisting of all enumeration elements. 1781 * 1782 * Returns a string of all enumeration elements. 1783 */ 1784static const xmlChar * 1785xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1786 xmlChar **buf, xmlSchemaTypePtr type) 1787{ 1788 xmlSchemaFacetPtr facet; 1789 xmlSchemaWhitespaceValueType ws; 1790 xmlChar *value = NULL; 1791 int res, found = 0; 1792 1793 if (*buf != NULL) 1794 xmlFree(*buf); 1795 *buf = NULL; 1796 1797 do { 1798 /* 1799 * Use the whitespace type of the base type. 1800 */ 1801 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1802 for (facet = type->facets; facet != NULL; facet = facet->next) { 1803 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1804 continue; 1805 found = 1; 1806 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1807 ws, &value); 1808 if (res == -1) { 1809 xmlSchemaInternalErr(actxt, 1810 "xmlSchemaFormatFacetEnumSet", 1811 "compute the canonical lexical representation"); 1812 if (*buf != NULL) 1813 xmlFree(*buf); 1814 *buf = NULL; 1815 return (NULL); 1816 } 1817 if (*buf == NULL) 1818 *buf = xmlStrdup(BAD_CAST "'"); 1819 else 1820 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1821 *buf = xmlStrcat(*buf, BAD_CAST value); 1822 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1823 if (value != NULL) { 1824 xmlFree((xmlChar *)value); 1825 value = NULL; 1826 } 1827 } 1828 /* 1829 * The enumeration facet of a type restricts the enumeration 1830 * facet of the ancestor type; i.e., such restricted enumerations 1831 * do not belong to the set of the given type. Thus we break 1832 * on the first found enumeration. 1833 */ 1834 if (found) 1835 break; 1836 type = type->baseType; 1837 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1838 1839 return ((const xmlChar *) *buf); 1840} 1841 1842/************************************************************************ 1843 * * 1844 * Error functions * 1845 * * 1846 ************************************************************************/ 1847 1848#if 0 1849static void 1850xmlSchemaErrMemory(const char *msg) 1851{ 1852 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1853 msg); 1854} 1855#endif 1856 1857static void 1858xmlSchemaPSimpleErr(const char *msg) 1859{ 1860 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1861 msg); 1862} 1863 1864/** 1865 * xmlSchemaPErrMemory: 1866 * @node: a context node 1867 * @extra: extra informations 1868 * 1869 * Handle an out of memory condition 1870 */ 1871static void 1872xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1873 const char *extra, xmlNodePtr node) 1874{ 1875 if (ctxt != NULL) 1876 ctxt->nberrors++; 1877 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1878 extra); 1879} 1880 1881/** 1882 * xmlSchemaPErr: 1883 * @ctxt: the parsing context 1884 * @node: the context node 1885 * @error: the error code 1886 * @msg: the error message 1887 * @str1: extra data 1888 * @str2: extra data 1889 * 1890 * Handle a parser error 1891 */ 1892static void 1893xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1894 const char *msg, const xmlChar * str1, const xmlChar * str2) 1895{ 1896 xmlGenericErrorFunc channel = NULL; 1897 xmlStructuredErrorFunc schannel = NULL; 1898 void *data = NULL; 1899 1900 if (ctxt != NULL) { 1901 ctxt->nberrors++; 1902 ctxt->err = error; 1903 channel = ctxt->error; 1904 data = ctxt->errCtxt; 1905 schannel = ctxt->serror; 1906 } 1907 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1908 error, XML_ERR_ERROR, NULL, 0, 1909 (const char *) str1, (const char *) str2, NULL, 0, 0, 1910 msg, str1, str2); 1911} 1912 1913/** 1914 * xmlSchemaPErr2: 1915 * @ctxt: the parsing context 1916 * @node: the context node 1917 * @node: the current child 1918 * @error: the error code 1919 * @msg: the error message 1920 * @str1: extra data 1921 * @str2: extra data 1922 * 1923 * Handle a parser error 1924 */ 1925static void 1926xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1927 xmlNodePtr child, int error, 1928 const char *msg, const xmlChar * str1, const xmlChar * str2) 1929{ 1930 if (child != NULL) 1931 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1932 else 1933 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1934} 1935 1936 1937/** 1938 * xmlSchemaPErrExt: 1939 * @ctxt: the parsing context 1940 * @node: the context node 1941 * @error: the error code 1942 * @strData1: extra data 1943 * @strData2: extra data 1944 * @strData3: extra data 1945 * @msg: the message 1946 * @str1: extra parameter for the message display 1947 * @str2: extra parameter for the message display 1948 * @str3: extra parameter for the message display 1949 * @str4: extra parameter for the message display 1950 * @str5: extra parameter for the message display 1951 * 1952 * Handle a parser error 1953 */ 1954static void 1955xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1956 const xmlChar * strData1, const xmlChar * strData2, 1957 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1958 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1959 const xmlChar * str5) 1960{ 1961 1962 xmlGenericErrorFunc channel = NULL; 1963 xmlStructuredErrorFunc schannel = NULL; 1964 void *data = NULL; 1965 1966 if (ctxt != NULL) { 1967 ctxt->nberrors++; 1968 ctxt->err = error; 1969 channel = ctxt->error; 1970 data = ctxt->errCtxt; 1971 schannel = ctxt->serror; 1972 } 1973 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1974 error, XML_ERR_ERROR, NULL, 0, 1975 (const char *) strData1, (const char *) strData2, 1976 (const char *) strData3, 0, 0, msg, str1, str2, 1977 str3, str4, str5); 1978} 1979 1980/************************************************************************ 1981 * * 1982 * Allround error functions * 1983 * * 1984 ************************************************************************/ 1985 1986/** 1987 * xmlSchemaVTypeErrMemory: 1988 * @node: a context node 1989 * @extra: extra informations 1990 * 1991 * Handle an out of memory condition 1992 */ 1993static void 1994xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1995 const char *extra, xmlNodePtr node) 1996{ 1997 if (ctxt != NULL) { 1998 ctxt->nberrors++; 1999 ctxt->err = XML_SCHEMAV_INTERNAL; 2000 } 2001 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2002 extra); 2003} 2004 2005static void 2006xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2007 const char *msg, const xmlChar *str) 2008{ 2009 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2010 msg, (const char *) str); 2011} 2012 2013#define WXS_ERROR_TYPE_ERROR 1 2014#define WXS_ERROR_TYPE_WARNING 2 2015/** 2016 * xmlSchemaErr3: 2017 * @ctxt: the validation context 2018 * @node: the context node 2019 * @error: the error code 2020 * @msg: the error message 2021 * @str1: extra data 2022 * @str2: extra data 2023 * @str3: extra data 2024 * 2025 * Handle a validation error 2026 */ 2027static void 2028xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2029 xmlErrorLevel errorLevel, 2030 int error, xmlNodePtr node, int line, const char *msg, 2031 const xmlChar *str1, const xmlChar *str2, 2032 const xmlChar *str3, const xmlChar *str4) 2033{ 2034 xmlStructuredErrorFunc schannel = NULL; 2035 xmlGenericErrorFunc channel = NULL; 2036 void *data = NULL; 2037 2038 if (ctxt != NULL) { 2039 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2040 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2041 const char *file = NULL; 2042 int col = 0; 2043 if (errorLevel != XML_ERR_WARNING) { 2044 vctxt->nberrors++; 2045 vctxt->err = error; 2046 channel = vctxt->error; 2047 } else { 2048 channel = vctxt->warning; 2049 } 2050 schannel = vctxt->serror; 2051 data = vctxt->errCtxt; 2052 2053 /* 2054 * Error node. If we specify a line number, then 2055 * do not channel any node to the error function. 2056 */ 2057 if (line == 0) { 2058 if ((node == NULL) && 2059 (vctxt->depth >= 0) && 2060 (vctxt->inode != NULL)) { 2061 node = vctxt->inode->node; 2062 } 2063 /* 2064 * Get filename and line if no node-tree. 2065 */ 2066 if ((node == NULL) && 2067 (vctxt->parserCtxt != NULL) && 2068 (vctxt->parserCtxt->input != NULL)) { 2069 file = vctxt->parserCtxt->input->filename; 2070 line = vctxt->parserCtxt->input->line; 2071 col = vctxt->parserCtxt->input->col; 2072 } 2073 } else { 2074 /* 2075 * Override the given node's (if any) position 2076 * and channel only the given line number. 2077 */ 2078 node = NULL; 2079 /* 2080 * Get filename. 2081 */ 2082 if (vctxt->doc != NULL) 2083 file = (const char *) vctxt->doc->URL; 2084 else if ((vctxt->parserCtxt != NULL) && 2085 (vctxt->parserCtxt->input != NULL)) 2086 file = vctxt->parserCtxt->input->filename; 2087 } 2088 if (vctxt->locFunc != NULL) { 2089 if ((file == NULL) || (line == 0)) { 2090 unsigned long l; 2091 const char *f; 2092 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2093 if (file == NULL) 2094 file = f; 2095 if (line == 0) 2096 line = (int) l; 2097 } 2098 } 2099 if ((file == NULL) && (vctxt->filename != NULL)) 2100 file = vctxt->filename; 2101 2102 __xmlRaiseError(schannel, channel, data, ctxt, 2103 node, XML_FROM_SCHEMASV, 2104 error, errorLevel, file, line, 2105 (const char *) str1, (const char *) str2, 2106 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2107 2108 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2109 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2110 if (errorLevel != XML_ERR_WARNING) { 2111 pctxt->nberrors++; 2112 pctxt->err = error; 2113 channel = pctxt->error; 2114 } else { 2115 channel = pctxt->warning; 2116 } 2117 schannel = pctxt->serror; 2118 data = pctxt->errCtxt; 2119 __xmlRaiseError(schannel, channel, data, ctxt, 2120 node, XML_FROM_SCHEMASP, error, 2121 errorLevel, NULL, 0, 2122 (const char *) str1, (const char *) str2, 2123 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2124 } else { 2125 TODO 2126 } 2127 } 2128} 2129 2130/** 2131 * xmlSchemaErr3: 2132 * @ctxt: the validation context 2133 * @node: the context node 2134 * @error: the error code 2135 * @msg: the error message 2136 * @str1: extra data 2137 * @str2: extra data 2138 * @str3: extra data 2139 * 2140 * Handle a validation error 2141 */ 2142static void 2143xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2144 int error, xmlNodePtr node, const char *msg, 2145 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2146{ 2147 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2148 msg, str1, str2, str3, NULL); 2149} 2150 2151static void 2152xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2153 int error, xmlNodePtr node, const char *msg, 2154 const xmlChar *str1, const xmlChar *str2, 2155 const xmlChar *str3, const xmlChar *str4) 2156{ 2157 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2158 msg, str1, str2, str3, str4); 2159} 2160 2161static void 2162xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2163 int error, xmlNodePtr node, const char *msg, 2164 const xmlChar *str1, const xmlChar *str2) 2165{ 2166 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2167} 2168 2169static xmlChar * 2170xmlSchemaFormatNodeForError(xmlChar ** msg, 2171 xmlSchemaAbstractCtxtPtr actxt, 2172 xmlNodePtr node) 2173{ 2174 xmlChar *str = NULL; 2175 2176 *msg = NULL; 2177 if ((node != NULL) && 2178 (node->type != XML_ELEMENT_NODE) && 2179 (node->type != XML_ATTRIBUTE_NODE)) 2180 { 2181 /* 2182 * Don't try to format other nodes than element and 2183 * attribute nodes. 2184 * Play save and return an empty string. 2185 */ 2186 *msg = xmlStrdup(BAD_CAST ""); 2187 return(*msg); 2188 } 2189 if (node != NULL) { 2190 /* 2191 * Work on tree nodes. 2192 */ 2193 if (node->type == XML_ATTRIBUTE_NODE) { 2194 xmlNodePtr elem = node->parent; 2195 2196 *msg = xmlStrdup(BAD_CAST "Element '"); 2197 if (elem->ns != NULL) 2198 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2199 elem->ns->href, elem->name)); 2200 else 2201 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2202 NULL, elem->name)); 2203 FREE_AND_NULL(str); 2204 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2205 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2206 } else { 2207 *msg = xmlStrdup(BAD_CAST "Element '"); 2208 } 2209 if (node->ns != NULL) 2210 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2211 node->ns->href, node->name)); 2212 else 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 NULL, node->name)); 2215 FREE_AND_NULL(str); 2216 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2217 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2218 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2219 /* 2220 * Work on node infos. 2221 */ 2222 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2223 xmlSchemaNodeInfoPtr ielem = 2224 vctxt->elemInfos[vctxt->depth]; 2225 2226 *msg = xmlStrdup(BAD_CAST "Element '"); 2227 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2228 ielem->nsName, ielem->localName)); 2229 FREE_AND_NULL(str); 2230 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2231 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2232 } else { 2233 *msg = xmlStrdup(BAD_CAST "Element '"); 2234 } 2235 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2236 vctxt->inode->nsName, vctxt->inode->localName)); 2237 FREE_AND_NULL(str); 2238 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2239 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2240 /* 2241 * Hmm, no node while parsing? 2242 * Return an empty string, in case NULL will break something. 2243 */ 2244 *msg = xmlStrdup(BAD_CAST ""); 2245 } else { 2246 TODO 2247 return (NULL); 2248 } 2249 /* 2250 * VAL TODO: The output of the given schema component is currently 2251 * disabled. 2252 */ 2253#if 0 2254 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2255 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2256 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2257 NULL, type, NULL, 0)); 2258 FREE_AND_NULL(str) 2259 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2260 } 2261#endif 2262 return (*msg); 2263} 2264 2265static void 2266xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2267 const char *funcName, 2268 const char *message, 2269 const xmlChar *str1, 2270 const xmlChar *str2) 2271{ 2272 xmlChar *msg = NULL; 2273 2274 if (actxt == NULL) 2275 return; 2276 msg = xmlStrdup(BAD_CAST "Internal error: "); 2277 msg = xmlStrcat(msg, BAD_CAST funcName); 2278 msg = xmlStrcat(msg, BAD_CAST ", "); 2279 msg = xmlStrcat(msg, BAD_CAST message); 2280 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2281 2282 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2283 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, 2284 (const char *) msg, str1, str2); 2285 2286 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2287 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, 2288 (const char *) msg, str1, str2); 2289 2290 FREE_AND_NULL(msg) 2291} 2292 2293static void 2294xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2295 const char *funcName, 2296 const char *message) 2297{ 2298 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2299} 2300 2301#if 0 2302static void 2303xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2304 const char *funcName, 2305 const char *message, 2306 const xmlChar *str1, 2307 const xmlChar *str2) 2308{ 2309 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2310 str1, str2); 2311} 2312#endif 2313 2314static void 2315xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2316 xmlParserErrors error, 2317 xmlNodePtr node, 2318 xmlSchemaBasicItemPtr item, 2319 const char *message, 2320 const xmlChar *str1, const xmlChar *str2, 2321 const xmlChar *str3, const xmlChar *str4) 2322{ 2323 xmlChar *msg = NULL; 2324 2325 if ((node == NULL) && (item != NULL) && 2326 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2327 node = WXS_ITEM_NODE(item); 2328 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2329 msg = xmlStrcat(msg, BAD_CAST ": "); 2330 } else 2331 xmlSchemaFormatNodeForError(&msg, actxt, node); 2332 msg = xmlStrcat(msg, (const xmlChar *) message); 2333 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2334 xmlSchemaErr4(actxt, error, node, 2335 (const char *) msg, str1, str2, str3, str4); 2336 FREE_AND_NULL(msg) 2337} 2338 2339static void 2340xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2341 xmlParserErrors error, 2342 xmlNodePtr node, 2343 xmlSchemaBasicItemPtr item, 2344 const char *message, 2345 const xmlChar *str1, 2346 const xmlChar *str2) 2347{ 2348 xmlSchemaCustomErr4(actxt, error, node, item, 2349 message, str1, str2, NULL, NULL); 2350} 2351 2352 2353 2354static void 2355xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2356 xmlParserErrors error, 2357 xmlNodePtr node, 2358 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2359 const char *message, 2360 const xmlChar *str1, 2361 const xmlChar *str2, 2362 const xmlChar *str3) 2363{ 2364 xmlChar *msg = NULL; 2365 2366 xmlSchemaFormatNodeForError(&msg, actxt, node); 2367 msg = xmlStrcat(msg, (const xmlChar *) message); 2368 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2369 2370 /* URGENT TODO: Set the error code to something sane. */ 2371 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2372 (const char *) msg, str1, str2, str3, NULL); 2373 2374 FREE_AND_NULL(msg) 2375} 2376 2377 2378 2379static void 2380xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2381 xmlParserErrors error, 2382 xmlSchemaPSVIIDCNodePtr idcNode, 2383 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2384 const char *message, 2385 const xmlChar *str1, 2386 const xmlChar *str2) 2387{ 2388 xmlChar *msg = NULL, *qname = NULL; 2389 2390 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2391 msg = xmlStrcat(msg, (const xmlChar *) message); 2392 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2393 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2394 error, NULL, idcNode->nodeLine, (const char *) msg, 2395 xmlSchemaFormatQName(&qname, 2396 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2397 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2398 str1, str2, NULL); 2399 FREE_AND_NULL(qname); 2400 FREE_AND_NULL(msg); 2401} 2402 2403static int 2404xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2405 xmlNodePtr node) 2406{ 2407 if (node != NULL) 2408 return (node->type); 2409 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2410 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2411 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2412 return (-1); 2413} 2414 2415static int 2416xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2417{ 2418 switch (item->type) { 2419 case XML_SCHEMA_TYPE_COMPLEX: 2420 case XML_SCHEMA_TYPE_SIMPLE: 2421 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2422 return(1); 2423 break; 2424 case XML_SCHEMA_TYPE_GROUP: 2425 return (1); 2426 case XML_SCHEMA_TYPE_ELEMENT: 2427 if ( ((xmlSchemaElementPtr) item)->flags & 2428 XML_SCHEMAS_ELEM_GLOBAL) 2429 return(1); 2430 break; 2431 case XML_SCHEMA_TYPE_ATTRIBUTE: 2432 if ( ((xmlSchemaAttributePtr) item)->flags & 2433 XML_SCHEMAS_ATTR_GLOBAL) 2434 return(1); 2435 break; 2436 /* Note that attribute groups are always global. */ 2437 default: 2438 return(1); 2439 } 2440 return (0); 2441} 2442 2443static void 2444xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2445 xmlParserErrors error, 2446 xmlNodePtr node, 2447 const xmlChar *value, 2448 xmlSchemaTypePtr type, 2449 int displayValue) 2450{ 2451 xmlChar *msg = NULL; 2452 2453 xmlSchemaFormatNodeForError(&msg, actxt, node); 2454 2455 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2456 XML_ATTRIBUTE_NODE)) 2457 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2458 else 2459 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2460 "value of "); 2461 2462 if (! xmlSchemaIsGlobalItem(type)) 2463 msg = xmlStrcat(msg, BAD_CAST "the local "); 2464 else 2465 msg = xmlStrcat(msg, BAD_CAST "the "); 2466 2467 if (WXS_IS_ATOMIC(type)) 2468 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2469 else if (WXS_IS_LIST(type)) 2470 msg = xmlStrcat(msg, BAD_CAST "list type"); 2471 else if (WXS_IS_UNION(type)) 2472 msg = xmlStrcat(msg, BAD_CAST "union type"); 2473 2474 if (xmlSchemaIsGlobalItem(type)) { 2475 xmlChar *str = NULL; 2476 msg = xmlStrcat(msg, BAD_CAST " '"); 2477 if (type->builtInType != 0) { 2478 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2479 msg = xmlStrcat(msg, type->name); 2480 } else 2481 msg = xmlStrcat(msg, 2482 xmlSchemaFormatQName(&str, 2483 type->targetNamespace, type->name)); 2484 msg = xmlStrcat(msg, BAD_CAST "'"); 2485 FREE_AND_NULL(str); 2486 } 2487 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2488 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2489 XML_ATTRIBUTE_NODE)) 2490 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2491 else 2492 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2493 FREE_AND_NULL(msg) 2494} 2495 2496static const xmlChar * 2497xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2498 xmlSchemaNodeInfoPtr ni, 2499 xmlNodePtr node) 2500{ 2501 if (node != NULL) { 2502 if (node->ns != NULL) 2503 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2504 else 2505 return (xmlSchemaFormatQName(str, NULL, node->name)); 2506 } else if (ni != NULL) 2507 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2508 return (NULL); 2509} 2510 2511static void 2512xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2513 xmlParserErrors error, 2514 xmlSchemaAttrInfoPtr ni, 2515 xmlNodePtr node) 2516{ 2517 xmlChar *msg = NULL, *str = NULL; 2518 2519 xmlSchemaFormatNodeForError(&msg, actxt, node); 2520 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2521 xmlSchemaErr(actxt, error, node, (const char *) msg, 2522 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2523 NULL); 2524 FREE_AND_NULL(str) 2525 FREE_AND_NULL(msg) 2526} 2527 2528static void 2529xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2530 xmlParserErrors error, 2531 xmlNodePtr node, 2532 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2533 const char *message, 2534 int nbval, 2535 int nbneg, 2536 xmlChar **values) 2537{ 2538 xmlChar *str = NULL, *msg = NULL; 2539 xmlChar *localName, *nsName; 2540 const xmlChar *cur, *end; 2541 int i; 2542 2543 xmlSchemaFormatNodeForError(&msg, actxt, node); 2544 msg = xmlStrcat(msg, (const xmlChar *) message); 2545 msg = xmlStrcat(msg, BAD_CAST "."); 2546 /* 2547 * Note that is does not make sense to report that we have a 2548 * wildcard here, since the wildcard might be unfolded into 2549 * multiple transitions. 2550 */ 2551 if (nbval + nbneg > 0) { 2552 if (nbval + nbneg > 1) { 2553 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2554 } else 2555 str = xmlStrdup(BAD_CAST " Expected is ( "); 2556 nsName = NULL; 2557 2558 for (i = 0; i < nbval + nbneg; i++) { 2559 cur = values[i]; 2560 if (cur == NULL) 2561 continue; 2562 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2563 (cur[3] == ' ')) { 2564 cur += 4; 2565 str = xmlStrcat(str, BAD_CAST "##other"); 2566 } 2567 /* 2568 * Get the local name. 2569 */ 2570 localName = NULL; 2571 2572 end = cur; 2573 if (*end == '*') { 2574 localName = xmlStrdup(BAD_CAST "*"); 2575 end++; 2576 } else { 2577 while ((*end != 0) && (*end != '|')) 2578 end++; 2579 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2580 } 2581 if (*end != 0) { 2582 end++; 2583 /* 2584 * Skip "*|*" if they come with negated expressions, since 2585 * they represent the same negated wildcard. 2586 */ 2587 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2588 /* 2589 * Get the namespace name. 2590 */ 2591 cur = end; 2592 if (*end == '*') { 2593 nsName = xmlStrdup(BAD_CAST "{*}"); 2594 } else { 2595 while (*end != 0) 2596 end++; 2597 2598 if (i >= nbval) 2599 nsName = xmlStrdup(BAD_CAST "{##other:"); 2600 else 2601 nsName = xmlStrdup(BAD_CAST "{"); 2602 2603 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2604 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2605 } 2606 str = xmlStrcat(str, BAD_CAST nsName); 2607 FREE_AND_NULL(nsName) 2608 } else { 2609 FREE_AND_NULL(localName); 2610 continue; 2611 } 2612 } 2613 str = xmlStrcat(str, BAD_CAST localName); 2614 FREE_AND_NULL(localName); 2615 2616 if (i < nbval + nbneg -1) 2617 str = xmlStrcat(str, BAD_CAST ", "); 2618 } 2619 str = xmlStrcat(str, BAD_CAST " ).\n"); 2620 msg = xmlStrcat(msg, BAD_CAST str); 2621 FREE_AND_NULL(str) 2622 } else 2623 msg = xmlStrcat(msg, BAD_CAST "\n"); 2624 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2625 xmlFree(msg); 2626} 2627 2628static void 2629xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2630 xmlParserErrors error, 2631 xmlNodePtr node, 2632 const xmlChar *value, 2633 unsigned long length, 2634 xmlSchemaTypePtr type, 2635 xmlSchemaFacetPtr facet, 2636 const char *message, 2637 const xmlChar *str1, 2638 const xmlChar *str2) 2639{ 2640 xmlChar *str = NULL, *msg = NULL; 2641 xmlSchemaTypeType facetType; 2642 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2643 2644 xmlSchemaFormatNodeForError(&msg, actxt, node); 2645 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2646 facetType = XML_SCHEMA_FACET_ENUMERATION; 2647 /* 2648 * If enumerations are validated, one must not expect the 2649 * facet to be given. 2650 */ 2651 } else 2652 facetType = facet->type; 2653 msg = xmlStrcat(msg, BAD_CAST "["); 2654 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2655 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2656 msg = xmlStrcat(msg, BAD_CAST "'] "); 2657 if (message == NULL) { 2658 /* 2659 * Use a default message. 2660 */ 2661 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2662 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2663 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2664 2665 char len[25], actLen[25]; 2666 2667 /* FIXME, TODO: What is the max expected string length of the 2668 * this value? 2669 */ 2670 if (nodeType == XML_ATTRIBUTE_NODE) 2671 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2672 else 2673 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2674 2675 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2676 snprintf(actLen, 24, "%lu", length); 2677 2678 if (facetType == XML_SCHEMA_FACET_LENGTH) 2679 msg = xmlStrcat(msg, 2680 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2681 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2682 msg = xmlStrcat(msg, 2683 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2684 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2685 msg = xmlStrcat(msg, 2686 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2687 2688 if (nodeType == XML_ATTRIBUTE_NODE) 2689 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2690 value, (const xmlChar *) actLen, (const xmlChar *) len); 2691 else 2692 xmlSchemaErr(actxt, error, node, (const char *) msg, 2693 (const xmlChar *) actLen, (const xmlChar *) len); 2694 2695 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2696 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2697 "of the set {%s}.\n"); 2698 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2699 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2700 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2701 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2702 "by the pattern '%s'.\n"); 2703 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2704 facet->value); 2705 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2706 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2707 "minimum value allowed ('%s').\n"); 2708 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2709 facet->value); 2710 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2711 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2712 "maximum value allowed ('%s').\n"); 2713 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2714 facet->value); 2715 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2716 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2717 "'%s'.\n"); 2718 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2719 facet->value); 2720 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2721 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2722 "'%s'.\n"); 2723 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2724 facet->value); 2725 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2726 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2727 "digits than are allowed ('%s').\n"); 2728 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2729 facet->value); 2730 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2731 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2732 "digits than are allowed ('%s').\n"); 2733 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2734 facet->value); 2735 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2736 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2737 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2738 } else { 2739 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2740 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2741 } 2742 } else { 2743 msg = xmlStrcat(msg, (const xmlChar *) message); 2744 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2745 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2746 } 2747 FREE_AND_NULL(str) 2748 xmlFree(msg); 2749} 2750 2751#define VERROR(err, type, msg) \ 2752 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2753 2754#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2755 2756#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2757#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2758 2759#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2760 2761 2762/** 2763 * xmlSchemaPMissingAttrErr: 2764 * @ctxt: the schema validation context 2765 * @ownerDes: the designation of the owner 2766 * @ownerName: the name of the owner 2767 * @ownerItem: the owner as a schema object 2768 * @ownerElem: the owner as an element node 2769 * @node: the parent element node of the missing attribute node 2770 * @type: the corresponding type of the attribute node 2771 * 2772 * Reports an illegal attribute. 2773 */ 2774static void 2775xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2776 xmlParserErrors error, 2777 xmlSchemaBasicItemPtr ownerItem, 2778 xmlNodePtr ownerElem, 2779 const char *name, 2780 const char *message) 2781{ 2782 xmlChar *des = NULL; 2783 2784 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2785 2786 if (message != NULL) 2787 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2788 else 2789 xmlSchemaPErr(ctxt, ownerElem, error, 2790 "%s: The attribute '%s' is required but missing.\n", 2791 BAD_CAST des, BAD_CAST name); 2792 FREE_AND_NULL(des); 2793} 2794 2795 2796/** 2797 * xmlSchemaPResCompAttrErr: 2798 * @ctxt: the schema validation context 2799 * @error: the error code 2800 * @ownerDes: the designation of the owner 2801 * @ownerItem: the owner as a schema object 2802 * @ownerElem: the owner as an element node 2803 * @name: the name of the attribute holding the QName 2804 * @refName: the referenced local name 2805 * @refURI: the referenced namespace URI 2806 * @message: optional message 2807 * 2808 * Used to report QName attribute values that failed to resolve 2809 * to schema components. 2810 */ 2811static void 2812xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2813 xmlParserErrors error, 2814 xmlSchemaBasicItemPtr ownerItem, 2815 xmlNodePtr ownerElem, 2816 const char *name, 2817 const xmlChar *refName, 2818 const xmlChar *refURI, 2819 xmlSchemaTypeType refType, 2820 const char *refTypeStr) 2821{ 2822 xmlChar *des = NULL, *strA = NULL; 2823 2824 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2825 if (refTypeStr == NULL) 2826 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2827 xmlSchemaPErrExt(ctxt, ownerElem, error, 2828 NULL, NULL, NULL, 2829 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2830 "%s.\n", BAD_CAST des, BAD_CAST name, 2831 xmlSchemaFormatQName(&strA, refURI, refName), 2832 BAD_CAST refTypeStr, NULL); 2833 FREE_AND_NULL(des) 2834 FREE_AND_NULL(strA) 2835} 2836 2837/** 2838 * xmlSchemaPCustomAttrErr: 2839 * @ctxt: the schema parser context 2840 * @error: the error code 2841 * @ownerDes: the designation of the owner 2842 * @ownerItem: the owner as a schema object 2843 * @attr: the illegal attribute node 2844 * 2845 * Reports an illegal attribute during the parse. 2846 */ 2847static void 2848xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2849 xmlParserErrors error, 2850 xmlChar **ownerDes, 2851 xmlSchemaBasicItemPtr ownerItem, 2852 xmlAttrPtr attr, 2853 const char *msg) 2854{ 2855 xmlChar *des = NULL; 2856 2857 if (ownerDes == NULL) 2858 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2859 else if (*ownerDes == NULL) { 2860 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2861 des = *ownerDes; 2862 } else 2863 des = *ownerDes; 2864 if (attr == NULL) { 2865 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2866 "%s, attribute '%s': %s.\n", 2867 BAD_CAST des, (const xmlChar *) "Unknown", 2868 (const xmlChar *) msg, NULL, NULL); 2869 } else { 2870 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2871 "%s, attribute '%s': %s.\n", 2872 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2873 } 2874 if (ownerDes == NULL) 2875 FREE_AND_NULL(des); 2876} 2877 2878/** 2879 * xmlSchemaPIllegalAttrErr: 2880 * @ctxt: the schema parser context 2881 * @error: the error code 2882 * @ownerDes: the designation of the attribute's owner 2883 * @ownerItem: the attribute's owner item 2884 * @attr: the illegal attribute node 2885 * 2886 * Reports an illegal attribute during the parse. 2887 */ 2888static void 2889xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2890 xmlParserErrors error, 2891 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2892 xmlAttrPtr attr) 2893{ 2894 xmlChar *strA = NULL, *strB = NULL; 2895 2896 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2897 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2898 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2899 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2900 NULL, NULL); 2901 FREE_AND_NULL(strA); 2902 FREE_AND_NULL(strB); 2903} 2904 2905/** 2906 * xmlSchemaPCustomErr: 2907 * @ctxt: the schema parser context 2908 * @error: the error code 2909 * @itemDes: the designation of the schema item 2910 * @item: the schema item 2911 * @itemElem: the node of the schema item 2912 * @message: the error message 2913 * @str1: an optional param for the error message 2914 * @str2: an optional param for the error message 2915 * @str3: an optional param for the error message 2916 * 2917 * Reports an error during parsing. 2918 */ 2919static void 2920xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2921 xmlParserErrors error, 2922 xmlSchemaBasicItemPtr item, 2923 xmlNodePtr itemElem, 2924 const char *message, 2925 const xmlChar *str1, 2926 const xmlChar *str2, 2927 const xmlChar *str3) 2928{ 2929 xmlChar *des = NULL, *msg = NULL; 2930 2931 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2932 msg = xmlStrdup(BAD_CAST "%s: "); 2933 msg = xmlStrcat(msg, (const xmlChar *) message); 2934 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2935 if ((itemElem == NULL) && (item != NULL)) 2936 itemElem = WXS_ITEM_NODE(item); 2937 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2938 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2939 FREE_AND_NULL(des); 2940 FREE_AND_NULL(msg); 2941} 2942 2943/** 2944 * xmlSchemaPCustomErr: 2945 * @ctxt: the schema parser context 2946 * @error: the error code 2947 * @itemDes: the designation of the schema item 2948 * @item: the schema item 2949 * @itemElem: the node of the schema item 2950 * @message: the error message 2951 * @str1: the optional param for the error message 2952 * 2953 * Reports an error during parsing. 2954 */ 2955static void 2956xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2957 xmlParserErrors error, 2958 xmlSchemaBasicItemPtr item, 2959 xmlNodePtr itemElem, 2960 const char *message, 2961 const xmlChar *str1) 2962{ 2963 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2964 str1, NULL, NULL); 2965} 2966 2967/** 2968 * xmlSchemaPAttrUseErr: 2969 * @ctxt: the schema parser context 2970 * @error: the error code 2971 * @itemDes: the designation of the schema type 2972 * @item: the schema type 2973 * @itemElem: the node of the schema type 2974 * @attr: the invalid schema attribute 2975 * @message: the error message 2976 * @str1: the optional param for the error message 2977 * 2978 * Reports an attribute use error during parsing. 2979 */ 2980static void 2981xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2982 xmlParserErrors error, 2983 xmlNodePtr node, 2984 xmlSchemaBasicItemPtr ownerItem, 2985 const xmlSchemaAttributeUsePtr attruse, 2986 const char *message, 2987 const xmlChar *str1, const xmlChar *str2, 2988 const xmlChar *str3,const xmlChar *str4) 2989{ 2990 xmlChar *str = NULL, *msg = NULL; 2991 2992 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 2993 msg = xmlStrcat(msg, BAD_CAST ", "); 2994 msg = xmlStrcat(msg, 2995 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 2996 WXS_BASIC_CAST attruse, NULL)); 2997 FREE_AND_NULL(str); 2998 msg = xmlStrcat(msg, BAD_CAST ": "); 2999 msg = xmlStrcat(msg, (const xmlChar *) message); 3000 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3001 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3002 (const char *) msg, str1, str2, str3, str4); 3003 xmlFree(msg); 3004} 3005 3006/** 3007 * xmlSchemaPIllegalFacetAtomicErr: 3008 * @ctxt: the schema parser context 3009 * @error: the error code 3010 * @type: the schema type 3011 * @baseType: the base type of type 3012 * @facet: the illegal facet 3013 * 3014 * Reports an illegal facet for atomic simple types. 3015 */ 3016static void 3017xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3018 xmlParserErrors error, 3019 xmlSchemaTypePtr type, 3020 xmlSchemaTypePtr baseType, 3021 xmlSchemaFacetPtr facet) 3022{ 3023 xmlChar *des = NULL, *strT = NULL; 3024 3025 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3026 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3027 "%s: The facet '%s' is not allowed on types derived from the " 3028 "type %s.\n", 3029 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3030 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3031 NULL, NULL); 3032 FREE_AND_NULL(des); 3033 FREE_AND_NULL(strT); 3034} 3035 3036/** 3037 * xmlSchemaPIllegalFacetListUnionErr: 3038 * @ctxt: the schema parser context 3039 * @error: the error code 3040 * @itemDes: the designation of the schema item involved 3041 * @item: the schema item involved 3042 * @facet: the illegal facet 3043 * 3044 * Reports an illegal facet for <list> and <union>. 3045 */ 3046static void 3047xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3048 xmlParserErrors error, 3049 xmlSchemaTypePtr type, 3050 xmlSchemaFacetPtr facet) 3051{ 3052 xmlChar *des = NULL; 3053 3054 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3055 type->node); 3056 xmlSchemaPErr(ctxt, type->node, error, 3057 "%s: The facet '%s' is not allowed.\n", 3058 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3059 FREE_AND_NULL(des); 3060} 3061 3062/** 3063 * xmlSchemaPMutualExclAttrErr: 3064 * @ctxt: the schema validation context 3065 * @error: the error code 3066 * @elemDes: the designation of the parent element node 3067 * @attr: the bad attribute node 3068 * @type: the corresponding type of the attribute node 3069 * 3070 * Reports an illegal attribute. 3071 */ 3072static void 3073xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3074 xmlParserErrors error, 3075 xmlSchemaBasicItemPtr ownerItem, 3076 xmlAttrPtr attr, 3077 const char *name1, 3078 const char *name2) 3079{ 3080 xmlChar *des = NULL; 3081 3082 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3083 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3084 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3085 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3086 FREE_AND_NULL(des); 3087} 3088 3089/** 3090 * xmlSchemaPSimpleTypeErr: 3091 * @ctxt: the schema validation context 3092 * @error: the error code 3093 * @type: the type specifier 3094 * @ownerDes: the designation of the owner 3095 * @ownerItem: the schema object if existent 3096 * @node: the validated node 3097 * @value: the validated value 3098 * 3099 * Reports a simple type validation error. 3100 * TODO: Should this report the value of an element as well? 3101 */ 3102static void 3103xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3104 xmlParserErrors error, 3105 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3106 xmlNodePtr node, 3107 xmlSchemaTypePtr type, 3108 const char *expected, 3109 const xmlChar *value, 3110 const char *message, 3111 const xmlChar *str1, 3112 const xmlChar *str2) 3113{ 3114 xmlChar *msg = NULL; 3115 3116 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3117 if (message == NULL) { 3118 /* 3119 * Use default messages. 3120 */ 3121 if (type != NULL) { 3122 if (node->type == XML_ATTRIBUTE_NODE) 3123 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3124 else 3125 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3126 "valid value of "); 3127 if (! xmlSchemaIsGlobalItem(type)) 3128 msg = xmlStrcat(msg, BAD_CAST "the local "); 3129 else 3130 msg = xmlStrcat(msg, BAD_CAST "the "); 3131 3132 if (WXS_IS_ATOMIC(type)) 3133 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3134 else if (WXS_IS_LIST(type)) 3135 msg = xmlStrcat(msg, BAD_CAST "list type"); 3136 else if (WXS_IS_UNION(type)) 3137 msg = xmlStrcat(msg, BAD_CAST "union type"); 3138 3139 if (xmlSchemaIsGlobalItem(type)) { 3140 xmlChar *str = NULL; 3141 msg = xmlStrcat(msg, BAD_CAST " '"); 3142 if (type->builtInType != 0) { 3143 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3144 msg = xmlStrcat(msg, type->name); 3145 } else 3146 msg = xmlStrcat(msg, 3147 xmlSchemaFormatQName(&str, 3148 type->targetNamespace, type->name)); 3149 msg = xmlStrcat(msg, BAD_CAST "'."); 3150 FREE_AND_NULL(str); 3151 } 3152 } else { 3153 if (node->type == XML_ATTRIBUTE_NODE) 3154 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3155 else 3156 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3157 "valid."); 3158 } 3159 if (expected) { 3160 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3161 msg = xmlStrcat(msg, BAD_CAST expected); 3162 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3163 } else 3164 msg = xmlStrcat(msg, BAD_CAST "\n"); 3165 if (node->type == XML_ATTRIBUTE_NODE) 3166 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3167 else 3168 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3169 } else { 3170 msg = xmlStrcat(msg, BAD_CAST message); 3171 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3172 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3173 (const char*) msg, str1, str2, NULL, NULL, NULL); 3174 } 3175 /* Cleanup. */ 3176 FREE_AND_NULL(msg) 3177} 3178 3179/** 3180 * xmlSchemaPContentErr: 3181 * @ctxt: the schema parser context 3182 * @error: the error code 3183 * @onwerDes: the designation of the holder of the content 3184 * @ownerItem: the owner item of the holder of the content 3185 * @ownerElem: the node of the holder of the content 3186 * @child: the invalid child node 3187 * @message: the optional error message 3188 * @content: the optional string describing the correct content 3189 * 3190 * Reports an error concerning the content of a schema element. 3191 */ 3192static void 3193xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3194 xmlParserErrors error, 3195 xmlSchemaBasicItemPtr ownerItem, 3196 xmlNodePtr ownerElem, 3197 xmlNodePtr child, 3198 const char *message, 3199 const char *content) 3200{ 3201 xmlChar *des = NULL; 3202 3203 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3204 if (message != NULL) 3205 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3206 "%s: %s.\n", 3207 BAD_CAST des, BAD_CAST message); 3208 else { 3209 if (content != NULL) { 3210 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3211 "%s: The content is not valid. Expected is %s.\n", 3212 BAD_CAST des, BAD_CAST content); 3213 } else { 3214 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3215 "%s: The content is not valid.\n", 3216 BAD_CAST des, NULL); 3217 } 3218 } 3219 FREE_AND_NULL(des) 3220} 3221 3222/************************************************************************ 3223 * * 3224 * Streamable error functions * 3225 * * 3226 ************************************************************************/ 3227 3228 3229 3230 3231/************************************************************************ 3232 * * 3233 * Validation helper functions * 3234 * * 3235 ************************************************************************/ 3236 3237 3238/************************************************************************ 3239 * * 3240 * Allocation functions * 3241 * * 3242 ************************************************************************/ 3243 3244/** 3245 * xmlSchemaNewSchemaForParserCtxt: 3246 * @ctxt: a schema validation context 3247 * 3248 * Allocate a new Schema structure. 3249 * 3250 * Returns the newly allocated structure or NULL in case or error 3251 */ 3252static xmlSchemaPtr 3253xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3254{ 3255 xmlSchemaPtr ret; 3256 3257 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3258 if (ret == NULL) { 3259 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3260 return (NULL); 3261 } 3262 memset(ret, 0, sizeof(xmlSchema)); 3263 ret->dict = ctxt->dict; 3264 xmlDictReference(ret->dict); 3265 3266 return (ret); 3267} 3268 3269/** 3270 * xmlSchemaNewFacet: 3271 * 3272 * Allocate a new Facet structure. 3273 * 3274 * Returns the newly allocated structure or NULL in case or error 3275 */ 3276xmlSchemaFacetPtr 3277xmlSchemaNewFacet(void) 3278{ 3279 xmlSchemaFacetPtr ret; 3280 3281 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3282 if (ret == NULL) { 3283 return (NULL); 3284 } 3285 memset(ret, 0, sizeof(xmlSchemaFacet)); 3286 3287 return (ret); 3288} 3289 3290/** 3291 * xmlSchemaNewAnnot: 3292 * @ctxt: a schema validation context 3293 * @node: a node 3294 * 3295 * Allocate a new annotation structure. 3296 * 3297 * Returns the newly allocated structure or NULL in case or error 3298 */ 3299static xmlSchemaAnnotPtr 3300xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3301{ 3302 xmlSchemaAnnotPtr ret; 3303 3304 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3305 if (ret == NULL) { 3306 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3307 return (NULL); 3308 } 3309 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3310 ret->content = node; 3311 return (ret); 3312} 3313 3314static xmlSchemaItemListPtr 3315xmlSchemaItemListCreate(void) 3316{ 3317 xmlSchemaItemListPtr ret; 3318 3319 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3320 if (ret == NULL) { 3321 xmlSchemaPErrMemory(NULL, 3322 "allocating an item list structure", NULL); 3323 return (NULL); 3324 } 3325 memset(ret, 0, sizeof(xmlSchemaItemList)); 3326 return (ret); 3327} 3328 3329static void 3330xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3331{ 3332 if (list->items != NULL) { 3333 xmlFree(list->items); 3334 list->items = NULL; 3335 } 3336 list->nbItems = 0; 3337 list->sizeItems = 0; 3338} 3339 3340static int 3341xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3342{ 3343 if (list->items == NULL) { 3344 list->items = (void **) xmlMalloc( 3345 20 * sizeof(void *)); 3346 if (list->items == NULL) { 3347 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3348 return(-1); 3349 } 3350 list->sizeItems = 20; 3351 } else if (list->sizeItems <= list->nbItems) { 3352 list->sizeItems *= 2; 3353 list->items = (void **) xmlRealloc(list->items, 3354 list->sizeItems * sizeof(void *)); 3355 if (list->items == NULL) { 3356 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3357 list->sizeItems = 0; 3358 return(-1); 3359 } 3360 } 3361 list->items[list->nbItems++] = item; 3362 return(0); 3363} 3364 3365static int 3366xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3367 int initialSize, 3368 void *item) 3369{ 3370 if (list->items == NULL) { 3371 if (initialSize <= 0) 3372 initialSize = 1; 3373 list->items = (void **) xmlMalloc( 3374 initialSize * sizeof(void *)); 3375 if (list->items == NULL) { 3376 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3377 return(-1); 3378 } 3379 list->sizeItems = initialSize; 3380 } else if (list->sizeItems <= list->nbItems) { 3381 list->sizeItems *= 2; 3382 list->items = (void **) xmlRealloc(list->items, 3383 list->sizeItems * sizeof(void *)); 3384 if (list->items == NULL) { 3385 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3386 list->sizeItems = 0; 3387 return(-1); 3388 } 3389 } 3390 list->items[list->nbItems++] = item; 3391 return(0); 3392} 3393 3394static int 3395xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3396{ 3397 if (list->items == NULL) { 3398 list->items = (void **) xmlMalloc( 3399 20 * sizeof(void *)); 3400 if (list->items == NULL) { 3401 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3402 return(-1); 3403 } 3404 list->sizeItems = 20; 3405 } else if (list->sizeItems <= list->nbItems) { 3406 list->sizeItems *= 2; 3407 list->items = (void **) xmlRealloc(list->items, 3408 list->sizeItems * sizeof(void *)); 3409 if (list->items == NULL) { 3410 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3411 list->sizeItems = 0; 3412 return(-1); 3413 } 3414 } 3415 /* 3416 * Just append if the index is greater/equal than the item count. 3417 */ 3418 if (idx >= list->nbItems) { 3419 list->items[list->nbItems++] = item; 3420 } else { 3421 int i; 3422 for (i = list->nbItems; i > idx; i--) 3423 list->items[i] = list->items[i-1]; 3424 list->items[idx] = item; 3425 list->nbItems++; 3426 } 3427 return(0); 3428} 3429 3430#if 0 /* enable if ever needed */ 3431static int 3432xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3433 int initialSize, 3434 void *item, 3435 int idx) 3436{ 3437 if (list->items == NULL) { 3438 if (initialSize <= 0) 3439 initialSize = 1; 3440 list->items = (void **) xmlMalloc( 3441 initialSize * sizeof(void *)); 3442 if (list->items == NULL) { 3443 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3444 return(-1); 3445 } 3446 list->sizeItems = initialSize; 3447 } else if (list->sizeItems <= list->nbItems) { 3448 list->sizeItems *= 2; 3449 list->items = (void **) xmlRealloc(list->items, 3450 list->sizeItems * sizeof(void *)); 3451 if (list->items == NULL) { 3452 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3453 list->sizeItems = 0; 3454 return(-1); 3455 } 3456 } 3457 /* 3458 * Just append if the index is greater/equal than the item count. 3459 */ 3460 if (idx >= list->nbItems) { 3461 list->items[list->nbItems++] = item; 3462 } else { 3463 int i; 3464 for (i = list->nbItems; i > idx; i--) 3465 list->items[i] = list->items[i-1]; 3466 list->items[idx] = item; 3467 list->nbItems++; 3468 } 3469 return(0); 3470} 3471#endif 3472 3473static int 3474xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3475{ 3476 int i; 3477 if ((list->items == NULL) || (idx >= list->nbItems)) { 3478 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3479 "index error.\n"); 3480 return(-1); 3481 } 3482 3483 if (list->nbItems == 1) { 3484 /* TODO: Really free the list? */ 3485 xmlFree(list->items); 3486 list->items = NULL; 3487 list->nbItems = 0; 3488 list->sizeItems = 0; 3489 } else if (list->nbItems -1 == idx) { 3490 list->nbItems--; 3491 } else { 3492 for (i = idx; i < list->nbItems -1; i++) 3493 list->items[i] = list->items[i+1]; 3494 list->nbItems--; 3495 } 3496 return(0); 3497} 3498 3499/** 3500 * xmlSchemaItemListFree: 3501 * @annot: a schema type structure 3502 * 3503 * Deallocate a annotation structure 3504 */ 3505static void 3506xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3507{ 3508 if (list == NULL) 3509 return; 3510 if (list->items != NULL) 3511 xmlFree(list->items); 3512 xmlFree(list); 3513} 3514 3515static void 3516xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3517{ 3518 if (bucket == NULL) 3519 return; 3520 if (bucket->globals != NULL) { 3521 xmlSchemaComponentListFree(bucket->globals); 3522 xmlSchemaItemListFree(bucket->globals); 3523 } 3524 if (bucket->locals != NULL) { 3525 xmlSchemaComponentListFree(bucket->locals); 3526 xmlSchemaItemListFree(bucket->locals); 3527 } 3528 if (bucket->relations != NULL) { 3529 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3530 do { 3531 prev = cur; 3532 cur = cur->next; 3533 xmlFree(prev); 3534 } while (cur != NULL); 3535 } 3536 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3537 xmlFreeDoc(bucket->doc); 3538 } 3539 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3540 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3541 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3542 } 3543 xmlFree(bucket); 3544} 3545 3546static xmlSchemaBucketPtr 3547xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3548 int type, const xmlChar *targetNamespace) 3549{ 3550 xmlSchemaBucketPtr ret; 3551 int size; 3552 xmlSchemaPtr mainSchema; 3553 3554 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3555 PERROR_INT("xmlSchemaBucketCreate", 3556 "no main schema on constructor"); 3557 return(NULL); 3558 } 3559 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3560 /* Create the schema bucket. */ 3561 if (WXS_IS_BUCKET_INCREDEF(type)) 3562 size = sizeof(xmlSchemaInclude); 3563 else 3564 size = sizeof(xmlSchemaImport); 3565 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3566 if (ret == NULL) { 3567 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3568 return(NULL); 3569 } 3570 memset(ret, 0, size); 3571 ret->targetNamespace = targetNamespace; 3572 ret->type = type; 3573 ret->globals = xmlSchemaItemListCreate(); 3574 if (ret->globals == NULL) { 3575 xmlFree(ret); 3576 return(NULL); 3577 } 3578 ret->locals = xmlSchemaItemListCreate(); 3579 if (ret->locals == NULL) { 3580 xmlFree(ret); 3581 return(NULL); 3582 } 3583 /* 3584 * The following will assure that only the first bucket is marked as 3585 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3586 * For each following import buckets an xmlSchema will be created. 3587 * An xmlSchema will be created for every distinct targetNamespace. 3588 * We assign the targetNamespace to the schemata here. 3589 */ 3590 if (! WXS_HAS_BUCKETS(pctxt)) { 3591 if (WXS_IS_BUCKET_INCREDEF(type)) { 3592 PERROR_INT("xmlSchemaBucketCreate", 3593 "first bucket but it's an include or redefine"); 3594 xmlSchemaBucketFree(ret); 3595 return(NULL); 3596 } 3597 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3598 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3599 /* Point to the *main* schema. */ 3600 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3601 WXS_IMPBUCKET(ret)->schema = mainSchema; 3602 /* 3603 * Ensure that the main schema gets a targetNamespace. 3604 */ 3605 mainSchema->targetNamespace = targetNamespace; 3606 } else { 3607 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3608 PERROR_INT("xmlSchemaBucketCreate", 3609 "main bucket but it's not the first one"); 3610 xmlSchemaBucketFree(ret); 3611 return(NULL); 3612 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3613 /* 3614 * Create a schema for imports and assign the 3615 * targetNamespace. 3616 */ 3617 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3618 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3619 xmlSchemaBucketFree(ret); 3620 return(NULL); 3621 } 3622 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3623 } 3624 } 3625 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3626 int res; 3627 /* 3628 * Imports go into the "schemasImports" slot of the main *schema*. 3629 * Note that we create an import entry for the main schema as well; i.e., 3630 * even if there's only one schema, we'll get an import. 3631 */ 3632 if (mainSchema->schemasImports == NULL) { 3633 mainSchema->schemasImports = xmlHashCreateDict(5, 3634 WXS_CONSTRUCTOR(pctxt)->dict); 3635 if (mainSchema->schemasImports == NULL) { 3636 xmlSchemaBucketFree(ret); 3637 return(NULL); 3638 } 3639 } 3640 if (targetNamespace == NULL) 3641 res = xmlHashAddEntry(mainSchema->schemasImports, 3642 XML_SCHEMAS_NO_NAMESPACE, ret); 3643 else 3644 res = xmlHashAddEntry(mainSchema->schemasImports, 3645 targetNamespace, ret); 3646 if (res != 0) { 3647 PERROR_INT("xmlSchemaBucketCreate", 3648 "failed to add the schema bucket to the hash"); 3649 xmlSchemaBucketFree(ret); 3650 return(NULL); 3651 } 3652 } else { 3653 /* Set the @ownerImport of an include bucket. */ 3654 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3655 WXS_INCBUCKET(ret)->ownerImport = 3656 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3657 else 3658 WXS_INCBUCKET(ret)->ownerImport = 3659 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3660 3661 /* Includes got into the "includes" slot of the *main* schema. */ 3662 if (mainSchema->includes == NULL) { 3663 mainSchema->includes = xmlSchemaItemListCreate(); 3664 if (mainSchema->includes == NULL) { 3665 xmlSchemaBucketFree(ret); 3666 return(NULL); 3667 } 3668 } 3669 xmlSchemaItemListAdd(mainSchema->includes, ret); 3670 } 3671 /* 3672 * Add to list of all buckets; this is used for lookup 3673 * during schema construction time only. 3674 */ 3675 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3676 return(NULL); 3677 return(ret); 3678} 3679 3680static int 3681xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3682{ 3683 if (*list == NULL) { 3684 *list = xmlSchemaItemListCreate(); 3685 if (*list == NULL) 3686 return(-1); 3687 } 3688 xmlSchemaItemListAddSize(*list, initialSize, item); 3689 return(0); 3690} 3691 3692/** 3693 * xmlSchemaFreeAnnot: 3694 * @annot: a schema type structure 3695 * 3696 * Deallocate a annotation structure 3697 */ 3698static void 3699xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3700{ 3701 if (annot == NULL) 3702 return; 3703 if (annot->next == NULL) { 3704 xmlFree(annot); 3705 } else { 3706 xmlSchemaAnnotPtr prev; 3707 3708 do { 3709 prev = annot; 3710 annot = annot->next; 3711 xmlFree(prev); 3712 } while (annot != NULL); 3713 } 3714} 3715 3716/** 3717 * xmlSchemaFreeNotation: 3718 * @schema: a schema notation structure 3719 * 3720 * Deallocate a Schema Notation structure. 3721 */ 3722static void 3723xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3724{ 3725 if (nota == NULL) 3726 return; 3727 xmlFree(nota); 3728} 3729 3730/** 3731 * xmlSchemaFreeAttribute: 3732 * @attr: an attribute declaration 3733 * 3734 * Deallocates an attribute declaration structure. 3735 */ 3736static void 3737xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3738{ 3739 if (attr == NULL) 3740 return; 3741 if (attr->annot != NULL) 3742 xmlSchemaFreeAnnot(attr->annot); 3743 if (attr->defVal != NULL) 3744 xmlSchemaFreeValue(attr->defVal); 3745 xmlFree(attr); 3746} 3747 3748/** 3749 * xmlSchemaFreeAttributeUse: 3750 * @use: an attribute use 3751 * 3752 * Deallocates an attribute use structure. 3753 */ 3754static void 3755xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3756{ 3757 if (use == NULL) 3758 return; 3759 if (use->annot != NULL) 3760 xmlSchemaFreeAnnot(use->annot); 3761 if (use->defVal != NULL) 3762 xmlSchemaFreeValue(use->defVal); 3763 xmlFree(use); 3764} 3765 3766/** 3767 * xmlSchemaFreeAttributeUseProhib: 3768 * @prohib: an attribute use prohibition 3769 * 3770 * Deallocates an attribute use structure. 3771 */ 3772static void 3773xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3774{ 3775 if (prohib == NULL) 3776 return; 3777 xmlFree(prohib); 3778} 3779 3780/** 3781 * xmlSchemaFreeWildcardNsSet: 3782 * set: a schema wildcard namespace 3783 * 3784 * Deallocates a list of wildcard constraint structures. 3785 */ 3786static void 3787xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3788{ 3789 xmlSchemaWildcardNsPtr next; 3790 3791 while (set != NULL) { 3792 next = set->next; 3793 xmlFree(set); 3794 set = next; 3795 } 3796} 3797 3798/** 3799 * xmlSchemaFreeWildcard: 3800 * @wildcard: a wildcard structure 3801 * 3802 * Deallocates a wildcard structure. 3803 */ 3804void 3805xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3806{ 3807 if (wildcard == NULL) 3808 return; 3809 if (wildcard->annot != NULL) 3810 xmlSchemaFreeAnnot(wildcard->annot); 3811 if (wildcard->nsSet != NULL) 3812 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3813 if (wildcard->negNsSet != NULL) 3814 xmlFree(wildcard->negNsSet); 3815 xmlFree(wildcard); 3816} 3817 3818/** 3819 * xmlSchemaFreeAttributeGroup: 3820 * @schema: a schema attribute group structure 3821 * 3822 * Deallocate a Schema Attribute Group structure. 3823 */ 3824static void 3825xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3826{ 3827 if (attrGr == NULL) 3828 return; 3829 if (attrGr->annot != NULL) 3830 xmlSchemaFreeAnnot(attrGr->annot); 3831 if (attrGr->attrUses != NULL) 3832 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3833 xmlFree(attrGr); 3834} 3835 3836/** 3837 * xmlSchemaFreeQNameRef: 3838 * @item: a QName reference structure 3839 * 3840 * Deallocatea a QName reference structure. 3841 */ 3842static void 3843xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3844{ 3845 xmlFree(item); 3846} 3847 3848/** 3849 * xmlSchemaFreeTypeLinkList: 3850 * @alink: a type link 3851 * 3852 * Deallocate a list of types. 3853 */ 3854static void 3855xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3856{ 3857 xmlSchemaTypeLinkPtr next; 3858 3859 while (link != NULL) { 3860 next = link->next; 3861 xmlFree(link); 3862 link = next; 3863 } 3864} 3865 3866static void 3867xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3868{ 3869 xmlSchemaIDCStateObjPtr next; 3870 while (sto != NULL) { 3871 next = sto->next; 3872 if (sto->history != NULL) 3873 xmlFree(sto->history); 3874 if (sto->xpathCtxt != NULL) 3875 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3876 xmlFree(sto); 3877 sto = next; 3878 } 3879} 3880 3881/** 3882 * xmlSchemaFreeIDC: 3883 * @idc: a identity-constraint definition 3884 * 3885 * Deallocates an identity-constraint definition. 3886 */ 3887static void 3888xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3889{ 3890 xmlSchemaIDCSelectPtr cur, prev; 3891 3892 if (idcDef == NULL) 3893 return; 3894 if (idcDef->annot != NULL) 3895 xmlSchemaFreeAnnot(idcDef->annot); 3896 /* Selector */ 3897 if (idcDef->selector != NULL) { 3898 if (idcDef->selector->xpathComp != NULL) 3899 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3900 xmlFree(idcDef->selector); 3901 } 3902 /* Fields */ 3903 if (idcDef->fields != NULL) { 3904 cur = idcDef->fields; 3905 do { 3906 prev = cur; 3907 cur = cur->next; 3908 if (prev->xpathComp != NULL) 3909 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3910 xmlFree(prev); 3911 } while (cur != NULL); 3912 } 3913 xmlFree(idcDef); 3914} 3915 3916/** 3917 * xmlSchemaFreeElement: 3918 * @schema: a schema element structure 3919 * 3920 * Deallocate a Schema Element structure. 3921 */ 3922static void 3923xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3924{ 3925 if (elem == NULL) 3926 return; 3927 if (elem->annot != NULL) 3928 xmlSchemaFreeAnnot(elem->annot); 3929 if (elem->contModel != NULL) 3930 xmlRegFreeRegexp(elem->contModel); 3931 if (elem->defVal != NULL) 3932 xmlSchemaFreeValue(elem->defVal); 3933 xmlFree(elem); 3934} 3935 3936/** 3937 * xmlSchemaFreeFacet: 3938 * @facet: a schema facet structure 3939 * 3940 * Deallocate a Schema Facet structure. 3941 */ 3942void 3943xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3944{ 3945 if (facet == NULL) 3946 return; 3947 if (facet->val != NULL) 3948 xmlSchemaFreeValue(facet->val); 3949 if (facet->regexp != NULL) 3950 xmlRegFreeRegexp(facet->regexp); 3951 if (facet->annot != NULL) 3952 xmlSchemaFreeAnnot(facet->annot); 3953 xmlFree(facet); 3954} 3955 3956/** 3957 * xmlSchemaFreeType: 3958 * @type: a schema type structure 3959 * 3960 * Deallocate a Schema Type structure. 3961 */ 3962void 3963xmlSchemaFreeType(xmlSchemaTypePtr type) 3964{ 3965 if (type == NULL) 3966 return; 3967 if (type->annot != NULL) 3968 xmlSchemaFreeAnnot(type->annot); 3969 if (type->facets != NULL) { 3970 xmlSchemaFacetPtr facet, next; 3971 3972 facet = type->facets; 3973 while (facet != NULL) { 3974 next = facet->next; 3975 xmlSchemaFreeFacet(facet); 3976 facet = next; 3977 } 3978 } 3979 if (type->attrUses != NULL) 3980 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3981 if (type->memberTypes != NULL) 3982 xmlSchemaFreeTypeLinkList(type->memberTypes); 3983 if (type->facetSet != NULL) { 3984 xmlSchemaFacetLinkPtr next, link; 3985 3986 link = type->facetSet; 3987 do { 3988 next = link->next; 3989 xmlFree(link); 3990 link = next; 3991 } while (link != NULL); 3992 } 3993 if (type->contModel != NULL) 3994 xmlRegFreeRegexp(type->contModel); 3995 xmlFree(type); 3996} 3997 3998/** 3999 * xmlSchemaFreeModelGroupDef: 4000 * @item: a schema model group definition 4001 * 4002 * Deallocates a schema model group definition. 4003 */ 4004static void 4005xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4006{ 4007 if (item->annot != NULL) 4008 xmlSchemaFreeAnnot(item->annot); 4009 xmlFree(item); 4010} 4011 4012/** 4013 * xmlSchemaFreeModelGroup: 4014 * @item: a schema model group 4015 * 4016 * Deallocates a schema model group structure. 4017 */ 4018static void 4019xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4020{ 4021 if (item->annot != NULL) 4022 xmlSchemaFreeAnnot(item->annot); 4023 xmlFree(item); 4024} 4025 4026static void 4027xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4028{ 4029 if ((list == NULL) || (list->nbItems == 0)) 4030 return; 4031 { 4032 xmlSchemaTreeItemPtr item; 4033 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4034 int i; 4035 4036 for (i = 0; i < list->nbItems; i++) { 4037 item = items[i]; 4038 if (item == NULL) 4039 continue; 4040 switch (item->type) { 4041 case XML_SCHEMA_TYPE_SIMPLE: 4042 case XML_SCHEMA_TYPE_COMPLEX: 4043 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4044 break; 4045 case XML_SCHEMA_TYPE_ATTRIBUTE: 4046 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4047 break; 4048 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4049 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4050 break; 4051 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4052 xmlSchemaFreeAttributeUseProhib( 4053 (xmlSchemaAttributeUseProhibPtr) item); 4054 break; 4055 case XML_SCHEMA_TYPE_ELEMENT: 4056 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4057 break; 4058 case XML_SCHEMA_TYPE_PARTICLE: 4059 if (item->annot != NULL) 4060 xmlSchemaFreeAnnot(item->annot); 4061 xmlFree(item); 4062 break; 4063 case XML_SCHEMA_TYPE_SEQUENCE: 4064 case XML_SCHEMA_TYPE_CHOICE: 4065 case XML_SCHEMA_TYPE_ALL: 4066 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4067 break; 4068 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4069 xmlSchemaFreeAttributeGroup( 4070 (xmlSchemaAttributeGroupPtr) item); 4071 break; 4072 case XML_SCHEMA_TYPE_GROUP: 4073 xmlSchemaFreeModelGroupDef( 4074 (xmlSchemaModelGroupDefPtr) item); 4075 break; 4076 case XML_SCHEMA_TYPE_ANY: 4077 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4078 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4079 break; 4080 case XML_SCHEMA_TYPE_IDC_KEY: 4081 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4082 case XML_SCHEMA_TYPE_IDC_KEYREF: 4083 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4084 break; 4085 case XML_SCHEMA_TYPE_NOTATION: 4086 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4087 break; 4088 case XML_SCHEMA_EXTRA_QNAMEREF: 4089 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4090 break; 4091 default: { 4092 /* TODO: This should never be hit. */ 4093 xmlSchemaPSimpleInternalErr(NULL, 4094 "Internal error: xmlSchemaComponentListFree, " 4095 "unexpected component type '%s'\n", 4096 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4097 } 4098 break; 4099 } 4100 } 4101 list->nbItems = 0; 4102 } 4103} 4104 4105/** 4106 * xmlSchemaFree: 4107 * @schema: a schema structure 4108 * 4109 * Deallocate a Schema structure. 4110 */ 4111void 4112xmlSchemaFree(xmlSchemaPtr schema) 4113{ 4114 if (schema == NULL) 4115 return; 4116 /* @volatiles is not used anymore :-/ */ 4117 if (schema->volatiles != NULL) 4118 TODO 4119 /* 4120 * Note that those slots are not responsible for freeing 4121 * schema components anymore; this will now be done by 4122 * the schema buckets. 4123 */ 4124 if (schema->notaDecl != NULL) 4125 xmlHashFree(schema->notaDecl, NULL); 4126 if (schema->attrDecl != NULL) 4127 xmlHashFree(schema->attrDecl, NULL); 4128 if (schema->attrgrpDecl != NULL) 4129 xmlHashFree(schema->attrgrpDecl, NULL); 4130 if (schema->elemDecl != NULL) 4131 xmlHashFree(schema->elemDecl, NULL); 4132 if (schema->typeDecl != NULL) 4133 xmlHashFree(schema->typeDecl, NULL); 4134 if (schema->groupDecl != NULL) 4135 xmlHashFree(schema->groupDecl, NULL); 4136 if (schema->idcDef != NULL) 4137 xmlHashFree(schema->idcDef, NULL); 4138 4139 if (schema->schemasImports != NULL) 4140 xmlHashFree(schema->schemasImports, 4141 (xmlHashDeallocator) xmlSchemaBucketFree); 4142 if (schema->includes != NULL) { 4143 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4144 int i; 4145 for (i = 0; i < list->nbItems; i++) { 4146 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4147 } 4148 xmlSchemaItemListFree(list); 4149 } 4150 if (schema->annot != NULL) 4151 xmlSchemaFreeAnnot(schema->annot); 4152 /* Never free the doc here, since this will be done by the buckets. */ 4153 4154 xmlDictFree(schema->dict); 4155 xmlFree(schema); 4156} 4157 4158/************************************************************************ 4159 * * 4160 * Debug functions * 4161 * * 4162 ************************************************************************/ 4163 4164#ifdef LIBXML_OUTPUT_ENABLED 4165 4166static void 4167xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4168 4169/** 4170 * xmlSchemaElementDump: 4171 * @elem: an element 4172 * @output: the file output 4173 * 4174 * Dump the element 4175 */ 4176static void 4177xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4178 const xmlChar * name ATTRIBUTE_UNUSED, 4179 const xmlChar * namespace ATTRIBUTE_UNUSED, 4180 const xmlChar * context ATTRIBUTE_UNUSED) 4181{ 4182 if (elem == NULL) 4183 return; 4184 4185 4186 fprintf(output, "Element"); 4187 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4188 fprintf(output, " (global)"); 4189 fprintf(output, ": '%s' ", elem->name); 4190 if (namespace != NULL) 4191 fprintf(output, "ns '%s'", namespace); 4192 fprintf(output, "\n"); 4193#if 0 4194 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4195 fprintf(output, " min %d ", elem->minOccurs); 4196 if (elem->maxOccurs >= UNBOUNDED) 4197 fprintf(output, "max: unbounded\n"); 4198 else if (elem->maxOccurs != 1) 4199 fprintf(output, "max: %d\n", elem->maxOccurs); 4200 else 4201 fprintf(output, "\n"); 4202 } 4203#endif 4204 /* 4205 * Misc other properties. 4206 */ 4207 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4208 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4209 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4210 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4211 fprintf(output, " props: "); 4212 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4213 fprintf(output, "[fixed] "); 4214 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4215 fprintf(output, "[default] "); 4216 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4217 fprintf(output, "[abstract] "); 4218 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4219 fprintf(output, "[nillable] "); 4220 fprintf(output, "\n"); 4221 } 4222 /* 4223 * Default/fixed value. 4224 */ 4225 if (elem->value != NULL) 4226 fprintf(output, " value: '%s'\n", elem->value); 4227 /* 4228 * Type. 4229 */ 4230 if (elem->namedType != NULL) { 4231 fprintf(output, " type: '%s' ", elem->namedType); 4232 if (elem->namedTypeNs != NULL) 4233 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4234 else 4235 fprintf(output, "\n"); 4236 } else if (elem->subtypes != NULL) { 4237 /* 4238 * Dump local types. 4239 */ 4240 xmlSchemaTypeDump(elem->subtypes, output); 4241 } 4242 /* 4243 * Substitution group. 4244 */ 4245 if (elem->substGroup != NULL) { 4246 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4247 if (elem->substGroupNs != NULL) 4248 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4249 else 4250 fprintf(output, "\n"); 4251 } 4252} 4253 4254/** 4255 * xmlSchemaAnnotDump: 4256 * @output: the file output 4257 * @annot: a annotation 4258 * 4259 * Dump the annotation 4260 */ 4261static void 4262xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4263{ 4264 xmlChar *content; 4265 4266 if (annot == NULL) 4267 return; 4268 4269 content = xmlNodeGetContent(annot->content); 4270 if (content != NULL) { 4271 fprintf(output, " Annot: %s\n", content); 4272 xmlFree(content); 4273 } else 4274 fprintf(output, " Annot: empty\n"); 4275} 4276 4277/** 4278 * xmlSchemaContentModelDump: 4279 * @particle: the schema particle 4280 * @output: the file output 4281 * @depth: the depth used for intentation 4282 * 4283 * Dump a SchemaType structure 4284 */ 4285static void 4286xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4287{ 4288 xmlChar *str = NULL; 4289 xmlSchemaTreeItemPtr term; 4290 char shift[100]; 4291 int i; 4292 4293 if (particle == NULL) 4294 return; 4295 for (i = 0;((i < depth) && (i < 25));i++) 4296 shift[2 * i] = shift[2 * i + 1] = ' '; 4297 shift[2 * i] = shift[2 * i + 1] = 0; 4298 fprintf(output, "%s", shift); 4299 if (particle->children == NULL) { 4300 fprintf(output, "MISSING particle term\n"); 4301 return; 4302 } 4303 term = particle->children; 4304 if (term == NULL) { 4305 fprintf(output, "(NULL)"); 4306 } else { 4307 switch (term->type) { 4308 case XML_SCHEMA_TYPE_ELEMENT: 4309 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4310 ((xmlSchemaElementPtr)term)->targetNamespace, 4311 ((xmlSchemaElementPtr)term)->name)); 4312 FREE_AND_NULL(str); 4313 break; 4314 case XML_SCHEMA_TYPE_SEQUENCE: 4315 fprintf(output, "SEQUENCE"); 4316 break; 4317 case XML_SCHEMA_TYPE_CHOICE: 4318 fprintf(output, "CHOICE"); 4319 break; 4320 case XML_SCHEMA_TYPE_ALL: 4321 fprintf(output, "ALL"); 4322 break; 4323 case XML_SCHEMA_TYPE_ANY: 4324 fprintf(output, "ANY"); 4325 break; 4326 default: 4327 fprintf(output, "UNKNOWN\n"); 4328 return; 4329 } 4330 } 4331 if (particle->minOccurs != 1) 4332 fprintf(output, " min: %d", particle->minOccurs); 4333 if (particle->maxOccurs >= UNBOUNDED) 4334 fprintf(output, " max: unbounded"); 4335 else if (particle->maxOccurs != 1) 4336 fprintf(output, " max: %d", particle->maxOccurs); 4337 fprintf(output, "\n"); 4338 if (term && 4339 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4340 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4341 (term->type == XML_SCHEMA_TYPE_ALL)) && 4342 (term->children != NULL)) { 4343 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4344 output, depth +1); 4345 } 4346 if (particle->next != NULL) 4347 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4348 output, depth); 4349} 4350 4351/** 4352 * xmlSchemaAttrUsesDump: 4353 * @uses: attribute uses list 4354 * @output: the file output 4355 * 4356 * Dumps a list of attribute use components. 4357 */ 4358static void 4359xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4360{ 4361 xmlSchemaAttributeUsePtr use; 4362 xmlSchemaAttributeUseProhibPtr prohib; 4363 xmlSchemaQNameRefPtr ref; 4364 const xmlChar *name, *tns; 4365 xmlChar *str = NULL; 4366 int i; 4367 4368 if ((uses == NULL) || (uses->nbItems == 0)) 4369 return; 4370 4371 fprintf(output, " attributes:\n"); 4372 for (i = 0; i < uses->nbItems; i++) { 4373 use = uses->items[i]; 4374 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4375 fprintf(output, " [prohibition] "); 4376 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4377 name = prohib->name; 4378 tns = prohib->targetNamespace; 4379 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4380 fprintf(output, " [reference] "); 4381 ref = (xmlSchemaQNameRefPtr) use; 4382 name = ref->name; 4383 tns = ref->targetNamespace; 4384 } else { 4385 fprintf(output, " [use] "); 4386 name = WXS_ATTRUSE_DECL_NAME(use); 4387 tns = WXS_ATTRUSE_DECL_TNS(use); 4388 } 4389 fprintf(output, "'%s'\n", 4390 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4391 FREE_AND_NULL(str); 4392 } 4393} 4394 4395/** 4396 * xmlSchemaTypeDump: 4397 * @output: the file output 4398 * @type: a type structure 4399 * 4400 * Dump a SchemaType structure 4401 */ 4402static void 4403xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4404{ 4405 if (type == NULL) { 4406 fprintf(output, "Type: NULL\n"); 4407 return; 4408 } 4409 fprintf(output, "Type: "); 4410 if (type->name != NULL) 4411 fprintf(output, "'%s' ", type->name); 4412 else 4413 fprintf(output, "(no name) "); 4414 if (type->targetNamespace != NULL) 4415 fprintf(output, "ns '%s' ", type->targetNamespace); 4416 switch (type->type) { 4417 case XML_SCHEMA_TYPE_BASIC: 4418 fprintf(output, "[basic] "); 4419 break; 4420 case XML_SCHEMA_TYPE_SIMPLE: 4421 fprintf(output, "[simple] "); 4422 break; 4423 case XML_SCHEMA_TYPE_COMPLEX: 4424 fprintf(output, "[complex] "); 4425 break; 4426 case XML_SCHEMA_TYPE_SEQUENCE: 4427 fprintf(output, "[sequence] "); 4428 break; 4429 case XML_SCHEMA_TYPE_CHOICE: 4430 fprintf(output, "[choice] "); 4431 break; 4432 case XML_SCHEMA_TYPE_ALL: 4433 fprintf(output, "[all] "); 4434 break; 4435 case XML_SCHEMA_TYPE_UR: 4436 fprintf(output, "[ur] "); 4437 break; 4438 case XML_SCHEMA_TYPE_RESTRICTION: 4439 fprintf(output, "[restriction] "); 4440 break; 4441 case XML_SCHEMA_TYPE_EXTENSION: 4442 fprintf(output, "[extension] "); 4443 break; 4444 default: 4445 fprintf(output, "[unknown type %d] ", type->type); 4446 break; 4447 } 4448 fprintf(output, "content: "); 4449 switch (type->contentType) { 4450 case XML_SCHEMA_CONTENT_UNKNOWN: 4451 fprintf(output, "[unknown] "); 4452 break; 4453 case XML_SCHEMA_CONTENT_EMPTY: 4454 fprintf(output, "[empty] "); 4455 break; 4456 case XML_SCHEMA_CONTENT_ELEMENTS: 4457 fprintf(output, "[element] "); 4458 break; 4459 case XML_SCHEMA_CONTENT_MIXED: 4460 fprintf(output, "[mixed] "); 4461 break; 4462 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4463 /* not used. */ 4464 break; 4465 case XML_SCHEMA_CONTENT_BASIC: 4466 fprintf(output, "[basic] "); 4467 break; 4468 case XML_SCHEMA_CONTENT_SIMPLE: 4469 fprintf(output, "[simple] "); 4470 break; 4471 case XML_SCHEMA_CONTENT_ANY: 4472 fprintf(output, "[any] "); 4473 break; 4474 } 4475 fprintf(output, "\n"); 4476 if (type->base != NULL) { 4477 fprintf(output, " base type: '%s'", type->base); 4478 if (type->baseNs != NULL) 4479 fprintf(output, " ns '%s'\n", type->baseNs); 4480 else 4481 fprintf(output, "\n"); 4482 } 4483 if (type->attrUses != NULL) 4484 xmlSchemaAttrUsesDump(type->attrUses, output); 4485 if (type->annot != NULL) 4486 xmlSchemaAnnotDump(output, type->annot); 4487#ifdef DUMP_CONTENT_MODEL 4488 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4489 (type->subtypes != NULL)) { 4490 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4491 output, 1); 4492 } 4493#endif 4494} 4495 4496/** 4497 * xmlSchemaDump: 4498 * @output: the file output 4499 * @schema: a schema structure 4500 * 4501 * Dump a Schema structure. 4502 */ 4503void 4504xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4505{ 4506 if (output == NULL) 4507 return; 4508 if (schema == NULL) { 4509 fprintf(output, "Schemas: NULL\n"); 4510 return; 4511 } 4512 fprintf(output, "Schemas: "); 4513 if (schema->name != NULL) 4514 fprintf(output, "%s, ", schema->name); 4515 else 4516 fprintf(output, "no name, "); 4517 if (schema->targetNamespace != NULL) 4518 fprintf(output, "%s", (const char *) schema->targetNamespace); 4519 else 4520 fprintf(output, "no target namespace"); 4521 fprintf(output, "\n"); 4522 if (schema->annot != NULL) 4523 xmlSchemaAnnotDump(output, schema->annot); 4524 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4525 output); 4526 xmlHashScanFull(schema->elemDecl, 4527 (xmlHashScannerFull) xmlSchemaElementDump, output); 4528} 4529 4530#ifdef DEBUG_IDC_NODE_TABLE 4531/** 4532 * xmlSchemaDebugDumpIDCTable: 4533 * @vctxt: the WXS validation context 4534 * 4535 * Displays the current IDC table for debug purposes. 4536 */ 4537static void 4538xmlSchemaDebugDumpIDCTable(FILE * output, 4539 const xmlChar *namespaceName, 4540 const xmlChar *localName, 4541 xmlSchemaPSVIIDCBindingPtr bind) 4542{ 4543 xmlChar *str = NULL; 4544 const xmlChar *value; 4545 xmlSchemaPSVIIDCNodePtr tab; 4546 xmlSchemaPSVIIDCKeyPtr key; 4547 int i, j, res; 4548 4549 fprintf(output, "IDC: TABLES on '%s'\n", 4550 xmlSchemaFormatQName(&str, namespaceName, localName)); 4551 FREE_AND_NULL(str) 4552 4553 if (bind == NULL) 4554 return; 4555 do { 4556 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4557 xmlSchemaGetComponentQName(&str, 4558 bind->definition), bind->nbNodes); 4559 FREE_AND_NULL(str) 4560 for (i = 0; i < bind->nbNodes; i++) { 4561 tab = bind->nodeTable[i]; 4562 fprintf(output, " ( "); 4563 for (j = 0; j < bind->definition->nbFields; j++) { 4564 key = tab->keys[j]; 4565 if ((key != NULL) && (key->val != NULL)) { 4566 res = xmlSchemaGetCanonValue(key->val, &value); 4567 if (res >= 0) 4568 fprintf(output, "'%s' ", value); 4569 else 4570 fprintf(output, "CANON-VALUE-FAILED "); 4571 if (res == 0) 4572 FREE_AND_NULL(value) 4573 } else if (key != NULL) 4574 fprintf(output, "(no val), "); 4575 else 4576 fprintf(output, "(key missing), "); 4577 } 4578 fprintf(output, ")\n"); 4579 } 4580 if (bind->dupls && bind->dupls->nbItems) { 4581 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4582 for (i = 0; i < bind->dupls->nbItems; i++) { 4583 tab = bind->dupls->items[i]; 4584 fprintf(output, " ( "); 4585 for (j = 0; j < bind->definition->nbFields; j++) { 4586 key = tab->keys[j]; 4587 if ((key != NULL) && (key->val != NULL)) { 4588 res = xmlSchemaGetCanonValue(key->val, &value); 4589 if (res >= 0) 4590 fprintf(output, "'%s' ", value); 4591 else 4592 fprintf(output, "CANON-VALUE-FAILED "); 4593 if (res == 0) 4594 FREE_AND_NULL(value) 4595 } else if (key != NULL) 4596 fprintf(output, "(no val), "); 4597 else 4598 fprintf(output, "(key missing), "); 4599 } 4600 fprintf(output, ")\n"); 4601 } 4602 } 4603 bind = bind->next; 4604 } while (bind != NULL); 4605} 4606#endif /* DEBUG_IDC */ 4607#endif /* LIBXML_OUTPUT_ENABLED */ 4608 4609/************************************************************************ 4610 * * 4611 * Utilities * 4612 * * 4613 ************************************************************************/ 4614 4615/** 4616 * xmlSchemaGetPropNode: 4617 * @node: the element node 4618 * @name: the name of the attribute 4619 * 4620 * Seeks an attribute with a name of @name in 4621 * no namespace. 4622 * 4623 * Returns the attribute or NULL if not present. 4624 */ 4625static xmlAttrPtr 4626xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4627{ 4628 xmlAttrPtr prop; 4629 4630 if ((node == NULL) || (name == NULL)) 4631 return(NULL); 4632 prop = node->properties; 4633 while (prop != NULL) { 4634 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4635 return(prop); 4636 prop = prop->next; 4637 } 4638 return (NULL); 4639} 4640 4641/** 4642 * xmlSchemaGetPropNodeNs: 4643 * @node: the element node 4644 * @uri: the uri 4645 * @name: the name of the attribute 4646 * 4647 * Seeks an attribute with a local name of @name and 4648 * a namespace URI of @uri. 4649 * 4650 * Returns the attribute or NULL if not present. 4651 */ 4652static xmlAttrPtr 4653xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4654{ 4655 xmlAttrPtr prop; 4656 4657 if ((node == NULL) || (name == NULL)) 4658 return(NULL); 4659 prop = node->properties; 4660 while (prop != NULL) { 4661 if ((prop->ns != NULL) && 4662 xmlStrEqual(prop->name, BAD_CAST name) && 4663 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4664 return(prop); 4665 prop = prop->next; 4666 } 4667 return (NULL); 4668} 4669 4670static const xmlChar * 4671xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4672{ 4673 xmlChar *val; 4674 const xmlChar *ret; 4675 4676 val = xmlNodeGetContent(node); 4677 if (val == NULL) 4678 val = xmlStrdup((xmlChar *)""); 4679 ret = xmlDictLookup(ctxt->dict, val, -1); 4680 xmlFree(val); 4681 return(ret); 4682} 4683 4684static const xmlChar * 4685xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4686{ 4687 return((const xmlChar*) xmlNodeGetContent(node)); 4688} 4689 4690/** 4691 * xmlSchemaGetProp: 4692 * @ctxt: the parser context 4693 * @node: the node 4694 * @name: the property name 4695 * 4696 * Read a attribute value and internalize the string 4697 * 4698 * Returns the string or NULL if not present. 4699 */ 4700static const xmlChar * 4701xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4702 const char *name) 4703{ 4704 xmlChar *val; 4705 const xmlChar *ret; 4706 4707 val = xmlGetNoNsProp(node, BAD_CAST name); 4708 if (val == NULL) 4709 return(NULL); 4710 ret = xmlDictLookup(ctxt->dict, val, -1); 4711 xmlFree(val); 4712 return(ret); 4713} 4714 4715/************************************************************************ 4716 * * 4717 * Parsing functions * 4718 * * 4719 ************************************************************************/ 4720 4721#define WXS_FIND_GLOBAL_ITEM(slot) \ 4722 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4723 ret = xmlHashLookup(schema->slot, name); \ 4724 if (ret != NULL) goto exit; \ 4725 } \ 4726 if (xmlHashSize(schema->schemasImports) > 1) { \ 4727 xmlSchemaImportPtr import; \ 4728 if (nsName == NULL) \ 4729 import = xmlHashLookup(schema->schemasImports, \ 4730 XML_SCHEMAS_NO_NAMESPACE); \ 4731 else \ 4732 import = xmlHashLookup(schema->schemasImports, nsName); \ 4733 if (import == NULL) \ 4734 goto exit; \ 4735 ret = xmlHashLookup(import->schema->slot, name); \ 4736 } 4737 4738/** 4739 * xmlSchemaGetElem: 4740 * @schema: the schema context 4741 * @name: the element name 4742 * @ns: the element namespace 4743 * 4744 * Lookup a global element declaration in the schema. 4745 * 4746 * Returns the element declaration or NULL if not found. 4747 */ 4748static xmlSchemaElementPtr 4749xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4750 const xmlChar * nsName) 4751{ 4752 xmlSchemaElementPtr ret = NULL; 4753 4754 if ((name == NULL) || (schema == NULL)) 4755 return(NULL); 4756 if (schema != NULL) { 4757 WXS_FIND_GLOBAL_ITEM(elemDecl) 4758 } 4759exit: 4760#ifdef DEBUG 4761 if (ret == NULL) { 4762 if (nsName == NULL) 4763 fprintf(stderr, "Unable to lookup element decl. %s", name); 4764 else 4765 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4766 nsName); 4767 } 4768#endif 4769 return (ret); 4770} 4771 4772/** 4773 * xmlSchemaGetType: 4774 * @schema: the main schema 4775 * @name: the type's name 4776 * nsName: the type's namespace 4777 * 4778 * Lookup a type in the schemas or the predefined types 4779 * 4780 * Returns the group definition or NULL if not found. 4781 */ 4782static xmlSchemaTypePtr 4783xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4784 const xmlChar * nsName) 4785{ 4786 xmlSchemaTypePtr ret = NULL; 4787 4788 if (name == NULL) 4789 return (NULL); 4790 /* First try the built-in types. */ 4791 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4792 ret = xmlSchemaGetPredefinedType(name, nsName); 4793 if (ret != NULL) 4794 goto exit; 4795 /* 4796 * Note that we try the parsed schemas as well here 4797 * since one might have parsed the S4S, which contain more 4798 * than the built-in types. 4799 * TODO: Can we optimize this? 4800 */ 4801 } 4802 if (schema != NULL) { 4803 WXS_FIND_GLOBAL_ITEM(typeDecl) 4804 } 4805exit: 4806 4807#ifdef DEBUG 4808 if (ret == NULL) { 4809 if (nsName == NULL) 4810 fprintf(stderr, "Unable to lookup type %s", name); 4811 else 4812 fprintf(stderr, "Unable to lookup type %s:%s", name, 4813 nsName); 4814 } 4815#endif 4816 return (ret); 4817} 4818 4819/** 4820 * xmlSchemaGetAttributeDecl: 4821 * @schema: the context of the schema 4822 * @name: the name of the attribute 4823 * @ns: the target namespace of the attribute 4824 * 4825 * Lookup a an attribute in the schema or imported schemas 4826 * 4827 * Returns the attribute declaration or NULL if not found. 4828 */ 4829static xmlSchemaAttributePtr 4830xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4831 const xmlChar * nsName) 4832{ 4833 xmlSchemaAttributePtr ret = NULL; 4834 4835 if ((name == NULL) || (schema == NULL)) 4836 return (NULL); 4837 if (schema != NULL) { 4838 WXS_FIND_GLOBAL_ITEM(attrDecl) 4839 } 4840exit: 4841#ifdef DEBUG 4842 if (ret == NULL) { 4843 if (nsName == NULL) 4844 fprintf(stderr, "Unable to lookup attribute %s", name); 4845 else 4846 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4847 nsName); 4848 } 4849#endif 4850 return (ret); 4851} 4852 4853/** 4854 * xmlSchemaGetAttributeGroup: 4855 * @schema: the context of the schema 4856 * @name: the name of the attribute group 4857 * @ns: the target namespace of the attribute group 4858 * 4859 * Lookup a an attribute group in the schema or imported schemas 4860 * 4861 * Returns the attribute group definition or NULL if not found. 4862 */ 4863static xmlSchemaAttributeGroupPtr 4864xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4865 const xmlChar * nsName) 4866{ 4867 xmlSchemaAttributeGroupPtr ret = NULL; 4868 4869 if ((name == NULL) || (schema == NULL)) 4870 return (NULL); 4871 if (schema != NULL) { 4872 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4873 } 4874exit: 4875 /* TODO: 4876 if ((ret != NULL) && (ret->redef != NULL)) { 4877 * Return the last redefinition. * 4878 ret = ret->redef; 4879 } 4880 */ 4881#ifdef DEBUG 4882 if (ret == NULL) { 4883 if (nsName == NULL) 4884 fprintf(stderr, "Unable to lookup attribute group %s", name); 4885 else 4886 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4887 nsName); 4888 } 4889#endif 4890 return (ret); 4891} 4892 4893/** 4894 * xmlSchemaGetGroup: 4895 * @schema: the context of the schema 4896 * @name: the name of the group 4897 * @ns: the target namespace of the group 4898 * 4899 * Lookup a group in the schema or imported schemas 4900 * 4901 * Returns the group definition or NULL if not found. 4902 */ 4903static xmlSchemaModelGroupDefPtr 4904xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4905 const xmlChar * nsName) 4906{ 4907 xmlSchemaModelGroupDefPtr ret = NULL; 4908 4909 if ((name == NULL) || (schema == NULL)) 4910 return (NULL); 4911 if (schema != NULL) { 4912 WXS_FIND_GLOBAL_ITEM(groupDecl) 4913 } 4914exit: 4915 4916#ifdef DEBUG 4917 if (ret == NULL) { 4918 if (nsName == NULL) 4919 fprintf(stderr, "Unable to lookup group %s", name); 4920 else 4921 fprintf(stderr, "Unable to lookup group %s:%s", name, 4922 nsName); 4923 } 4924#endif 4925 return (ret); 4926} 4927 4928static xmlSchemaNotationPtr 4929xmlSchemaGetNotation(xmlSchemaPtr schema, 4930 const xmlChar *name, 4931 const xmlChar *nsName) 4932{ 4933 xmlSchemaNotationPtr ret = NULL; 4934 4935 if ((name == NULL) || (schema == NULL)) 4936 return (NULL); 4937 if (schema != NULL) { 4938 WXS_FIND_GLOBAL_ITEM(notaDecl) 4939 } 4940exit: 4941 return (ret); 4942} 4943 4944static xmlSchemaIDCPtr 4945xmlSchemaGetIDC(xmlSchemaPtr schema, 4946 const xmlChar *name, 4947 const xmlChar *nsName) 4948{ 4949 xmlSchemaIDCPtr ret = NULL; 4950 4951 if ((name == NULL) || (schema == NULL)) 4952 return (NULL); 4953 if (schema != NULL) { 4954 WXS_FIND_GLOBAL_ITEM(idcDef) 4955 } 4956exit: 4957 return (ret); 4958} 4959 4960/** 4961 * xmlSchemaGetNamedComponent: 4962 * @schema: the schema 4963 * @name: the name of the group 4964 * @ns: the target namespace of the group 4965 * 4966 * Lookup a group in the schema or imported schemas 4967 * 4968 * Returns the group definition or NULL if not found. 4969 */ 4970static xmlSchemaBasicItemPtr 4971xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4972 xmlSchemaTypeType itemType, 4973 const xmlChar *name, 4974 const xmlChar *targetNs) 4975{ 4976 switch (itemType) { 4977 case XML_SCHEMA_TYPE_GROUP: 4978 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4979 name, targetNs)); 4980 case XML_SCHEMA_TYPE_ELEMENT: 4981 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4982 name, targetNs)); 4983 default: 4984 TODO 4985 return (NULL); 4986 } 4987} 4988 4989/************************************************************************ 4990 * * 4991 * Parsing functions * 4992 * * 4993 ************************************************************************/ 4994 4995#define IS_BLANK_NODE(n) \ 4996 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 4997 4998/** 4999 * xmlSchemaIsBlank: 5000 * @str: a string 5001 * @len: the length of the string or -1 5002 * 5003 * Check if a string is ignorable 5004 * 5005 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5006 */ 5007static int 5008xmlSchemaIsBlank(xmlChar * str, int len) 5009{ 5010 if (str == NULL) 5011 return (1); 5012 if (len < 0) { 5013 while (*str != 0) { 5014 if (!(IS_BLANK_CH(*str))) 5015 return (0); 5016 str++; 5017 } 5018 } else while ((*str != 0) && (len != 0)) { 5019 if (!(IS_BLANK_CH(*str))) 5020 return (0); 5021 str++; 5022 len--; 5023 } 5024 5025 return (1); 5026} 5027 5028#define WXS_COMP_NAME(c, t) ((t) (c))->name 5029#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5030/* 5031* xmlSchemaFindRedefCompInGraph: 5032* ATTENTION TODO: This uses pointer comp. for strings. 5033*/ 5034static xmlSchemaBasicItemPtr 5035xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5036 xmlSchemaTypeType type, 5037 const xmlChar *name, 5038 const xmlChar *nsName) 5039{ 5040 xmlSchemaBasicItemPtr ret; 5041 int i; 5042 5043 if ((bucket == NULL) || (name == NULL)) 5044 return(NULL); 5045 if ((bucket->globals == NULL) || 5046 (bucket->globals->nbItems == 0)) 5047 goto subschemas; 5048 /* 5049 * Search in global components. 5050 */ 5051 for (i = 0; i < bucket->globals->nbItems; i++) { 5052 ret = bucket->globals->items[i]; 5053 if (ret->type == type) { 5054 switch (type) { 5055 case XML_SCHEMA_TYPE_COMPLEX: 5056 case XML_SCHEMA_TYPE_SIMPLE: 5057 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5058 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5059 nsName)) 5060 { 5061 return(ret); 5062 } 5063 break; 5064 case XML_SCHEMA_TYPE_GROUP: 5065 if ((WXS_COMP_NAME(ret, 5066 xmlSchemaModelGroupDefPtr) == name) && 5067 (WXS_COMP_TNS(ret, 5068 xmlSchemaModelGroupDefPtr) == nsName)) 5069 { 5070 return(ret); 5071 } 5072 break; 5073 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5074 if ((WXS_COMP_NAME(ret, 5075 xmlSchemaAttributeGroupPtr) == name) && 5076 (WXS_COMP_TNS(ret, 5077 xmlSchemaAttributeGroupPtr) == nsName)) 5078 { 5079 return(ret); 5080 } 5081 break; 5082 default: 5083 /* Should not be hit. */ 5084 return(NULL); 5085 } 5086 } 5087 } 5088subschemas: 5089 /* 5090 * Process imported/included schemas. 5091 */ 5092 if (bucket->relations != NULL) { 5093 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5094 5095 /* 5096 * TODO: Marking the bucket will not avoid multiple searches 5097 * in the same schema, but avoids at least circularity. 5098 */ 5099 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5100 do { 5101 if ((rel->bucket != NULL) && 5102 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5103 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5104 type, name, nsName); 5105 if (ret != NULL) 5106 return(ret); 5107 } 5108 rel = rel->next; 5109 } while (rel != NULL); 5110 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5111 } 5112 return(NULL); 5113} 5114 5115/** 5116 * xmlSchemaAddNotation: 5117 * @ctxt: a schema parser context 5118 * @schema: the schema being built 5119 * @name: the item name 5120 * 5121 * Add an XML schema annotation declaration 5122 * *WARNING* this interface is highly subject to change 5123 * 5124 * Returns the new struture or NULL in case of error 5125 */ 5126static xmlSchemaNotationPtr 5127xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5128 const xmlChar *name, const xmlChar *nsName, 5129 xmlNodePtr node ATTRIBUTE_UNUSED) 5130{ 5131 xmlSchemaNotationPtr ret = NULL; 5132 5133 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5134 return (NULL); 5135 5136 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5137 if (ret == NULL) { 5138 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5139 return (NULL); 5140 } 5141 memset(ret, 0, sizeof(xmlSchemaNotation)); 5142 ret->type = XML_SCHEMA_TYPE_NOTATION; 5143 ret->name = name; 5144 ret->targetNamespace = nsName; 5145 /* TODO: do we need the node to be set? 5146 * ret->node = node;*/ 5147 WXS_ADD_GLOBAL(ctxt, ret); 5148 return (ret); 5149} 5150 5151/** 5152 * xmlSchemaAddAttribute: 5153 * @ctxt: a schema parser context 5154 * @schema: the schema being built 5155 * @name: the item name 5156 * @namespace: the namespace 5157 * 5158 * Add an XML schema Attrribute declaration 5159 * *WARNING* this interface is highly subject to change 5160 * 5161 * Returns the new struture or NULL in case of error 5162 */ 5163static xmlSchemaAttributePtr 5164xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5165 const xmlChar * name, const xmlChar * nsName, 5166 xmlNodePtr node, int topLevel) 5167{ 5168 xmlSchemaAttributePtr ret = NULL; 5169 5170 if ((ctxt == NULL) || (schema == NULL)) 5171 return (NULL); 5172 5173 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5174 if (ret == NULL) { 5175 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5176 return (NULL); 5177 } 5178 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5179 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5180 ret->node = node; 5181 ret->name = name; 5182 ret->targetNamespace = nsName; 5183 5184 if (topLevel) 5185 WXS_ADD_GLOBAL(ctxt, ret); 5186 else 5187 WXS_ADD_LOCAL(ctxt, ret); 5188 WXS_ADD_PENDING(ctxt, ret); 5189 return (ret); 5190} 5191 5192/** 5193 * xmlSchemaAddAttributeUse: 5194 * @ctxt: a schema parser context 5195 * @schema: the schema being built 5196 * @name: the item name 5197 * @namespace: the namespace 5198 * 5199 * Add an XML schema Attrribute declaration 5200 * *WARNING* this interface is highly subject to change 5201 * 5202 * Returns the new struture or NULL in case of error 5203 */ 5204static xmlSchemaAttributeUsePtr 5205xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5206 xmlNodePtr node) 5207{ 5208 xmlSchemaAttributeUsePtr ret = NULL; 5209 5210 if (pctxt == NULL) 5211 return (NULL); 5212 5213 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5214 if (ret == NULL) { 5215 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5216 return (NULL); 5217 } 5218 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5219 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5220 ret->node = node; 5221 5222 WXS_ADD_LOCAL(pctxt, ret); 5223 return (ret); 5224} 5225 5226/* 5227* xmlSchemaAddRedef: 5228* 5229* Adds a redefinition information. This is used at a later stage to: 5230* resolve references to the redefined components and to check constraints. 5231*/ 5232static xmlSchemaRedefPtr 5233xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5234 xmlSchemaBucketPtr targetBucket, 5235 void *item, 5236 const xmlChar *refName, 5237 const xmlChar *refTargetNs) 5238{ 5239 xmlSchemaRedefPtr ret; 5240 5241 ret = (xmlSchemaRedefPtr) 5242 xmlMalloc(sizeof(xmlSchemaRedef)); 5243 if (ret == NULL) { 5244 xmlSchemaPErrMemory(pctxt, 5245 "allocating redefinition info", NULL); 5246 return (NULL); 5247 } 5248 memset(ret, 0, sizeof(xmlSchemaRedef)); 5249 ret->item = item; 5250 ret->targetBucket = targetBucket; 5251 ret->refName = refName; 5252 ret->refTargetNs = refTargetNs; 5253 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5254 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5255 else 5256 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5257 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5258 5259 return (ret); 5260} 5261 5262/** 5263 * xmlSchemaAddAttributeGroupDefinition: 5264 * @ctxt: a schema parser context 5265 * @schema: the schema being built 5266 * @name: the item name 5267 * @nsName: the target namespace 5268 * @node: the corresponding node 5269 * 5270 * Add an XML schema Attrribute Group definition. 5271 * 5272 * Returns the new struture or NULL in case of error 5273 */ 5274static xmlSchemaAttributeGroupPtr 5275xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5276 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5277 const xmlChar *name, 5278 const xmlChar *nsName, 5279 xmlNodePtr node) 5280{ 5281 xmlSchemaAttributeGroupPtr ret = NULL; 5282 5283 if ((pctxt == NULL) || (name == NULL)) 5284 return (NULL); 5285 5286 ret = (xmlSchemaAttributeGroupPtr) 5287 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5288 if (ret == NULL) { 5289 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5290 return (NULL); 5291 } 5292 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5293 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5294 ret->name = name; 5295 ret->targetNamespace = nsName; 5296 ret->node = node; 5297 5298 /* TODO: Remove the flag. */ 5299 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5300 if (pctxt->isRedefine) { 5301 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5302 ret, name, nsName); 5303 if (pctxt->redef == NULL) { 5304 xmlFree(ret); 5305 return(NULL); 5306 } 5307 pctxt->redefCounter = 0; 5308 } 5309 WXS_ADD_GLOBAL(pctxt, ret); 5310 WXS_ADD_PENDING(pctxt, ret); 5311 return (ret); 5312} 5313 5314/** 5315 * xmlSchemaAddElement: 5316 * @ctxt: a schema parser context 5317 * @schema: the schema being built 5318 * @name: the type name 5319 * @namespace: the type namespace 5320 * 5321 * Add an XML schema Element declaration 5322 * *WARNING* this interface is highly subject to change 5323 * 5324 * Returns the new struture or NULL in case of error 5325 */ 5326static xmlSchemaElementPtr 5327xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5328 const xmlChar * name, const xmlChar * nsName, 5329 xmlNodePtr node, int topLevel) 5330{ 5331 xmlSchemaElementPtr ret = NULL; 5332 5333 if ((ctxt == NULL) || (name == NULL)) 5334 return (NULL); 5335 5336 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5337 if (ret == NULL) { 5338 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5339 return (NULL); 5340 } 5341 memset(ret, 0, sizeof(xmlSchemaElement)); 5342 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5343 ret->name = name; 5344 ret->targetNamespace = nsName; 5345 ret->node = node; 5346 5347 if (topLevel) 5348 WXS_ADD_GLOBAL(ctxt, ret); 5349 else 5350 WXS_ADD_LOCAL(ctxt, ret); 5351 WXS_ADD_PENDING(ctxt, ret); 5352 return (ret); 5353} 5354 5355/** 5356 * xmlSchemaAddType: 5357 * @ctxt: a schema parser context 5358 * @schema: the schema being built 5359 * @name: the item name 5360 * @namespace: the namespace 5361 * 5362 * Add an XML schema item 5363 * *WARNING* this interface is highly subject to change 5364 * 5365 * Returns the new struture or NULL in case of error 5366 */ 5367static xmlSchemaTypePtr 5368xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5369 xmlSchemaTypeType type, 5370 const xmlChar * name, const xmlChar * nsName, 5371 xmlNodePtr node, int topLevel) 5372{ 5373 xmlSchemaTypePtr ret = NULL; 5374 5375 if ((ctxt == NULL) || (schema == NULL)) 5376 return (NULL); 5377 5378 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5379 if (ret == NULL) { 5380 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5381 return (NULL); 5382 } 5383 memset(ret, 0, sizeof(xmlSchemaType)); 5384 ret->type = type; 5385 ret->name = name; 5386 ret->targetNamespace = nsName; 5387 ret->node = node; 5388 if (topLevel) { 5389 if (ctxt->isRedefine) { 5390 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5391 ret, name, nsName); 5392 if (ctxt->redef == NULL) { 5393 xmlFree(ret); 5394 return(NULL); 5395 } 5396 ctxt->redefCounter = 0; 5397 } 5398 WXS_ADD_GLOBAL(ctxt, ret); 5399 } else 5400 WXS_ADD_LOCAL(ctxt, ret); 5401 WXS_ADD_PENDING(ctxt, ret); 5402 return (ret); 5403} 5404 5405static xmlSchemaQNameRefPtr 5406xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5407 xmlSchemaTypeType refType, 5408 const xmlChar *refName, 5409 const xmlChar *refNs) 5410{ 5411 xmlSchemaQNameRefPtr ret; 5412 5413 ret = (xmlSchemaQNameRefPtr) 5414 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5415 if (ret == NULL) { 5416 xmlSchemaPErrMemory(pctxt, 5417 "allocating QName reference item", NULL); 5418 return (NULL); 5419 } 5420 ret->node = NULL; 5421 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5422 ret->name = refName; 5423 ret->targetNamespace = refNs; 5424 ret->item = NULL; 5425 ret->itemType = refType; 5426 /* 5427 * Store the reference item in the schema. 5428 */ 5429 WXS_ADD_LOCAL(pctxt, ret); 5430 return (ret); 5431} 5432 5433static xmlSchemaAttributeUseProhibPtr 5434xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5435{ 5436 xmlSchemaAttributeUseProhibPtr ret; 5437 5438 ret = (xmlSchemaAttributeUseProhibPtr) 5439 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5440 if (ret == NULL) { 5441 xmlSchemaPErrMemory(pctxt, 5442 "allocating attribute use prohibition", NULL); 5443 return (NULL); 5444 } 5445 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5446 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5447 WXS_ADD_LOCAL(pctxt, ret); 5448 return (ret); 5449} 5450 5451 5452/** 5453 * xmlSchemaAddModelGroup: 5454 * @ctxt: a schema parser context 5455 * @schema: the schema being built 5456 * @type: the "compositor" type of the model group 5457 * @node: the node in the schema doc 5458 * 5459 * Adds a schema model group 5460 * *WARNING* this interface is highly subject to change 5461 * 5462 * Returns the new struture or NULL in case of error 5463 */ 5464static xmlSchemaModelGroupPtr 5465xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5466 xmlSchemaPtr schema, 5467 xmlSchemaTypeType type, 5468 xmlNodePtr node) 5469{ 5470 xmlSchemaModelGroupPtr ret = NULL; 5471 5472 if ((ctxt == NULL) || (schema == NULL)) 5473 return (NULL); 5474 5475 ret = (xmlSchemaModelGroupPtr) 5476 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5477 if (ret == NULL) { 5478 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5479 NULL); 5480 return (NULL); 5481 } 5482 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5483 ret->type = type; 5484 ret->node = node; 5485 WXS_ADD_LOCAL(ctxt, ret); 5486 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5487 (type == XML_SCHEMA_TYPE_CHOICE)) 5488 WXS_ADD_PENDING(ctxt, ret); 5489 return (ret); 5490} 5491 5492 5493/** 5494 * xmlSchemaAddParticle: 5495 * @ctxt: a schema parser context 5496 * @schema: the schema being built 5497 * @node: the corresponding node in the schema doc 5498 * @min: the minOccurs 5499 * @max: the maxOccurs 5500 * 5501 * Adds an XML schema particle component. 5502 * *WARNING* this interface is highly subject to change 5503 * 5504 * Returns the new struture or NULL in case of error 5505 */ 5506static xmlSchemaParticlePtr 5507xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5508 xmlNodePtr node, int min, int max) 5509{ 5510 xmlSchemaParticlePtr ret = NULL; 5511 if (ctxt == NULL) 5512 return (NULL); 5513 5514#ifdef DEBUG 5515 fprintf(stderr, "Adding particle component\n"); 5516#endif 5517 ret = (xmlSchemaParticlePtr) 5518 xmlMalloc(sizeof(xmlSchemaParticle)); 5519 if (ret == NULL) { 5520 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5521 NULL); 5522 return (NULL); 5523 } 5524 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5525 ret->annot = NULL; 5526 ret->node = node; 5527 ret->minOccurs = min; 5528 ret->maxOccurs = max; 5529 ret->next = NULL; 5530 ret->children = NULL; 5531 5532 WXS_ADD_LOCAL(ctxt, ret); 5533 /* 5534 * Note that addition to pending components will be done locally 5535 * to the specific parsing function, since the most particles 5536 * need not to be fixed up (i.e. the reference to be resolved). 5537 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5538 */ 5539 return (ret); 5540} 5541 5542/** 5543 * xmlSchemaAddModelGroupDefinition: 5544 * @ctxt: a schema validation context 5545 * @schema: the schema being built 5546 * @name: the group name 5547 * 5548 * Add an XML schema Group definition 5549 * 5550 * Returns the new struture or NULL in case of error 5551 */ 5552static xmlSchemaModelGroupDefPtr 5553xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5554 xmlSchemaPtr schema, 5555 const xmlChar *name, 5556 const xmlChar *nsName, 5557 xmlNodePtr node) 5558{ 5559 xmlSchemaModelGroupDefPtr ret = NULL; 5560 5561 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5562 return (NULL); 5563 5564 ret = (xmlSchemaModelGroupDefPtr) 5565 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5566 if (ret == NULL) { 5567 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5568 return (NULL); 5569 } 5570 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5571 ret->name = name; 5572 ret->type = XML_SCHEMA_TYPE_GROUP; 5573 ret->node = node; 5574 ret->targetNamespace = nsName; 5575 5576 if (ctxt->isRedefine) { 5577 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5578 ret, name, nsName); 5579 if (ctxt->redef == NULL) { 5580 xmlFree(ret); 5581 return(NULL); 5582 } 5583 ctxt->redefCounter = 0; 5584 } 5585 WXS_ADD_GLOBAL(ctxt, ret); 5586 WXS_ADD_PENDING(ctxt, ret); 5587 return (ret); 5588} 5589 5590/** 5591 * xmlSchemaNewWildcardNs: 5592 * @ctxt: a schema validation context 5593 * 5594 * Creates a new wildcard namespace constraint. 5595 * 5596 * Returns the new struture or NULL in case of error 5597 */ 5598static xmlSchemaWildcardNsPtr 5599xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5600{ 5601 xmlSchemaWildcardNsPtr ret; 5602 5603 ret = (xmlSchemaWildcardNsPtr) 5604 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5605 if (ret == NULL) { 5606 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5607 return (NULL); 5608 } 5609 ret->value = NULL; 5610 ret->next = NULL; 5611 return (ret); 5612} 5613 5614static xmlSchemaIDCPtr 5615xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5616 const xmlChar *name, const xmlChar *nsName, 5617 int category, xmlNodePtr node) 5618{ 5619 xmlSchemaIDCPtr ret = NULL; 5620 5621 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5622 return (NULL); 5623 5624 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5625 if (ret == NULL) { 5626 xmlSchemaPErrMemory(ctxt, 5627 "allocating an identity-constraint definition", NULL); 5628 return (NULL); 5629 } 5630 memset(ret, 0, sizeof(xmlSchemaIDC)); 5631 /* The target namespace of the parent element declaration. */ 5632 ret->targetNamespace = nsName; 5633 ret->name = name; 5634 ret->type = category; 5635 ret->node = node; 5636 5637 WXS_ADD_GLOBAL(ctxt, ret); 5638 /* 5639 * Only keyrefs need to be fixup up. 5640 */ 5641 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5642 WXS_ADD_PENDING(ctxt, ret); 5643 return (ret); 5644} 5645 5646/** 5647 * xmlSchemaAddWildcard: 5648 * @ctxt: a schema validation context 5649 * @schema: a schema 5650 * 5651 * Adds a wildcard. 5652 * It corresponds to a xsd:anyAttribute and xsd:any. 5653 * 5654 * Returns the new struture or NULL in case of error 5655 */ 5656static xmlSchemaWildcardPtr 5657xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5658 xmlSchemaTypeType type, xmlNodePtr node) 5659{ 5660 xmlSchemaWildcardPtr ret = NULL; 5661 5662 if ((ctxt == NULL) || (schema == NULL)) 5663 return (NULL); 5664 5665 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5666 if (ret == NULL) { 5667 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5668 return (NULL); 5669 } 5670 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5671 ret->type = type; 5672 ret->node = node; 5673 WXS_ADD_LOCAL(ctxt, ret); 5674 return (ret); 5675} 5676 5677static void 5678xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5679{ 5680 if (group == NULL) 5681 return; 5682 if (group->members != NULL) 5683 xmlSchemaItemListFree(group->members); 5684 xmlFree(group); 5685} 5686 5687static xmlSchemaSubstGroupPtr 5688xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5689 xmlSchemaElementPtr head) 5690{ 5691 xmlSchemaSubstGroupPtr ret; 5692 5693 /* Init subst group hash. */ 5694 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5695 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5696 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5697 return(NULL); 5698 } 5699 /* Create a new substitution group. */ 5700 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5701 if (ret == NULL) { 5702 xmlSchemaPErrMemory(NULL, 5703 "allocating a substitution group container", NULL); 5704 return(NULL); 5705 } 5706 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5707 ret->head = head; 5708 /* Create list of members. */ 5709 ret->members = xmlSchemaItemListCreate(); 5710 if (ret->members == NULL) { 5711 xmlSchemaSubstGroupFree(ret); 5712 return(NULL); 5713 } 5714 /* Add subst group to hash. */ 5715 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5716 head->name, head->targetNamespace, ret) != 0) { 5717 PERROR_INT("xmlSchemaSubstGroupAdd", 5718 "failed to add a new substitution container"); 5719 xmlSchemaSubstGroupFree(ret); 5720 return(NULL); 5721 } 5722 return(ret); 5723} 5724 5725static xmlSchemaSubstGroupPtr 5726xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5727 xmlSchemaElementPtr head) 5728{ 5729 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5730 return(NULL); 5731 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5732 head->name, head->targetNamespace)); 5733 5734} 5735 5736/** 5737 * xmlSchemaAddElementSubstitutionMember: 5738 * @pctxt: a schema parser context 5739 * @head: the head of the substitution group 5740 * @member: the new member of the substitution group 5741 * 5742 * Allocate a new annotation structure. 5743 * 5744 * Returns the newly allocated structure or NULL in case or error 5745 */ 5746static int 5747xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5748 xmlSchemaElementPtr head, 5749 xmlSchemaElementPtr member) 5750{ 5751 xmlSchemaSubstGroupPtr substGroup = NULL; 5752 5753 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5754 return (-1); 5755 5756 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5757 if (substGroup == NULL) 5758 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5759 if (substGroup == NULL) 5760 return(-1); 5761 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5762 return(-1); 5763 return(0); 5764} 5765 5766/************************************************************************ 5767 * * 5768 * Utilities for parsing * 5769 * * 5770 ************************************************************************/ 5771 5772/** 5773 * xmlSchemaPValAttrNodeQNameValue: 5774 * @ctxt: a schema parser context 5775 * @schema: the schema context 5776 * @ownerDes: the designation of the parent element 5777 * @ownerItem: the parent as a schema object 5778 * @value: the QName value 5779 * @local: the resulting local part if found, the attribute value otherwise 5780 * @uri: the resulting namespace URI if found 5781 * 5782 * Extracts the local name and the URI of a QName value and validates it. 5783 * This one is intended to be used on attribute values that 5784 * should resolve to schema components. 5785 * 5786 * Returns 0, in case the QName is valid, a positive error code 5787 * if not valid and -1 if an internal error occurs. 5788 */ 5789static int 5790xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5791 xmlSchemaPtr schema, 5792 xmlSchemaBasicItemPtr ownerItem, 5793 xmlAttrPtr attr, 5794 const xmlChar *value, 5795 const xmlChar **uri, 5796 const xmlChar **local) 5797{ 5798 const xmlChar *pref; 5799 xmlNsPtr ns; 5800 int len, ret; 5801 5802 *uri = NULL; 5803 *local = NULL; 5804 ret = xmlValidateQName(value, 1); 5805 if (ret > 0) { 5806 xmlSchemaPSimpleTypeErr(ctxt, 5807 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5808 ownerItem, (xmlNodePtr) attr, 5809 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5810 NULL, value, NULL, NULL, NULL); 5811 *local = value; 5812 return (ctxt->err); 5813 } else if (ret < 0) 5814 return (-1); 5815 5816 if (!strchr((char *) value, ':')) { 5817 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5818 if (ns) 5819 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5820 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5821 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5822 * parser context. */ 5823 /* 5824 * This one takes care of included schemas with no 5825 * target namespace. 5826 */ 5827 *uri = ctxt->targetNamespace; 5828 } 5829 *local = xmlDictLookup(ctxt->dict, value, -1); 5830 return (0); 5831 } 5832 /* 5833 * At this point xmlSplitQName3 has to return a local name. 5834 */ 5835 *local = xmlSplitQName3(value, &len); 5836 *local = xmlDictLookup(ctxt->dict, *local, -1); 5837 pref = xmlDictLookup(ctxt->dict, value, len); 5838 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5839 if (ns == NULL) { 5840 xmlSchemaPSimpleTypeErr(ctxt, 5841 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5842 ownerItem, (xmlNodePtr) attr, 5843 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5844 "The value '%s' of simple type 'xs:QName' has no " 5845 "corresponding namespace declaration in scope", value, NULL); 5846 return (ctxt->err); 5847 } else { 5848 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5849 } 5850 return (0); 5851} 5852 5853/** 5854 * xmlSchemaPValAttrNodeQName: 5855 * @ctxt: a schema parser context 5856 * @schema: the schema context 5857 * @ownerDes: the designation of the owner element 5858 * @ownerItem: the owner as a schema object 5859 * @attr: the attribute node 5860 * @local: the resulting local part if found, the attribute value otherwise 5861 * @uri: the resulting namespace URI if found 5862 * 5863 * Extracts and validates the QName of an attribute value. 5864 * This one is intended to be used on attribute values that 5865 * should resolve to schema components. 5866 * 5867 * Returns 0, in case the QName is valid, a positive error code 5868 * if not valid and -1 if an internal error occurs. 5869 */ 5870static int 5871xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5872 xmlSchemaPtr schema, 5873 xmlSchemaBasicItemPtr ownerItem, 5874 xmlAttrPtr attr, 5875 const xmlChar **uri, 5876 const xmlChar **local) 5877{ 5878 const xmlChar *value; 5879 5880 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5881 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5882 ownerItem, attr, value, uri, local)); 5883} 5884 5885/** 5886 * xmlSchemaPValAttrQName: 5887 * @ctxt: a schema parser context 5888 * @schema: the schema context 5889 * @ownerDes: the designation of the parent element 5890 * @ownerItem: the owner as a schema object 5891 * @ownerElem: the parent node of the attribute 5892 * @name: the name of the attribute 5893 * @local: the resulting local part if found, the attribute value otherwise 5894 * @uri: the resulting namespace URI if found 5895 * 5896 * Extracts and validates the QName of an attribute value. 5897 * 5898 * Returns 0, in case the QName is valid, a positive error code 5899 * if not valid and -1 if an internal error occurs. 5900 */ 5901static int 5902xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5903 xmlSchemaPtr schema, 5904 xmlSchemaBasicItemPtr ownerItem, 5905 xmlNodePtr ownerElem, 5906 const char *name, 5907 const xmlChar **uri, 5908 const xmlChar **local) 5909{ 5910 xmlAttrPtr attr; 5911 5912 attr = xmlSchemaGetPropNode(ownerElem, name); 5913 if (attr == NULL) { 5914 *local = NULL; 5915 *uri = NULL; 5916 return (0); 5917 } 5918 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5919 ownerItem, attr, uri, local)); 5920} 5921 5922/** 5923 * xmlSchemaPValAttrID: 5924 * @ctxt: a schema parser context 5925 * @schema: the schema context 5926 * @ownerDes: the designation of the parent element 5927 * @ownerItem: the owner as a schema object 5928 * @ownerElem: the parent node of the attribute 5929 * @name: the name of the attribute 5930 * 5931 * Extracts and validates the ID of an attribute value. 5932 * 5933 * Returns 0, in case the ID is valid, a positive error code 5934 * if not valid and -1 if an internal error occurs. 5935 */ 5936static int 5937xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5938{ 5939 int ret; 5940 const xmlChar *value; 5941 5942 if (attr == NULL) 5943 return(0); 5944 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5945 ret = xmlValidateNCName(value, 1); 5946 if (ret == 0) { 5947 /* 5948 * NOTE: the IDness might have already be declared in the DTD 5949 */ 5950 if (attr->atype != XML_ATTRIBUTE_ID) { 5951 xmlIDPtr res; 5952 xmlChar *strip; 5953 5954 /* 5955 * TODO: Use xmlSchemaStrip here; it's not exported at this 5956 * moment. 5957 */ 5958 strip = xmlSchemaCollapseString(value); 5959 if (strip != NULL) { 5960 xmlFree((xmlChar *) value); 5961 value = strip; 5962 } 5963 res = xmlAddID(NULL, attr->doc, value, attr); 5964 if (res == NULL) { 5965 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5966 xmlSchemaPSimpleTypeErr(ctxt, 5967 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5968 NULL, (xmlNodePtr) attr, 5969 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5970 NULL, NULL, "Duplicate value '%s' of simple " 5971 "type 'xs:ID'", value, NULL); 5972 } else 5973 attr->atype = XML_ATTRIBUTE_ID; 5974 } 5975 } else if (ret > 0) { 5976 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5977 xmlSchemaPSimpleTypeErr(ctxt, 5978 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5979 NULL, (xmlNodePtr) attr, 5980 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5981 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5982 "not a valid 'xs:NCName'", 5983 value, NULL); 5984 } 5985 if (value != NULL) 5986 xmlFree((xmlChar *)value); 5987 5988 return (ret); 5989} 5990 5991static int 5992xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 5993 xmlNodePtr ownerElem, 5994 const xmlChar *name) 5995{ 5996 xmlAttrPtr attr; 5997 5998 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 5999 if (attr == NULL) 6000 return(0); 6001 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6002 6003} 6004 6005/** 6006 * xmlGetMaxOccurs: 6007 * @ctxt: a schema validation context 6008 * @node: a subtree containing XML Schema informations 6009 * 6010 * Get the maxOccurs property 6011 * 6012 * Returns the default if not found, or the value 6013 */ 6014static int 6015xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6016 int min, int max, int def, const char *expected) 6017{ 6018 const xmlChar *val, *cur; 6019 int ret = 0; 6020 xmlAttrPtr attr; 6021 6022 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6023 if (attr == NULL) 6024 return (def); 6025 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6026 6027 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6028 if (max != UNBOUNDED) { 6029 xmlSchemaPSimpleTypeErr(ctxt, 6030 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6031 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6032 NULL, (xmlNodePtr) attr, NULL, expected, 6033 val, NULL, NULL, NULL); 6034 return (def); 6035 } else 6036 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6037 } 6038 6039 cur = val; 6040 while (IS_BLANK_CH(*cur)) 6041 cur++; 6042 if (*cur == 0) { 6043 xmlSchemaPSimpleTypeErr(ctxt, 6044 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6045 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6046 NULL, (xmlNodePtr) attr, NULL, expected, 6047 val, NULL, NULL, NULL); 6048 return (def); 6049 } 6050 while ((*cur >= '0') && (*cur <= '9')) { 6051 ret = ret * 10 + (*cur - '0'); 6052 cur++; 6053 } 6054 while (IS_BLANK_CH(*cur)) 6055 cur++; 6056 /* 6057 * TODO: Restrict the maximal value to Integer. 6058 */ 6059 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6060 xmlSchemaPSimpleTypeErr(ctxt, 6061 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6062 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6063 NULL, (xmlNodePtr) attr, NULL, expected, 6064 val, NULL, NULL, NULL); 6065 return (def); 6066 } 6067 return (ret); 6068} 6069 6070/** 6071 * xmlGetMinOccurs: 6072 * @ctxt: a schema validation context 6073 * @node: a subtree containing XML Schema informations 6074 * 6075 * Get the minOccurs property 6076 * 6077 * Returns the default if not found, or the value 6078 */ 6079static int 6080xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6081 int min, int max, int def, const char *expected) 6082{ 6083 const xmlChar *val, *cur; 6084 int ret = 0; 6085 xmlAttrPtr attr; 6086 6087 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6088 if (attr == NULL) 6089 return (def); 6090 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6091 cur = val; 6092 while (IS_BLANK_CH(*cur)) 6093 cur++; 6094 if (*cur == 0) { 6095 xmlSchemaPSimpleTypeErr(ctxt, 6096 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6097 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6098 NULL, (xmlNodePtr) attr, NULL, expected, 6099 val, NULL, NULL, NULL); 6100 return (def); 6101 } 6102 while ((*cur >= '0') && (*cur <= '9')) { 6103 ret = ret * 10 + (*cur - '0'); 6104 cur++; 6105 } 6106 while (IS_BLANK_CH(*cur)) 6107 cur++; 6108 /* 6109 * TODO: Restrict the maximal value to Integer. 6110 */ 6111 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6112 xmlSchemaPSimpleTypeErr(ctxt, 6113 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6114 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6115 NULL, (xmlNodePtr) attr, NULL, expected, 6116 val, NULL, NULL, NULL); 6117 return (def); 6118 } 6119 return (ret); 6120} 6121 6122/** 6123 * xmlSchemaPGetBoolNodeValue: 6124 * @ctxt: a schema validation context 6125 * @ownerDes: owner designation 6126 * @ownerItem: the owner as a schema item 6127 * @node: the node holding the value 6128 * 6129 * Converts a boolean string value into 1 or 0. 6130 * 6131 * Returns 0 or 1. 6132 */ 6133static int 6134xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6135 xmlSchemaBasicItemPtr ownerItem, 6136 xmlNodePtr node) 6137{ 6138 xmlChar *value = NULL; 6139 int res = 0; 6140 6141 value = xmlNodeGetContent(node); 6142 /* 6143 * 3.2.2.1 Lexical representation 6144 * An instance of a datatype that is defined as `boolean` 6145 * can have the following legal literals {true, false, 1, 0}. 6146 */ 6147 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6148 res = 1; 6149 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6150 res = 0; 6151 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6152 res = 1; 6153 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6154 res = 0; 6155 else { 6156 xmlSchemaPSimpleTypeErr(ctxt, 6157 XML_SCHEMAP_INVALID_BOOLEAN, 6158 ownerItem, node, 6159 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6160 NULL, BAD_CAST value, 6161 NULL, NULL, NULL); 6162 } 6163 if (value != NULL) 6164 xmlFree(value); 6165 return (res); 6166} 6167 6168/** 6169 * xmlGetBooleanProp: 6170 * @ctxt: a schema validation context 6171 * @node: a subtree containing XML Schema informations 6172 * @name: the attribute name 6173 * @def: the default value 6174 * 6175 * Evaluate if a boolean property is set 6176 * 6177 * Returns the default if not found, 0 if found to be false, 6178 * 1 if found to be true 6179 */ 6180static int 6181xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6182 xmlNodePtr node, 6183 const char *name, int def) 6184{ 6185 const xmlChar *val; 6186 6187 val = xmlSchemaGetProp(ctxt, node, name); 6188 if (val == NULL) 6189 return (def); 6190 /* 6191 * 3.2.2.1 Lexical representation 6192 * An instance of a datatype that is defined as `boolean` 6193 * can have the following legal literals {true, false, 1, 0}. 6194 */ 6195 if (xmlStrEqual(val, BAD_CAST "true")) 6196 def = 1; 6197 else if (xmlStrEqual(val, BAD_CAST "false")) 6198 def = 0; 6199 else if (xmlStrEqual(val, BAD_CAST "1")) 6200 def = 1; 6201 else if (xmlStrEqual(val, BAD_CAST "0")) 6202 def = 0; 6203 else { 6204 xmlSchemaPSimpleTypeErr(ctxt, 6205 XML_SCHEMAP_INVALID_BOOLEAN, 6206 NULL, 6207 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6208 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6209 NULL, val, NULL, NULL, NULL); 6210 } 6211 return (def); 6212} 6213 6214/************************************************************************ 6215 * * 6216 * Shema extraction from an Infoset * 6217 * * 6218 ************************************************************************/ 6219static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6220 ctxt, xmlSchemaPtr schema, 6221 xmlNodePtr node, 6222 int topLevel); 6223static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6224 ctxt, 6225 xmlSchemaPtr schema, 6226 xmlNodePtr node, 6227 int topLevel); 6228static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6229 ctxt, 6230 xmlSchemaPtr schema, 6231 xmlNodePtr node, 6232 xmlSchemaTypeType parentType); 6233static xmlSchemaBasicItemPtr 6234xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6235 xmlSchemaPtr schema, 6236 xmlNodePtr node, 6237 xmlSchemaItemListPtr uses, 6238 int parentType); 6239static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6240 xmlSchemaPtr schema, 6241 xmlNodePtr node); 6242static xmlSchemaWildcardPtr 6243xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6244 xmlSchemaPtr schema, xmlNodePtr node); 6245 6246/** 6247 * xmlSchemaPValAttrNodeValue: 6248 * 6249 * @ctxt: a schema parser context 6250 * @ownerDes: the designation of the parent element 6251 * @ownerItem: the schema object owner if existent 6252 * @attr: the schema attribute node being validated 6253 * @value: the value 6254 * @type: the built-in type to be validated against 6255 * 6256 * Validates a value against the given built-in type. 6257 * This one is intended to be used internally for validation 6258 * of schema attribute values during parsing of the schema. 6259 * 6260 * Returns 0 if the value is valid, a positive error code 6261 * number otherwise and -1 in case of an internal or API error. 6262 */ 6263static int 6264xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6265 xmlSchemaBasicItemPtr ownerItem, 6266 xmlAttrPtr attr, 6267 const xmlChar *value, 6268 xmlSchemaTypePtr type) 6269{ 6270 6271 int ret = 0; 6272 6273 /* 6274 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6275 * one is really meant to be used internally, so better not. 6276 */ 6277 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6278 return (-1); 6279 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6280 PERROR_INT("xmlSchemaPValAttrNodeValue", 6281 "the given type is not a built-in type"); 6282 return (-1); 6283 } 6284 switch (type->builtInType) { 6285 case XML_SCHEMAS_NCNAME: 6286 case XML_SCHEMAS_QNAME: 6287 case XML_SCHEMAS_ANYURI: 6288 case XML_SCHEMAS_TOKEN: 6289 case XML_SCHEMAS_LANGUAGE: 6290 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6291 (xmlNodePtr) attr); 6292 break; 6293 default: { 6294 PERROR_INT("xmlSchemaPValAttrNodeValue", 6295 "validation using the given type is not supported while " 6296 "parsing a schema"); 6297 return (-1); 6298 } 6299 } 6300 /* 6301 * TODO: Should we use the S4S error codes instead? 6302 */ 6303 if (ret < 0) { 6304 PERROR_INT("xmlSchemaPValAttrNodeValue", 6305 "failed to validate a schema attribute value"); 6306 return (-1); 6307 } else if (ret > 0) { 6308 if (WXS_IS_LIST(type)) 6309 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6310 else 6311 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6312 xmlSchemaPSimpleTypeErr(pctxt, 6313 ret, ownerItem, (xmlNodePtr) attr, 6314 type, NULL, value, NULL, NULL, NULL); 6315 } 6316 return (ret); 6317} 6318 6319/** 6320 * xmlSchemaPValAttrNode: 6321 * 6322 * @ctxt: a schema parser context 6323 * @ownerDes: the designation of the parent element 6324 * @ownerItem: the schema object owner if existent 6325 * @attr: the schema attribute node being validated 6326 * @type: the built-in type to be validated against 6327 * @value: the resulting value if any 6328 * 6329 * Extracts and validates a value against the given built-in type. 6330 * This one is intended to be used internally for validation 6331 * of schema attribute values during parsing of the schema. 6332 * 6333 * Returns 0 if the value is valid, a positive error code 6334 * number otherwise and -1 in case of an internal or API error. 6335 */ 6336static int 6337xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6338 xmlSchemaBasicItemPtr ownerItem, 6339 xmlAttrPtr attr, 6340 xmlSchemaTypePtr type, 6341 const xmlChar **value) 6342{ 6343 const xmlChar *val; 6344 6345 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6346 return (-1); 6347 6348 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6349 if (value != NULL) 6350 *value = val; 6351 6352 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6353 val, type)); 6354} 6355 6356/** 6357 * xmlSchemaPValAttr: 6358 * 6359 * @ctxt: a schema parser context 6360 * @node: the element node of the attribute 6361 * @ownerDes: the designation of the parent element 6362 * @ownerItem: the schema object owner if existent 6363 * @ownerElem: the owner element node 6364 * @name: the name of the schema attribute node 6365 * @type: the built-in type to be validated against 6366 * @value: the resulting value if any 6367 * 6368 * Extracts and validates a value against the given built-in type. 6369 * This one is intended to be used internally for validation 6370 * of schema attribute values during parsing of the schema. 6371 * 6372 * Returns 0 if the value is valid, a positive error code 6373 * number otherwise and -1 in case of an internal or API error. 6374 */ 6375static int 6376xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6377 xmlSchemaBasicItemPtr ownerItem, 6378 xmlNodePtr ownerElem, 6379 const char *name, 6380 xmlSchemaTypePtr type, 6381 const xmlChar **value) 6382{ 6383 xmlAttrPtr attr; 6384 6385 if ((ctxt == NULL) || (type == NULL)) { 6386 if (value != NULL) 6387 *value = NULL; 6388 return (-1); 6389 } 6390 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6391 if (value != NULL) 6392 *value = NULL; 6393 xmlSchemaPErr(ctxt, ownerElem, 6394 XML_SCHEMAP_INTERNAL, 6395 "Internal error: xmlSchemaPValAttr, the given " 6396 "type '%s' is not a built-in type.\n", 6397 type->name, NULL); 6398 return (-1); 6399 } 6400 attr = xmlSchemaGetPropNode(ownerElem, name); 6401 if (attr == NULL) { 6402 if (value != NULL) 6403 *value = NULL; 6404 return (0); 6405 } 6406 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6407 type, value)); 6408} 6409 6410static int 6411xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6412 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6413 xmlNodePtr node, 6414 xmlAttrPtr attr, 6415 const xmlChar *namespaceName) 6416{ 6417 /* TODO: Pointer comparison instead? */ 6418 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6419 return (0); 6420 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6421 return (0); 6422 /* 6423 * Check if the referenced namespace was <import>ed. 6424 */ 6425 if (WXS_BUCKET(pctxt)->relations != NULL) { 6426 xmlSchemaSchemaRelationPtr rel; 6427 6428 rel = WXS_BUCKET(pctxt)->relations; 6429 do { 6430 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6431 xmlStrEqual(namespaceName, rel->importNamespace)) 6432 return (0); 6433 rel = rel->next; 6434 } while (rel != NULL); 6435 } 6436 /* 6437 * No matching <import>ed namespace found. 6438 */ 6439 { 6440 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6441 6442 if (namespaceName == NULL) 6443 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6444 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6445 "References from this schema to components in no " 6446 "namespace are not allowed, since not indicated by an " 6447 "import statement", NULL, NULL); 6448 else 6449 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6450 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6451 "References from this schema to components in the " 6452 "namespace '%s' are not allowed, since not indicated by an " 6453 "import statement", namespaceName, NULL); 6454 } 6455 return (XML_SCHEMAP_SRC_RESOLVE); 6456} 6457 6458/** 6459 * xmlSchemaParseLocalAttributes: 6460 * @ctxt: a schema validation context 6461 * @schema: the schema being built 6462 * @node: a subtree containing XML Schema informations 6463 * @type: the hosting type where the attributes will be anchored 6464 * 6465 * Parses attribute uses and attribute declarations and 6466 * attribute group references. 6467 */ 6468static int 6469xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6470 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6471 int parentType, int *hasRefs) 6472{ 6473 void *item; 6474 6475 while ((IS_SCHEMA((*child), "attribute")) || 6476 (IS_SCHEMA((*child), "attributeGroup"))) { 6477 if (IS_SCHEMA((*child), "attribute")) { 6478 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6479 *list, parentType); 6480 } else { 6481 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6482 if ((item != NULL) && (hasRefs != NULL)) 6483 *hasRefs = 1; 6484 } 6485 if (item != NULL) { 6486 if (*list == NULL) { 6487 /* TODO: Customize grow factor. */ 6488 *list = xmlSchemaItemListCreate(); 6489 if (*list == NULL) 6490 return(-1); 6491 } 6492 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6493 return(-1); 6494 } 6495 *child = (*child)->next; 6496 } 6497 return (0); 6498} 6499 6500/** 6501 * xmlSchemaParseAnnotation: 6502 * @ctxt: a schema validation context 6503 * @schema: the schema being built 6504 * @node: a subtree containing XML Schema informations 6505 * 6506 * parse a XML schema Attrribute declaration 6507 * *WARNING* this interface is highly subject to change 6508 * 6509 * Returns -1 in case of error, 0 if the declaration is improper and 6510 * 1 in case of success. 6511 */ 6512static xmlSchemaAnnotPtr 6513xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6514{ 6515 xmlSchemaAnnotPtr ret; 6516 xmlNodePtr child = NULL; 6517 xmlAttrPtr attr; 6518 int barked = 0; 6519 6520 /* 6521 * INFO: S4S completed. 6522 */ 6523 /* 6524 * id = ID 6525 * {any attributes with non-schema namespace . . .}> 6526 * Content: (appinfo | documentation)* 6527 */ 6528 if ((ctxt == NULL) || (node == NULL)) 6529 return (NULL); 6530 if (needed) 6531 ret = xmlSchemaNewAnnot(ctxt, node); 6532 else 6533 ret = NULL; 6534 attr = node->properties; 6535 while (attr != NULL) { 6536 if (((attr->ns == NULL) && 6537 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6538 ((attr->ns != NULL) && 6539 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6540 6541 xmlSchemaPIllegalAttrErr(ctxt, 6542 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6543 } 6544 attr = attr->next; 6545 } 6546 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6547 /* 6548 * And now for the children... 6549 */ 6550 child = node->children; 6551 while (child != NULL) { 6552 if (IS_SCHEMA(child, "appinfo")) { 6553 /* TODO: make available the content of "appinfo". */ 6554 /* 6555 * source = anyURI 6556 * {any attributes with non-schema namespace . . .}> 6557 * Content: ({any})* 6558 */ 6559 attr = child->properties; 6560 while (attr != NULL) { 6561 if (((attr->ns == NULL) && 6562 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6563 ((attr->ns != NULL) && 6564 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6565 6566 xmlSchemaPIllegalAttrErr(ctxt, 6567 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6568 } 6569 attr = attr->next; 6570 } 6571 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6572 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6573 child = child->next; 6574 } else if (IS_SCHEMA(child, "documentation")) { 6575 /* TODO: make available the content of "documentation". */ 6576 /* 6577 * source = anyURI 6578 * {any attributes with non-schema namespace . . .}> 6579 * Content: ({any})* 6580 */ 6581 attr = child->properties; 6582 while (attr != NULL) { 6583 if (attr->ns == NULL) { 6584 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6585 xmlSchemaPIllegalAttrErr(ctxt, 6586 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6587 } 6588 } else { 6589 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6590 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6591 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6592 6593 xmlSchemaPIllegalAttrErr(ctxt, 6594 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6595 } 6596 } 6597 attr = attr->next; 6598 } 6599 /* 6600 * Attribute "xml:lang". 6601 */ 6602 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6603 if (attr != NULL) 6604 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6605 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6606 child = child->next; 6607 } else { 6608 if (!barked) 6609 xmlSchemaPContentErr(ctxt, 6610 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6611 NULL, node, child, NULL, "(appinfo | documentation)*"); 6612 barked = 1; 6613 child = child->next; 6614 } 6615 } 6616 6617 return (ret); 6618} 6619 6620/** 6621 * xmlSchemaParseFacet: 6622 * @ctxt: a schema validation context 6623 * @schema: the schema being built 6624 * @node: a subtree containing XML Schema informations 6625 * 6626 * parse a XML schema Facet declaration 6627 * *WARNING* this interface is highly subject to change 6628 * 6629 * Returns the new type structure or NULL in case of error 6630 */ 6631static xmlSchemaFacetPtr 6632xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6633 xmlNodePtr node) 6634{ 6635 xmlSchemaFacetPtr facet; 6636 xmlNodePtr child = NULL; 6637 const xmlChar *value; 6638 6639 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6640 return (NULL); 6641 6642 facet = xmlSchemaNewFacet(); 6643 if (facet == NULL) { 6644 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6645 return (NULL); 6646 } 6647 facet->node = node; 6648 value = xmlSchemaGetProp(ctxt, node, "value"); 6649 if (value == NULL) { 6650 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6651 "Facet %s has no value\n", node->name, NULL); 6652 xmlSchemaFreeFacet(facet); 6653 return (NULL); 6654 } 6655 if (IS_SCHEMA(node, "minInclusive")) { 6656 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6657 } else if (IS_SCHEMA(node, "minExclusive")) { 6658 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6659 } else if (IS_SCHEMA(node, "maxInclusive")) { 6660 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6661 } else if (IS_SCHEMA(node, "maxExclusive")) { 6662 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6663 } else if (IS_SCHEMA(node, "totalDigits")) { 6664 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6665 } else if (IS_SCHEMA(node, "fractionDigits")) { 6666 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6667 } else if (IS_SCHEMA(node, "pattern")) { 6668 facet->type = XML_SCHEMA_FACET_PATTERN; 6669 } else if (IS_SCHEMA(node, "enumeration")) { 6670 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6671 } else if (IS_SCHEMA(node, "whiteSpace")) { 6672 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6673 } else if (IS_SCHEMA(node, "length")) { 6674 facet->type = XML_SCHEMA_FACET_LENGTH; 6675 } else if (IS_SCHEMA(node, "maxLength")) { 6676 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6677 } else if (IS_SCHEMA(node, "minLength")) { 6678 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6679 } else { 6680 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6681 "Unknown facet type %s\n", node->name, NULL); 6682 xmlSchemaFreeFacet(facet); 6683 return (NULL); 6684 } 6685 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6686 facet->value = value; 6687 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6688 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6689 const xmlChar *fixed; 6690 6691 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6692 if (fixed != NULL) { 6693 if (xmlStrEqual(fixed, BAD_CAST "true")) 6694 facet->fixed = 1; 6695 } 6696 } 6697 child = node->children; 6698 6699 if (IS_SCHEMA(child, "annotation")) { 6700 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6701 child = child->next; 6702 } 6703 if (child != NULL) { 6704 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6705 "Facet %s has unexpected child content\n", 6706 node->name, NULL); 6707 } 6708 return (facet); 6709} 6710 6711/** 6712 * xmlSchemaParseWildcardNs: 6713 * @ctxt: a schema parser context 6714 * @wildc: the wildcard, already created 6715 * @node: a subtree containing XML Schema informations 6716 * 6717 * Parses the attribute "processContents" and "namespace" 6718 * of a xsd:anyAttribute and xsd:any. 6719 * *WARNING* this interface is highly subject to change 6720 * 6721 * Returns 0 if everything goes fine, a positive error code 6722 * if something is not valid and -1 if an internal error occurs. 6723 */ 6724static int 6725xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6726 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6727 xmlSchemaWildcardPtr wildc, 6728 xmlNodePtr node) 6729{ 6730 const xmlChar *pc, *ns, *dictnsItem; 6731 int ret = 0; 6732 xmlChar *nsItem; 6733 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6734 xmlAttrPtr attr; 6735 6736 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6737 if ((pc == NULL) 6738 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6739 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6740 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6741 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6742 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6743 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6744 } else { 6745 xmlSchemaPSimpleTypeErr(ctxt, 6746 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6747 NULL, node, 6748 NULL, "(strict | skip | lax)", pc, 6749 NULL, NULL, NULL); 6750 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6751 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6752 } 6753 /* 6754 * Build the namespace constraints. 6755 */ 6756 attr = xmlSchemaGetPropNode(node, "namespace"); 6757 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6758 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6759 wildc->any = 1; 6760 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6761 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6762 if (wildc->negNsSet == NULL) { 6763 return (-1); 6764 } 6765 wildc->negNsSet->value = ctxt->targetNamespace; 6766 } else { 6767 const xmlChar *end, *cur; 6768 6769 cur = ns; 6770 do { 6771 while (IS_BLANK_CH(*cur)) 6772 cur++; 6773 end = cur; 6774 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6775 end++; 6776 if (end == cur) 6777 break; 6778 nsItem = xmlStrndup(cur, end - cur); 6779 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6780 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6781 xmlSchemaPSimpleTypeErr(ctxt, 6782 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6783 NULL, (xmlNodePtr) attr, 6784 NULL, 6785 "((##any | ##other) | List of (xs:anyURI | " 6786 "(##targetNamespace | ##local)))", 6787 nsItem, NULL, NULL, NULL); 6788 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6789 } else { 6790 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6791 dictnsItem = ctxt->targetNamespace; 6792 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6793 dictnsItem = NULL; 6794 } else { 6795 /* 6796 * Validate the item (anyURI). 6797 */ 6798 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6799 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6800 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6801 } 6802 /* 6803 * Avoid dublicate namespaces. 6804 */ 6805 tmp = wildc->nsSet; 6806 while (tmp != NULL) { 6807 if (dictnsItem == tmp->value) 6808 break; 6809 tmp = tmp->next; 6810 } 6811 if (tmp == NULL) { 6812 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6813 if (tmp == NULL) { 6814 xmlFree(nsItem); 6815 return (-1); 6816 } 6817 tmp->value = dictnsItem; 6818 tmp->next = NULL; 6819 if (wildc->nsSet == NULL) 6820 wildc->nsSet = tmp; 6821 else if (lastNs != NULL) 6822 lastNs->next = tmp; 6823 lastNs = tmp; 6824 } 6825 6826 } 6827 xmlFree(nsItem); 6828 cur = end; 6829 } while (*cur != 0); 6830 } 6831 return (ret); 6832} 6833 6834static int 6835xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6836 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6837 xmlNodePtr node, 6838 int minOccurs, 6839 int maxOccurs) { 6840 6841 if ((maxOccurs == 0) && ( minOccurs == 0)) 6842 return (0); 6843 if (maxOccurs != UNBOUNDED) { 6844 /* 6845 * TODO: Maybe we should better not create the particle, 6846 * if min/max is invalid, since it could confuse the build of the 6847 * content model. 6848 */ 6849 /* 6850 * 3.9.6 Schema Component Constraint: Particle Correct 6851 * 6852 */ 6853 if (maxOccurs < 1) { 6854 /* 6855 * 2.2 {max occurs} must be greater than or equal to 1. 6856 */ 6857 xmlSchemaPCustomAttrErr(ctxt, 6858 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6859 NULL, NULL, 6860 xmlSchemaGetPropNode(node, "maxOccurs"), 6861 "The value must be greater than or equal to 1"); 6862 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6863 } else if (minOccurs > maxOccurs) { 6864 /* 6865 * 2.1 {min occurs} must not be greater than {max occurs}. 6866 */ 6867 xmlSchemaPCustomAttrErr(ctxt, 6868 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6869 NULL, NULL, 6870 xmlSchemaGetPropNode(node, "minOccurs"), 6871 "The value must not be greater than the value of 'maxOccurs'"); 6872 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6873 } 6874 } 6875 return (0); 6876} 6877 6878/** 6879 * xmlSchemaParseAny: 6880 * @ctxt: a schema validation context 6881 * @schema: the schema being built 6882 * @node: a subtree containing XML Schema informations 6883 * 6884 * Parsea a XML schema <any> element. A particle and wildcard 6885 * will be created (except if minOccurs==maxOccurs==0, in this case 6886 * nothing will be created). 6887 * *WARNING* this interface is highly subject to change 6888 * 6889 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6890 */ 6891static xmlSchemaParticlePtr 6892xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6893 xmlNodePtr node) 6894{ 6895 xmlSchemaParticlePtr particle; 6896 xmlNodePtr child = NULL; 6897 xmlSchemaWildcardPtr wild; 6898 int min, max; 6899 xmlAttrPtr attr; 6900 xmlSchemaAnnotPtr annot = NULL; 6901 6902 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6903 return (NULL); 6904 /* 6905 * Check for illegal attributes. 6906 */ 6907 attr = node->properties; 6908 while (attr != NULL) { 6909 if (attr->ns == NULL) { 6910 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6911 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6912 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6913 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6914 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6915 xmlSchemaPIllegalAttrErr(ctxt, 6916 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6917 } 6918 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6919 xmlSchemaPIllegalAttrErr(ctxt, 6920 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6921 } 6922 attr = attr->next; 6923 } 6924 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6925 /* 6926 * minOccurs/maxOccurs. 6927 */ 6928 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6929 "(xs:nonNegativeInteger | unbounded)"); 6930 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6931 "xs:nonNegativeInteger"); 6932 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6933 /* 6934 * Create & parse the wildcard. 6935 */ 6936 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6937 if (wild == NULL) 6938 return (NULL); 6939 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6940 /* 6941 * And now for the children... 6942 */ 6943 child = node->children; 6944 if (IS_SCHEMA(child, "annotation")) { 6945 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6946 child = child->next; 6947 } 6948 if (child != NULL) { 6949 xmlSchemaPContentErr(ctxt, 6950 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6951 NULL, node, child, 6952 NULL, "(annotation?)"); 6953 } 6954 /* 6955 * No component if minOccurs==maxOccurs==0. 6956 */ 6957 if ((min == 0) && (max == 0)) { 6958 /* Don't free the wildcard, since it's already on the list. */ 6959 return (NULL); 6960 } 6961 /* 6962 * Create the particle. 6963 */ 6964 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6965 if (particle == NULL) 6966 return (NULL); 6967 particle->annot = annot; 6968 particle->children = (xmlSchemaTreeItemPtr) wild; 6969 6970 return (particle); 6971} 6972 6973/** 6974 * xmlSchemaParseNotation: 6975 * @ctxt: a schema validation context 6976 * @schema: the schema being built 6977 * @node: a subtree containing XML Schema informations 6978 * 6979 * parse a XML schema Notation declaration 6980 * 6981 * Returns the new structure or NULL in case of error 6982 */ 6983static xmlSchemaNotationPtr 6984xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6985 xmlNodePtr node) 6986{ 6987 const xmlChar *name; 6988 xmlSchemaNotationPtr ret; 6989 xmlNodePtr child = NULL; 6990 6991 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6992 return (NULL); 6993 name = xmlSchemaGetProp(ctxt, node, "name"); 6994 if (name == NULL) { 6995 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 6996 "Notation has no name\n", NULL, NULL); 6997 return (NULL); 6998 } 6999 ret = xmlSchemaAddNotation(ctxt, schema, name, 7000 ctxt->targetNamespace, node); 7001 if (ret == NULL) 7002 return (NULL); 7003 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7004 7005 child = node->children; 7006 if (IS_SCHEMA(child, "annotation")) { 7007 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7008 child = child->next; 7009 } 7010 if (child != NULL) { 7011 xmlSchemaPContentErr(ctxt, 7012 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7013 NULL, node, child, 7014 NULL, "(annotation?)"); 7015 } 7016 7017 return (ret); 7018} 7019 7020/** 7021 * xmlSchemaParseAnyAttribute: 7022 * @ctxt: a schema validation context 7023 * @schema: the schema being built 7024 * @node: a subtree containing XML Schema informations 7025 * 7026 * parse a XML schema AnyAttrribute declaration 7027 * *WARNING* this interface is highly subject to change 7028 * 7029 * Returns a wildcard or NULL. 7030 */ 7031static xmlSchemaWildcardPtr 7032xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7033 xmlSchemaPtr schema, xmlNodePtr node) 7034{ 7035 xmlSchemaWildcardPtr ret; 7036 xmlNodePtr child = NULL; 7037 xmlAttrPtr attr; 7038 7039 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7040 return (NULL); 7041 7042 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7043 node); 7044 if (ret == NULL) { 7045 return (NULL); 7046 } 7047 /* 7048 * Check for illegal attributes. 7049 */ 7050 attr = node->properties; 7051 while (attr != NULL) { 7052 if (attr->ns == NULL) { 7053 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7054 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7055 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7056 xmlSchemaPIllegalAttrErr(ctxt, 7057 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7058 } 7059 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7060 xmlSchemaPIllegalAttrErr(ctxt, 7061 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7062 } 7063 attr = attr->next; 7064 } 7065 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7066 /* 7067 * Parse the namespace list. 7068 */ 7069 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7070 return (NULL); 7071 /* 7072 * And now for the children... 7073 */ 7074 child = node->children; 7075 if (IS_SCHEMA(child, "annotation")) { 7076 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7077 child = child->next; 7078 } 7079 if (child != NULL) { 7080 xmlSchemaPContentErr(ctxt, 7081 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7082 NULL, node, child, 7083 NULL, "(annotation?)"); 7084 } 7085 7086 return (ret); 7087} 7088 7089 7090/** 7091 * xmlSchemaParseAttribute: 7092 * @ctxt: a schema validation context 7093 * @schema: the schema being built 7094 * @node: a subtree containing XML Schema informations 7095 * 7096 * parse a XML schema Attrribute declaration 7097 * *WARNING* this interface is highly subject to change 7098 * 7099 * Returns the attribute declaration. 7100 */ 7101static xmlSchemaBasicItemPtr 7102xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7103 xmlSchemaPtr schema, 7104 xmlNodePtr node, 7105 xmlSchemaItemListPtr uses, 7106 int parentType) 7107{ 7108 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7109 xmlSchemaAttributeUsePtr use = NULL; 7110 xmlNodePtr child = NULL; 7111 xmlAttrPtr attr; 7112 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7113 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7114 int nberrors, hasForm = 0, defValueType = 0; 7115 7116#define WXS_ATTR_DEF_VAL_DEFAULT 1 7117#define WXS_ATTR_DEF_VAL_FIXED 2 7118 7119 /* 7120 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7121 */ 7122 7123 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7124 return (NULL); 7125 attr = xmlSchemaGetPropNode(node, "ref"); 7126 if (attr != NULL) { 7127 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7128 NULL, attr, &tmpNs, &tmpName) != 0) { 7129 return (NULL); 7130 } 7131 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7132 return(NULL); 7133 isRef = 1; 7134 } 7135 nberrors = pctxt->nberrors; 7136 /* 7137 * Check for illegal attributes. 7138 */ 7139 attr = node->properties; 7140 while (attr != NULL) { 7141 if (attr->ns == NULL) { 7142 if (isRef) { 7143 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7144 xmlSchemaPValAttrNodeID(pctxt, attr); 7145 goto attr_next; 7146 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7147 goto attr_next; 7148 } 7149 } else { 7150 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7151 goto attr_next; 7152 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7153 xmlSchemaPValAttrNodeID(pctxt, attr); 7154 goto attr_next; 7155 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7156 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7157 attr, &tmpNs, &tmpName); 7158 goto attr_next; 7159 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7160 /* 7161 * Evaluate the target namespace 7162 */ 7163 hasForm = 1; 7164 attrValue = xmlSchemaGetNodeContent(pctxt, 7165 (xmlNodePtr) attr); 7166 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7167 ns = pctxt->targetNamespace; 7168 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7169 { 7170 xmlSchemaPSimpleTypeErr(pctxt, 7171 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7172 NULL, (xmlNodePtr) attr, 7173 NULL, "(qualified | unqualified)", 7174 attrValue, NULL, NULL, NULL); 7175 } 7176 goto attr_next; 7177 } 7178 } 7179 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7180 7181 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7182 /* TODO: Maybe we need to normalize the value beforehand. */ 7183 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7184 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7185 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7186 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7187 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7188 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7189 else { 7190 xmlSchemaPSimpleTypeErr(pctxt, 7191 XML_SCHEMAP_INVALID_ATTR_USE, 7192 NULL, (xmlNodePtr) attr, 7193 NULL, "(optional | prohibited | required)", 7194 attrValue, NULL, NULL, NULL); 7195 } 7196 goto attr_next; 7197 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7198 /* 7199 * 3.2.3 : 1 7200 * default and fixed must not both be present. 7201 */ 7202 if (defValue) { 7203 xmlSchemaPMutualExclAttrErr(pctxt, 7204 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7205 NULL, attr, "default", "fixed"); 7206 } else { 7207 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7208 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7209 } 7210 goto attr_next; 7211 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7212 /* 7213 * 3.2.3 : 1 7214 * default and fixed must not both be present. 7215 */ 7216 if (defValue) { 7217 xmlSchemaPMutualExclAttrErr(pctxt, 7218 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7219 NULL, attr, "default", "fixed"); 7220 } else { 7221 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7222 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7223 } 7224 goto attr_next; 7225 } 7226 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7227 goto attr_next; 7228 7229 xmlSchemaPIllegalAttrErr(pctxt, 7230 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7231 7232attr_next: 7233 attr = attr->next; 7234 } 7235 /* 7236 * 3.2.3 : 2 7237 * If default and use are both present, use must have 7238 * the actual value optional. 7239 */ 7240 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7241 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7242 xmlSchemaPSimpleTypeErr(pctxt, 7243 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7244 NULL, node, NULL, 7245 "(optional | prohibited | required)", NULL, 7246 "The value of the attribute 'use' must be 'optional' " 7247 "if the attribute 'default' is present", 7248 NULL, NULL); 7249 } 7250 /* 7251 * We want correct attributes. 7252 */ 7253 if (nberrors != pctxt->nberrors) 7254 return(NULL); 7255 if (! isRef) { 7256 xmlSchemaAttributePtr attrDecl; 7257 7258 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7259 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7260 ns = pctxt->targetNamespace; 7261 /* 7262 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7263 * TODO: Move this to the component layer. 7264 */ 7265 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7266 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7267 XML_SCHEMAP_NO_XSI, 7268 node, NULL, 7269 "The target namespace must not match '%s'", 7270 xmlSchemaInstanceNs, NULL); 7271 } 7272 attr = xmlSchemaGetPropNode(node, "name"); 7273 if (attr == NULL) { 7274 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7275 NULL, node, "name", NULL); 7276 return (NULL); 7277 } 7278 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7279 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7280 return (NULL); 7281 } 7282 /* 7283 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7284 * TODO: Move this to the component layer. 7285 */ 7286 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7287 xmlSchemaPSimpleTypeErr(pctxt, 7288 XML_SCHEMAP_NO_XMLNS, 7289 NULL, (xmlNodePtr) attr, 7290 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7291 "The value of the attribute must not match 'xmlns'", 7292 NULL, NULL); 7293 return (NULL); 7294 } 7295 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7296 goto check_children; 7297 /* 7298 * Create the attribute use component. 7299 */ 7300 use = xmlSchemaAddAttributeUse(pctxt, node); 7301 if (use == NULL) 7302 return(NULL); 7303 use->occurs = occurs; 7304 /* 7305 * Create the attribute declaration. 7306 */ 7307 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7308 if (attrDecl == NULL) 7309 return (NULL); 7310 if (tmpName != NULL) { 7311 attrDecl->typeName = tmpName; 7312 attrDecl->typeNs = tmpNs; 7313 } 7314 use->attrDecl = attrDecl; 7315 /* 7316 * Value constraint. 7317 */ 7318 if (defValue != NULL) { 7319 attrDecl->defValue = defValue; 7320 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7321 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7322 } 7323 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7324 xmlSchemaQNameRefPtr ref; 7325 7326 /* 7327 * Create the attribute use component. 7328 */ 7329 use = xmlSchemaAddAttributeUse(pctxt, node); 7330 if (use == NULL) 7331 return(NULL); 7332 /* 7333 * We need to resolve the reference at later stage. 7334 */ 7335 WXS_ADD_PENDING(pctxt, use); 7336 use->occurs = occurs; 7337 /* 7338 * Create a QName reference to the attribute declaration. 7339 */ 7340 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7341 tmpName, tmpNs); 7342 if (ref == NULL) 7343 return(NULL); 7344 /* 7345 * Assign the reference. This will be substituted for the 7346 * referenced attribute declaration when the QName is resolved. 7347 */ 7348 use->attrDecl = WXS_ATTR_CAST ref; 7349 /* 7350 * Value constraint. 7351 */ 7352 if (defValue != NULL) 7353 use->defValue = defValue; 7354 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7355 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7356 } 7357 7358check_children: 7359 /* 7360 * And now for the children... 7361 */ 7362 child = node->children; 7363 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7364 xmlSchemaAttributeUseProhibPtr prohib; 7365 7366 if (IS_SCHEMA(child, "annotation")) { 7367 xmlSchemaParseAnnotation(pctxt, child, 0); 7368 child = child->next; 7369 } 7370 if (child != NULL) { 7371 xmlSchemaPContentErr(pctxt, 7372 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7373 NULL, node, child, NULL, 7374 "(annotation?)"); 7375 } 7376 /* 7377 * Check for pointlessness of attribute prohibitions. 7378 */ 7379 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7380 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7381 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7382 node, NULL, 7383 "Skipping attribute use prohibition, since it is " 7384 "pointless inside an <attributeGroup>", 7385 NULL, NULL, NULL); 7386 return(NULL); 7387 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7388 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7389 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7390 node, NULL, 7391 "Skipping attribute use prohibition, since it is " 7392 "pointless when extending a type", 7393 NULL, NULL, NULL); 7394 return(NULL); 7395 } 7396 if (! isRef) { 7397 tmpName = name; 7398 tmpNs = ns; 7399 } 7400 /* 7401 * Check for duplicate attribute prohibitions. 7402 */ 7403 if (uses) { 7404 int i; 7405 7406 for (i = 0; i < uses->nbItems; i++) { 7407 use = uses->items[i]; 7408 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7409 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7410 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7411 { 7412 xmlChar *str = NULL; 7413 7414 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7415 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7416 node, NULL, 7417 "Skipping duplicate attribute use prohibition '%s'", 7418 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7419 NULL, NULL); 7420 FREE_AND_NULL(str) 7421 return(NULL); 7422 } 7423 } 7424 } 7425 /* 7426 * Create the attribute prohibition helper component. 7427 */ 7428 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7429 if (prohib == NULL) 7430 return(NULL); 7431 prohib->node = node; 7432 prohib->name = tmpName; 7433 prohib->targetNamespace = tmpNs; 7434 if (isRef) { 7435 /* 7436 * We need at least to resolve to the attribute declaration. 7437 */ 7438 WXS_ADD_PENDING(pctxt, prohib); 7439 } 7440 return(WXS_BASIC_CAST prohib); 7441 } else { 7442 if (IS_SCHEMA(child, "annotation")) { 7443 /* 7444 * TODO: Should this go into the attr decl? 7445 */ 7446 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7447 child = child->next; 7448 } 7449 if (isRef) { 7450 if (child != NULL) { 7451 if (IS_SCHEMA(child, "simpleType")) 7452 /* 7453 * 3.2.3 : 3.2 7454 * If ref is present, then all of <simpleType>, 7455 * form and type must be absent. 7456 */ 7457 xmlSchemaPContentErr(pctxt, 7458 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7459 NULL, node, child, NULL, 7460 "(annotation?)"); 7461 else 7462 xmlSchemaPContentErr(pctxt, 7463 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7464 NULL, node, child, NULL, 7465 "(annotation?)"); 7466 } 7467 } else { 7468 if (IS_SCHEMA(child, "simpleType")) { 7469 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7470 /* 7471 * 3.2.3 : 4 7472 * type and <simpleType> must not both be present. 7473 */ 7474 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7475 NULL, node, child, 7476 "The attribute 'type' and the <simpleType> child " 7477 "are mutually exclusive", NULL); 7478 } else 7479 WXS_ATTRUSE_TYPEDEF(use) = 7480 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7481 child = child->next; 7482 } 7483 if (child != NULL) 7484 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7485 NULL, node, child, NULL, 7486 "(annotation?, simpleType?)"); 7487 } 7488 } 7489 return (WXS_BASIC_CAST use); 7490} 7491 7492 7493static xmlSchemaAttributePtr 7494xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7495 xmlSchemaPtr schema, 7496 xmlNodePtr node) 7497{ 7498 const xmlChar *attrValue; 7499 xmlSchemaAttributePtr ret; 7500 xmlNodePtr child = NULL; 7501 xmlAttrPtr attr; 7502 7503 /* 7504 * Note that the w3c spec assumes the schema to be validated with schema 7505 * for schemas beforehand. 7506 * 7507 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7508 */ 7509 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7510 return (NULL); 7511 /* 7512 * 3.2.3 : 3.1 7513 * One of ref or name must be present, but not both 7514 */ 7515 attr = xmlSchemaGetPropNode(node, "name"); 7516 if (attr == NULL) { 7517 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7518 NULL, node, "name", NULL); 7519 return (NULL); 7520 } 7521 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7522 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7523 return (NULL); 7524 } 7525 /* 7526 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7527 * TODO: Move this to the component layer. 7528 */ 7529 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7530 xmlSchemaPSimpleTypeErr(pctxt, 7531 XML_SCHEMAP_NO_XMLNS, 7532 NULL, (xmlNodePtr) attr, 7533 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7534 "The value of the attribute must not match 'xmlns'", 7535 NULL, NULL); 7536 return (NULL); 7537 } 7538 /* 7539 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7540 * TODO: Move this to the component layer. 7541 * Or better leave it here and add it to the component layer 7542 * if we have a schema construction API. 7543 */ 7544 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7545 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7546 XML_SCHEMAP_NO_XSI, node, NULL, 7547 "The target namespace must not match '%s'", 7548 xmlSchemaInstanceNs, NULL); 7549 } 7550 7551 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7552 pctxt->targetNamespace, node, 1); 7553 if (ret == NULL) 7554 return (NULL); 7555 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7556 7557 /* 7558 * Check for illegal attributes. 7559 */ 7560 attr = node->properties; 7561 while (attr != NULL) { 7562 if (attr->ns == NULL) { 7563 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7564 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7565 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7566 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7567 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7568 { 7569 xmlSchemaPIllegalAttrErr(pctxt, 7570 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7571 } 7572 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7573 xmlSchemaPIllegalAttrErr(pctxt, 7574 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7575 } 7576 attr = attr->next; 7577 } 7578 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7579 node, "type", &ret->typeNs, &ret->typeName); 7580 7581 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7582 /* 7583 * Attribute "fixed". 7584 */ 7585 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7586 if (ret->defValue != NULL) 7587 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7588 /* 7589 * Attribute "default". 7590 */ 7591 attr = xmlSchemaGetPropNode(node, "default"); 7592 if (attr != NULL) { 7593 /* 7594 * 3.2.3 : 1 7595 * default and fixed must not both be present. 7596 */ 7597 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7598 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7599 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7600 } else 7601 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7602 } 7603 /* 7604 * And now for the children... 7605 */ 7606 child = node->children; 7607 if (IS_SCHEMA(child, "annotation")) { 7608 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7609 child = child->next; 7610 } 7611 if (IS_SCHEMA(child, "simpleType")) { 7612 if (ret->typeName != NULL) { 7613 /* 7614 * 3.2.3 : 4 7615 * type and <simpleType> must not both be present. 7616 */ 7617 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7618 NULL, node, child, 7619 "The attribute 'type' and the <simpleType> child " 7620 "are mutually exclusive", NULL); 7621 } else 7622 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7623 child = child->next; 7624 } 7625 if (child != NULL) 7626 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7627 NULL, node, child, NULL, 7628 "(annotation?, simpleType?)"); 7629 7630 return (ret); 7631} 7632 7633/** 7634 * xmlSchemaParseAttributeGroupRef: 7635 * @ctxt: a schema validation context 7636 * @schema: the schema being built 7637 * @node: a subtree containing XML Schema informations 7638 * 7639 * Parse an attribute group definition reference. 7640 * Note that a reference to an attribute group does not 7641 * correspond to any component at all. 7642 * *WARNING* this interface is highly subject to change 7643 * 7644 * Returns the attribute group or NULL in case of error. 7645 */ 7646static xmlSchemaQNameRefPtr 7647xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7648 xmlSchemaPtr schema, 7649 xmlNodePtr node) 7650{ 7651 xmlSchemaQNameRefPtr ret; 7652 xmlNodePtr child = NULL; 7653 xmlAttrPtr attr; 7654 const xmlChar *refNs = NULL, *ref = NULL; 7655 7656 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7657 return (NULL); 7658 7659 attr = xmlSchemaGetPropNode(node, "ref"); 7660 if (attr == NULL) { 7661 xmlSchemaPMissingAttrErr(pctxt, 7662 XML_SCHEMAP_S4S_ATTR_MISSING, 7663 NULL, node, "ref", NULL); 7664 return (NULL); 7665 } 7666 xmlSchemaPValAttrNodeQName(pctxt, schema, 7667 NULL, attr, &refNs, &ref); 7668 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7669 return(NULL); 7670 7671 /* 7672 * Check for illegal attributes. 7673 */ 7674 attr = node->properties; 7675 while (attr != NULL) { 7676 if (attr->ns == NULL) { 7677 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7678 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7679 { 7680 xmlSchemaPIllegalAttrErr(pctxt, 7681 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7682 } 7683 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7684 xmlSchemaPIllegalAttrErr(pctxt, 7685 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7686 } 7687 attr = attr->next; 7688 } 7689 /* Attribute ID */ 7690 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7691 7692 /* 7693 * And now for the children... 7694 */ 7695 child = node->children; 7696 if (IS_SCHEMA(child, "annotation")) { 7697 /* 7698 * TODO: We do not have a place to store the annotation, do we? 7699 */ 7700 xmlSchemaParseAnnotation(pctxt, child, 0); 7701 child = child->next; 7702 } 7703 if (child != NULL) { 7704 xmlSchemaPContentErr(pctxt, 7705 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7706 NULL, node, child, NULL, 7707 "(annotation?)"); 7708 } 7709 7710 /* 7711 * Handle attribute group redefinitions. 7712 */ 7713 if (pctxt->isRedefine && pctxt->redef && 7714 (pctxt->redef->item->type == 7715 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7716 (ref == pctxt->redef->refName) && 7717 (refNs == pctxt->redef->refTargetNs)) 7718 { 7719 /* 7720 * SPEC src-redefine: 7721 * (7.1) "If it has an <attributeGroup> among its contents 7722 * the `actual value` of whose ref [attribute] is the same 7723 * as the `actual value` of its own name attribute plus 7724 * target namespace, then it must have exactly one such group." 7725 */ 7726 if (pctxt->redefCounter != 0) { 7727 xmlChar *str = NULL; 7728 7729 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7730 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7731 "The redefining attribute group definition " 7732 "'%s' must not contain more than one " 7733 "reference to the redefined definition", 7734 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7735 FREE_AND_NULL(str); 7736 return(NULL); 7737 } 7738 pctxt->redefCounter++; 7739 /* 7740 * URGENT TODO: How to ensure that the reference will not be 7741 * handled by the normal component resolution mechanism? 7742 */ 7743 ret = xmlSchemaNewQNameRef(pctxt, 7744 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7745 if (ret == NULL) 7746 return(NULL); 7747 ret->node = node; 7748 pctxt->redef->reference = WXS_BASIC_CAST ret; 7749 } else { 7750 /* 7751 * Create a QName-reference helper component. We will substitute this 7752 * component for the attribute uses of the referenced attribute group 7753 * definition. 7754 */ 7755 ret = xmlSchemaNewQNameRef(pctxt, 7756 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7757 if (ret == NULL) 7758 return(NULL); 7759 ret->node = node; 7760 /* Add to pending items, to be able to resolve the reference. */ 7761 WXS_ADD_PENDING(pctxt, ret); 7762 } 7763 return (ret); 7764} 7765 7766/** 7767 * xmlSchemaParseAttributeGroupDefinition: 7768 * @pctxt: a schema validation context 7769 * @schema: the schema being built 7770 * @node: a subtree containing XML Schema informations 7771 * 7772 * parse a XML schema Attribute Group declaration 7773 * *WARNING* this interface is highly subject to change 7774 * 7775 * Returns the attribute group definition or NULL in case of error. 7776 */ 7777static xmlSchemaAttributeGroupPtr 7778xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7779 xmlSchemaPtr schema, 7780 xmlNodePtr node) 7781{ 7782 const xmlChar *name; 7783 xmlSchemaAttributeGroupPtr ret; 7784 xmlNodePtr child = NULL; 7785 xmlAttrPtr attr; 7786 int hasRefs = 0; 7787 7788 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7789 return (NULL); 7790 7791 attr = xmlSchemaGetPropNode(node, "name"); 7792 if (attr == NULL) { 7793 xmlSchemaPMissingAttrErr(pctxt, 7794 XML_SCHEMAP_S4S_ATTR_MISSING, 7795 NULL, node, "name", NULL); 7796 return (NULL); 7797 } 7798 /* 7799 * The name is crucial, exit if invalid. 7800 */ 7801 if (xmlSchemaPValAttrNode(pctxt, 7802 NULL, attr, 7803 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7804 return (NULL); 7805 } 7806 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7807 name, pctxt->targetNamespace, node); 7808 if (ret == NULL) 7809 return (NULL); 7810 /* 7811 * Check for illegal attributes. 7812 */ 7813 attr = node->properties; 7814 while (attr != NULL) { 7815 if (attr->ns == NULL) { 7816 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7817 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7818 { 7819 xmlSchemaPIllegalAttrErr(pctxt, 7820 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7821 } 7822 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7823 xmlSchemaPIllegalAttrErr(pctxt, 7824 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7825 } 7826 attr = attr->next; 7827 } 7828 /* Attribute ID */ 7829 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7830 /* 7831 * And now for the children... 7832 */ 7833 child = node->children; 7834 if (IS_SCHEMA(child, "annotation")) { 7835 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7836 child = child->next; 7837 } 7838 /* 7839 * Parse contained attribute decls/refs. 7840 */ 7841 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7842 (xmlSchemaItemListPtr *) &(ret->attrUses), 7843 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7844 return(NULL); 7845 if (hasRefs) 7846 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7847 /* 7848 * Parse the attribute wildcard. 7849 */ 7850 if (IS_SCHEMA(child, "anyAttribute")) { 7851 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7852 schema, child); 7853 child = child->next; 7854 } 7855 if (child != NULL) { 7856 xmlSchemaPContentErr(pctxt, 7857 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7858 NULL, node, child, NULL, 7859 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7860 } 7861 return (ret); 7862} 7863 7864/** 7865 * xmlSchemaPValAttrFormDefault: 7866 * @value: the value 7867 * @flags: the flags to be modified 7868 * @flagQualified: the specific flag for "qualified" 7869 * 7870 * Returns 0 if the value is valid, 1 otherwise. 7871 */ 7872static int 7873xmlSchemaPValAttrFormDefault(const xmlChar *value, 7874 int *flags, 7875 int flagQualified) 7876{ 7877 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7878 if ((*flags & flagQualified) == 0) 7879 *flags |= flagQualified; 7880 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7881 return (1); 7882 7883 return (0); 7884} 7885 7886/** 7887 * xmlSchemaPValAttrBlockFinal: 7888 * @value: the value 7889 * @flags: the flags to be modified 7890 * @flagAll: the specific flag for "#all" 7891 * @flagExtension: the specific flag for "extension" 7892 * @flagRestriction: the specific flag for "restriction" 7893 * @flagSubstitution: the specific flag for "substitution" 7894 * @flagList: the specific flag for "list" 7895 * @flagUnion: the specific flag for "union" 7896 * 7897 * Validates the value of the attribute "final" and "block". The value 7898 * is converted into the specified flag values and returned in @flags. 7899 * 7900 * Returns 0 if the value is valid, 1 otherwise. 7901 */ 7902 7903static int 7904xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7905 int *flags, 7906 int flagAll, 7907 int flagExtension, 7908 int flagRestriction, 7909 int flagSubstitution, 7910 int flagList, 7911 int flagUnion) 7912{ 7913 int ret = 0; 7914 7915 /* 7916 * TODO: This does not check for dublicate entries. 7917 */ 7918 if ((flags == NULL) || (value == NULL)) 7919 return (-1); 7920 if (value[0] == 0) 7921 return (0); 7922 if (xmlStrEqual(value, BAD_CAST "#all")) { 7923 if (flagAll != -1) 7924 *flags |= flagAll; 7925 else { 7926 if (flagExtension != -1) 7927 *flags |= flagExtension; 7928 if (flagRestriction != -1) 7929 *flags |= flagRestriction; 7930 if (flagSubstitution != -1) 7931 *flags |= flagSubstitution; 7932 if (flagList != -1) 7933 *flags |= flagList; 7934 if (flagUnion != -1) 7935 *flags |= flagUnion; 7936 } 7937 } else { 7938 const xmlChar *end, *cur = value; 7939 xmlChar *item; 7940 7941 do { 7942 while (IS_BLANK_CH(*cur)) 7943 cur++; 7944 end = cur; 7945 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7946 end++; 7947 if (end == cur) 7948 break; 7949 item = xmlStrndup(cur, end - cur); 7950 if (xmlStrEqual(item, BAD_CAST "extension")) { 7951 if (flagExtension != -1) { 7952 if ((*flags & flagExtension) == 0) 7953 *flags |= flagExtension; 7954 } else 7955 ret = 1; 7956 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7957 if (flagRestriction != -1) { 7958 if ((*flags & flagRestriction) == 0) 7959 *flags |= flagRestriction; 7960 } else 7961 ret = 1; 7962 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7963 if (flagSubstitution != -1) { 7964 if ((*flags & flagSubstitution) == 0) 7965 *flags |= flagSubstitution; 7966 } else 7967 ret = 1; 7968 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7969 if (flagList != -1) { 7970 if ((*flags & flagList) == 0) 7971 *flags |= flagList; 7972 } else 7973 ret = 1; 7974 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7975 if (flagUnion != -1) { 7976 if ((*flags & flagUnion) == 0) 7977 *flags |= flagUnion; 7978 } else 7979 ret = 1; 7980 } else 7981 ret = 1; 7982 if (item != NULL) 7983 xmlFree(item); 7984 cur = end; 7985 } while ((ret == 0) && (*cur != 0)); 7986 } 7987 7988 return (ret); 7989} 7990 7991static int 7992xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 7993 xmlSchemaIDCPtr idc, 7994 xmlSchemaIDCSelectPtr selector, 7995 xmlAttrPtr attr, 7996 int isField) 7997{ 7998 xmlNodePtr node; 7999 8000 /* 8001 * c-selector-xpath: 8002 * Schema Component Constraint: Selector Value OK 8003 * 8004 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8005 * in [XPath]. 8006 */ 8007 if (selector == NULL) { 8008 xmlSchemaPErr(ctxt, idc->node, 8009 XML_SCHEMAP_INTERNAL, 8010 "Internal error: xmlSchemaCheckCSelectorXPath, " 8011 "the selector is not specified.\n", NULL, NULL); 8012 return (-1); 8013 } 8014 if (attr == NULL) 8015 node = idc->node; 8016 else 8017 node = (xmlNodePtr) attr; 8018 if (selector->xpath == NULL) { 8019 xmlSchemaPCustomErr(ctxt, 8020 /* TODO: Adjust error code. */ 8021 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8022 NULL, node, 8023 "The XPath expression of the selector is not valid", NULL); 8024 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8025 } else { 8026 const xmlChar **nsArray = NULL; 8027 xmlNsPtr *nsList = NULL; 8028 /* 8029 * Compile the XPath expression. 8030 */ 8031 /* 8032 * TODO: We need the array of in-scope namespaces for compilation. 8033 * TODO: Call xmlPatterncompile with different options for selector/ 8034 * field. 8035 */ 8036 if (attr == NULL) 8037 nsList = NULL; 8038 else 8039 nsList = xmlGetNsList(attr->doc, attr->parent); 8040 /* 8041 * Build an array of prefixes and namespaces. 8042 */ 8043 if (nsList != NULL) { 8044 int i, count = 0; 8045 8046 for (i = 0; nsList[i] != NULL; i++) 8047 count++; 8048 8049 nsArray = (const xmlChar **) xmlMalloc( 8050 (count * 2 + 1) * sizeof(const xmlChar *)); 8051 if (nsArray == NULL) { 8052 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8053 NULL); 8054 xmlFree(nsList); 8055 return (-1); 8056 } 8057 for (i = 0; i < count; i++) { 8058 nsArray[2 * i] = nsList[i]->href; 8059 nsArray[2 * i + 1] = nsList[i]->prefix; 8060 } 8061 nsArray[count * 2] = NULL; 8062 xmlFree(nsList); 8063 } 8064 /* 8065 * TODO: Differentiate between "selector" and "field". 8066 */ 8067 if (isField) 8068 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8069 NULL, XML_PATTERN_XSFIELD, nsArray); 8070 else 8071 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8072 NULL, XML_PATTERN_XSSEL, nsArray); 8073 if (nsArray != NULL) 8074 xmlFree((xmlChar **) nsArray); 8075 8076 if (selector->xpathComp == NULL) { 8077 xmlSchemaPCustomErr(ctxt, 8078 /* TODO: Adjust error code? */ 8079 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8080 NULL, node, 8081 "The XPath expression '%s' could not be " 8082 "compiled", selector->xpath); 8083 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8084 } 8085 } 8086 return (0); 8087} 8088 8089#define ADD_ANNOTATION(annot) \ 8090 xmlSchemaAnnotPtr cur = item->annot; \ 8091 if (item->annot == NULL) { \ 8092 item->annot = annot; \ 8093 return (annot); \ 8094 } \ 8095 cur = item->annot; \ 8096 if (cur->next != NULL) { \ 8097 cur = cur->next; \ 8098 } \ 8099 cur->next = annot; 8100 8101/** 8102 * xmlSchemaAssignAnnotation: 8103 * @item: the schema component 8104 * @annot: the annotation 8105 * 8106 * Adds the annotation to the given schema component. 8107 * 8108 * Returns the given annotaion. 8109 */ 8110static xmlSchemaAnnotPtr 8111xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8112 xmlSchemaAnnotPtr annot) 8113{ 8114 if ((annItem == NULL) || (annot == NULL)) 8115 return (NULL); 8116 switch (annItem->type) { 8117 case XML_SCHEMA_TYPE_ELEMENT: { 8118 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8119 ADD_ANNOTATION(annot) 8120 } 8121 break; 8122 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8123 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8124 ADD_ANNOTATION(annot) 8125 } 8126 break; 8127 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8128 case XML_SCHEMA_TYPE_ANY: { 8129 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8130 ADD_ANNOTATION(annot) 8131 } 8132 break; 8133 case XML_SCHEMA_TYPE_PARTICLE: 8134 case XML_SCHEMA_TYPE_IDC_KEY: 8135 case XML_SCHEMA_TYPE_IDC_KEYREF: 8136 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8137 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8138 ADD_ANNOTATION(annot) 8139 } 8140 break; 8141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8142 xmlSchemaAttributeGroupPtr item = 8143 (xmlSchemaAttributeGroupPtr) annItem; 8144 ADD_ANNOTATION(annot) 8145 } 8146 break; 8147 case XML_SCHEMA_TYPE_NOTATION: { 8148 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8149 ADD_ANNOTATION(annot) 8150 } 8151 break; 8152 case XML_SCHEMA_FACET_MININCLUSIVE: 8153 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8154 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8155 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8156 case XML_SCHEMA_FACET_TOTALDIGITS: 8157 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8158 case XML_SCHEMA_FACET_PATTERN: 8159 case XML_SCHEMA_FACET_ENUMERATION: 8160 case XML_SCHEMA_FACET_WHITESPACE: 8161 case XML_SCHEMA_FACET_LENGTH: 8162 case XML_SCHEMA_FACET_MAXLENGTH: 8163 case XML_SCHEMA_FACET_MINLENGTH: { 8164 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8165 ADD_ANNOTATION(annot) 8166 } 8167 break; 8168 case XML_SCHEMA_TYPE_SIMPLE: 8169 case XML_SCHEMA_TYPE_COMPLEX: { 8170 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8171 ADD_ANNOTATION(annot) 8172 } 8173 break; 8174 case XML_SCHEMA_TYPE_GROUP: { 8175 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8176 ADD_ANNOTATION(annot) 8177 } 8178 break; 8179 case XML_SCHEMA_TYPE_SEQUENCE: 8180 case XML_SCHEMA_TYPE_CHOICE: 8181 case XML_SCHEMA_TYPE_ALL: { 8182 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8183 ADD_ANNOTATION(annot) 8184 } 8185 break; 8186 default: 8187 xmlSchemaPCustomErr(NULL, 8188 XML_SCHEMAP_INTERNAL, 8189 NULL, NULL, 8190 "Internal error: xmlSchemaAddAnnotation, " 8191 "The item is not a annotated schema component", NULL); 8192 break; 8193 } 8194 return (annot); 8195} 8196 8197/** 8198 * xmlSchemaParseIDCSelectorAndField: 8199 * @ctxt: a schema validation context 8200 * @schema: the schema being built 8201 * @node: a subtree containing XML Schema informations 8202 * 8203 * Parses a XML Schema identity-contraint definition's 8204 * <selector> and <field> elements. 8205 * 8206 * Returns the parsed identity-constraint definition. 8207 */ 8208static xmlSchemaIDCSelectPtr 8209xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8210 xmlSchemaIDCPtr idc, 8211 xmlNodePtr node, 8212 int isField) 8213{ 8214 xmlSchemaIDCSelectPtr item; 8215 xmlNodePtr child = NULL; 8216 xmlAttrPtr attr; 8217 8218 /* 8219 * Check for illegal attributes. 8220 */ 8221 attr = node->properties; 8222 while (attr != NULL) { 8223 if (attr->ns == NULL) { 8224 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8225 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8226 xmlSchemaPIllegalAttrErr(ctxt, 8227 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8228 } 8229 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8230 xmlSchemaPIllegalAttrErr(ctxt, 8231 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8232 } 8233 attr = attr->next; 8234 } 8235 /* 8236 * Create the item. 8237 */ 8238 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8239 if (item == NULL) { 8240 xmlSchemaPErrMemory(ctxt, 8241 "allocating a 'selector' of an identity-constraint definition", 8242 NULL); 8243 return (NULL); 8244 } 8245 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8246 /* 8247 * Attribute "xpath" (mandatory). 8248 */ 8249 attr = xmlSchemaGetPropNode(node, "xpath"); 8250 if (attr == NULL) { 8251 xmlSchemaPMissingAttrErr(ctxt, 8252 XML_SCHEMAP_S4S_ATTR_MISSING, 8253 NULL, node, 8254 "name", NULL); 8255 } else { 8256 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8257 /* 8258 * URGENT TODO: "field"s have an other syntax than "selector"s. 8259 */ 8260 8261 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8262 isField) == -1) { 8263 xmlSchemaPErr(ctxt, 8264 (xmlNodePtr) attr, 8265 XML_SCHEMAP_INTERNAL, 8266 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8267 "validating the XPath expression of a IDC selector.\n", 8268 NULL, NULL); 8269 } 8270 8271 } 8272 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8273 /* 8274 * And now for the children... 8275 */ 8276 child = node->children; 8277 if (IS_SCHEMA(child, "annotation")) { 8278 /* 8279 * Add the annotation to the parent IDC. 8280 */ 8281 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8282 xmlSchemaParseAnnotation(ctxt, child, 1)); 8283 child = child->next; 8284 } 8285 if (child != NULL) { 8286 xmlSchemaPContentErr(ctxt, 8287 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8288 NULL, node, child, 8289 NULL, "(annotation?)"); 8290 } 8291 8292 return (item); 8293} 8294 8295/** 8296 * xmlSchemaParseIDC: 8297 * @ctxt: a schema validation context 8298 * @schema: the schema being built 8299 * @node: a subtree containing XML Schema informations 8300 * 8301 * Parses a XML Schema identity-contraint definition. 8302 * 8303 * Returns the parsed identity-constraint definition. 8304 */ 8305static xmlSchemaIDCPtr 8306xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8307 xmlSchemaPtr schema, 8308 xmlNodePtr node, 8309 xmlSchemaTypeType idcCategory, 8310 const xmlChar *targetNamespace) 8311{ 8312 xmlSchemaIDCPtr item = NULL; 8313 xmlNodePtr child = NULL; 8314 xmlAttrPtr attr; 8315 const xmlChar *name = NULL; 8316 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8317 8318 /* 8319 * Check for illegal attributes. 8320 */ 8321 attr = node->properties; 8322 while (attr != NULL) { 8323 if (attr->ns == NULL) { 8324 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8325 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8326 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8327 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8328 xmlSchemaPIllegalAttrErr(ctxt, 8329 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8330 } 8331 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8332 xmlSchemaPIllegalAttrErr(ctxt, 8333 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8334 } 8335 attr = attr->next; 8336 } 8337 /* 8338 * Attribute "name" (mandatory). 8339 */ 8340 attr = xmlSchemaGetPropNode(node, "name"); 8341 if (attr == NULL) { 8342 xmlSchemaPMissingAttrErr(ctxt, 8343 XML_SCHEMAP_S4S_ATTR_MISSING, 8344 NULL, node, 8345 "name", NULL); 8346 return (NULL); 8347 } else if (xmlSchemaPValAttrNode(ctxt, 8348 NULL, attr, 8349 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8350 return (NULL); 8351 } 8352 /* Create the component. */ 8353 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8354 idcCategory, node); 8355 if (item == NULL) 8356 return(NULL); 8357 8358 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8359 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8360 /* 8361 * Attribute "refer" (mandatory). 8362 */ 8363 attr = xmlSchemaGetPropNode(node, "refer"); 8364 if (attr == NULL) { 8365 xmlSchemaPMissingAttrErr(ctxt, 8366 XML_SCHEMAP_S4S_ATTR_MISSING, 8367 NULL, node, 8368 "refer", NULL); 8369 } else { 8370 /* 8371 * Create a reference item. 8372 */ 8373 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8374 NULL, NULL); 8375 if (item->ref == NULL) 8376 return (NULL); 8377 xmlSchemaPValAttrNodeQName(ctxt, schema, 8378 NULL, attr, 8379 &(item->ref->targetNamespace), 8380 &(item->ref->name)); 8381 xmlSchemaCheckReference(ctxt, schema, node, attr, 8382 item->ref->targetNamespace); 8383 } 8384 } 8385 /* 8386 * And now for the children... 8387 */ 8388 child = node->children; 8389 if (IS_SCHEMA(child, "annotation")) { 8390 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8391 child = child->next; 8392 } 8393 if (child == NULL) { 8394 xmlSchemaPContentErr(ctxt, 8395 XML_SCHEMAP_S4S_ELEM_MISSING, 8396 NULL, node, child, 8397 "A child element is missing", 8398 "(annotation?, (selector, field+))"); 8399 } 8400 /* 8401 * Child element <selector>. 8402 */ 8403 if (IS_SCHEMA(child, "selector")) { 8404 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8405 item, child, 0); 8406 child = child->next; 8407 /* 8408 * Child elements <field>. 8409 */ 8410 if (IS_SCHEMA(child, "field")) { 8411 do { 8412 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8413 item, child, 1); 8414 if (field != NULL) { 8415 field->index = item->nbFields; 8416 item->nbFields++; 8417 if (lastField != NULL) 8418 lastField->next = field; 8419 else 8420 item->fields = field; 8421 lastField = field; 8422 } 8423 child = child->next; 8424 } while (IS_SCHEMA(child, "field")); 8425 } else { 8426 xmlSchemaPContentErr(ctxt, 8427 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8428 NULL, node, child, 8429 NULL, "(annotation?, (selector, field+))"); 8430 } 8431 } 8432 if (child != NULL) { 8433 xmlSchemaPContentErr(ctxt, 8434 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8435 NULL, node, child, 8436 NULL, "(annotation?, (selector, field+))"); 8437 } 8438 8439 return (item); 8440} 8441 8442/** 8443 * xmlSchemaParseElement: 8444 * @ctxt: a schema validation context 8445 * @schema: the schema being built 8446 * @node: a subtree containing XML Schema informations 8447 * @topLevel: indicates if this is global declaration 8448 * 8449 * Parses a XML schema element declaration. 8450 * *WARNING* this interface is highly subject to change 8451 * 8452 * Returns the element declaration or a particle; NULL in case 8453 * of an error or if the particle has minOccurs==maxOccurs==0. 8454 */ 8455static xmlSchemaBasicItemPtr 8456xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8457 xmlNodePtr node, int *isElemRef, int topLevel) 8458{ 8459 xmlSchemaElementPtr decl = NULL; 8460 xmlSchemaParticlePtr particle = NULL; 8461 xmlSchemaAnnotPtr annot = NULL; 8462 xmlNodePtr child = NULL; 8463 xmlAttrPtr attr, nameAttr; 8464 int min, max, isRef = 0; 8465 xmlChar *des = NULL; 8466 8467 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8468 /* TODO: Complete implementation of 3.3.6 */ 8469 8470 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8471 return (NULL); 8472 8473 if (isElemRef != NULL) 8474 *isElemRef = 0; 8475 /* 8476 * If we get a "ref" attribute on a local <element> we will assume it's 8477 * a reference - even if there's a "name" attribute; this seems to be more 8478 * robust. 8479 */ 8480 nameAttr = xmlSchemaGetPropNode(node, "name"); 8481 attr = xmlSchemaGetPropNode(node, "ref"); 8482 if ((topLevel) || (attr == NULL)) { 8483 if (nameAttr == NULL) { 8484 xmlSchemaPMissingAttrErr(ctxt, 8485 XML_SCHEMAP_S4S_ATTR_MISSING, 8486 NULL, node, "name", NULL); 8487 return (NULL); 8488 } 8489 } else 8490 isRef = 1; 8491 8492 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8493 child = node->children; 8494 if (IS_SCHEMA(child, "annotation")) { 8495 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8496 child = child->next; 8497 } 8498 /* 8499 * Skip particle part if a global declaration. 8500 */ 8501 if (topLevel) 8502 goto declaration_part; 8503 /* 8504 * The particle part ================================================== 8505 */ 8506 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8507 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8508 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8509 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8510 if (particle == NULL) 8511 goto return_null; 8512 8513 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8514 8515 if (isRef) { 8516 const xmlChar *refNs = NULL, *ref = NULL; 8517 xmlSchemaQNameRefPtr refer = NULL; 8518 /* 8519 * The reference part ============================================= 8520 */ 8521 if (isElemRef != NULL) 8522 *isElemRef = 1; 8523 8524 xmlSchemaPValAttrNodeQName(ctxt, schema, 8525 NULL, attr, &refNs, &ref); 8526 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8527 /* 8528 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8529 */ 8530 if (nameAttr != NULL) { 8531 xmlSchemaPMutualExclAttrErr(ctxt, 8532 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8533 } 8534 /* 8535 * Check for illegal attributes. 8536 */ 8537 attr = node->properties; 8538 while (attr != NULL) { 8539 if (attr->ns == NULL) { 8540 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8541 xmlStrEqual(attr->name, BAD_CAST "name") || 8542 xmlStrEqual(attr->name, BAD_CAST "id") || 8543 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8544 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8545 { 8546 attr = attr->next; 8547 continue; 8548 } else { 8549 /* SPEC (3.3.3 : 2.2) */ 8550 xmlSchemaPCustomAttrErr(ctxt, 8551 XML_SCHEMAP_SRC_ELEMENT_2_2, 8552 NULL, NULL, attr, 8553 "Only the attributes 'minOccurs', 'maxOccurs' and " 8554 "'id' are allowed in addition to 'ref'"); 8555 break; 8556 } 8557 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8558 xmlSchemaPIllegalAttrErr(ctxt, 8559 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8560 } 8561 attr = attr->next; 8562 } 8563 /* 8564 * No children except <annotation> expected. 8565 */ 8566 if (child != NULL) { 8567 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8568 NULL, node, child, NULL, "(annotation?)"); 8569 } 8570 if ((min == 0) && (max == 0)) 8571 goto return_null; 8572 /* 8573 * Create the reference item and attach it to the particle. 8574 */ 8575 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8576 ref, refNs); 8577 if (refer == NULL) 8578 goto return_null; 8579 particle->children = (xmlSchemaTreeItemPtr) refer; 8580 particle->annot = annot; 8581 /* 8582 * Add the particle to pending components, since the reference 8583 * need to be resolved. 8584 */ 8585 WXS_ADD_PENDING(ctxt, particle); 8586 return ((xmlSchemaBasicItemPtr) particle); 8587 } 8588 /* 8589 * The declaration part =============================================== 8590 */ 8591declaration_part: 8592 { 8593 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8594 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8595 8596 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8597 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8598 goto return_null; 8599 /* 8600 * Evaluate the target namespace. 8601 */ 8602 if (topLevel) { 8603 ns = ctxt->targetNamespace; 8604 } else { 8605 attr = xmlSchemaGetPropNode(node, "form"); 8606 if (attr != NULL) { 8607 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8608 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8609 ns = ctxt->targetNamespace; 8610 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8611 xmlSchemaPSimpleTypeErr(ctxt, 8612 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8613 NULL, (xmlNodePtr) attr, 8614 NULL, "(qualified | unqualified)", 8615 attrValue, NULL, NULL, NULL); 8616 } 8617 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8618 ns = ctxt->targetNamespace; 8619 } 8620 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8621 if (decl == NULL) { 8622 goto return_null; 8623 } 8624 /* 8625 * Check for illegal attributes. 8626 */ 8627 attr = node->properties; 8628 while (attr != NULL) { 8629 if (attr->ns == NULL) { 8630 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8631 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8632 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8633 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8634 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8635 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8636 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8637 { 8638 if (topLevel == 0) { 8639 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8640 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8641 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8642 { 8643 xmlSchemaPIllegalAttrErr(ctxt, 8644 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8645 } 8646 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8647 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8648 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8649 8650 xmlSchemaPIllegalAttrErr(ctxt, 8651 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8652 } 8653 } 8654 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8655 8656 xmlSchemaPIllegalAttrErr(ctxt, 8657 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8658 } 8659 attr = attr->next; 8660 } 8661 /* 8662 * Extract/validate attributes. 8663 */ 8664 if (topLevel) { 8665 /* 8666 * Process top attributes of global element declarations here. 8667 */ 8668 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8669 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8670 xmlSchemaPValAttrQName(ctxt, schema, 8671 NULL, node, "substitutionGroup", 8672 &(decl->substGroupNs), &(decl->substGroup)); 8673 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8674 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8675 /* 8676 * Attribute "final". 8677 */ 8678 attr = xmlSchemaGetPropNode(node, "final"); 8679 if (attr == NULL) { 8680 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8681 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8682 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8683 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8684 } else { 8685 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8686 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8687 -1, 8688 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8689 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8690 xmlSchemaPSimpleTypeErr(ctxt, 8691 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8692 NULL, (xmlNodePtr) attr, 8693 NULL, "(#all | List of (extension | restriction))", 8694 attrValue, NULL, NULL, NULL); 8695 } 8696 } 8697 } 8698 /* 8699 * Attribute "block". 8700 */ 8701 attr = xmlSchemaGetPropNode(node, "block"); 8702 if (attr == NULL) { 8703 /* 8704 * Apply default "block" values. 8705 */ 8706 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8707 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8708 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8709 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8710 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8711 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8712 } else { 8713 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8714 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8715 -1, 8716 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8717 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8718 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8719 xmlSchemaPSimpleTypeErr(ctxt, 8720 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8721 NULL, (xmlNodePtr) attr, 8722 NULL, "(#all | List of (extension | " 8723 "restriction | substitution))", attrValue, 8724 NULL, NULL, NULL); 8725 } 8726 } 8727 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8728 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8729 8730 attr = xmlSchemaGetPropNode(node, "type"); 8731 if (attr != NULL) { 8732 xmlSchemaPValAttrNodeQName(ctxt, schema, 8733 NULL, attr, 8734 &(decl->namedTypeNs), &(decl->namedType)); 8735 xmlSchemaCheckReference(ctxt, schema, node, 8736 attr, decl->namedTypeNs); 8737 } 8738 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8739 attr = xmlSchemaGetPropNode(node, "fixed"); 8740 if (attr != NULL) { 8741 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8742 if (decl->value != NULL) { 8743 /* 8744 * 3.3.3 : 1 8745 * default and fixed must not both be present. 8746 */ 8747 xmlSchemaPMutualExclAttrErr(ctxt, 8748 XML_SCHEMAP_SRC_ELEMENT_1, 8749 NULL, attr, "default", "fixed"); 8750 } else { 8751 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8752 decl->value = fixed; 8753 } 8754 } 8755 /* 8756 * And now for the children... 8757 */ 8758 if (IS_SCHEMA(child, "complexType")) { 8759 /* 8760 * 3.3.3 : 3 8761 * "type" and either <simpleType> or <complexType> are mutually 8762 * exclusive 8763 */ 8764 if (decl->namedType != NULL) { 8765 xmlSchemaPContentErr(ctxt, 8766 XML_SCHEMAP_SRC_ELEMENT_3, 8767 NULL, node, child, 8768 "The attribute 'type' and the <complexType> child are " 8769 "mutually exclusive", NULL); 8770 } else 8771 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8772 child = child->next; 8773 } else if (IS_SCHEMA(child, "simpleType")) { 8774 /* 8775 * 3.3.3 : 3 8776 * "type" and either <simpleType> or <complexType> are 8777 * mutually exclusive 8778 */ 8779 if (decl->namedType != NULL) { 8780 xmlSchemaPContentErr(ctxt, 8781 XML_SCHEMAP_SRC_ELEMENT_3, 8782 NULL, node, child, 8783 "The attribute 'type' and the <simpleType> child are " 8784 "mutually exclusive", NULL); 8785 } else 8786 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8787 child = child->next; 8788 } 8789 while ((IS_SCHEMA(child, "unique")) || 8790 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8791 if (IS_SCHEMA(child, "unique")) { 8792 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8793 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8794 } else if (IS_SCHEMA(child, "key")) { 8795 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8796 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8797 } else if (IS_SCHEMA(child, "keyref")) { 8798 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8799 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8800 } 8801 if (lastIDC != NULL) 8802 lastIDC->next = curIDC; 8803 else 8804 decl->idcs = (void *) curIDC; 8805 lastIDC = curIDC; 8806 child = child->next; 8807 } 8808 if (child != NULL) { 8809 xmlSchemaPContentErr(ctxt, 8810 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8811 NULL, node, child, 8812 NULL, "(annotation?, ((simpleType | complexType)?, " 8813 "(unique | key | keyref)*))"); 8814 } 8815 decl->annot = annot; 8816 } 8817 /* 8818 * NOTE: Element Declaration Representation OK 4. will be checked at a 8819 * different layer. 8820 */ 8821 FREE_AND_NULL(des) 8822 if (topLevel) 8823 return ((xmlSchemaBasicItemPtr) decl); 8824 else { 8825 particle->children = (xmlSchemaTreeItemPtr) decl; 8826 return ((xmlSchemaBasicItemPtr) particle); 8827 } 8828 8829return_null: 8830 FREE_AND_NULL(des); 8831 if (annot != NULL) { 8832 if (particle != NULL) 8833 particle->annot = NULL; 8834 if (decl != NULL) 8835 decl->annot = NULL; 8836 xmlSchemaFreeAnnot(annot); 8837 } 8838 return (NULL); 8839} 8840 8841/** 8842 * xmlSchemaParseUnion: 8843 * @ctxt: a schema validation context 8844 * @schema: the schema being built 8845 * @node: a subtree containing XML Schema informations 8846 * 8847 * parse a XML schema Union definition 8848 * *WARNING* this interface is highly subject to change 8849 * 8850 * Returns -1 in case of internal error, 0 in case of success and a positive 8851 * error code otherwise. 8852 */ 8853static int 8854xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8855 xmlNodePtr node) 8856{ 8857 xmlSchemaTypePtr type; 8858 xmlNodePtr child = NULL; 8859 xmlAttrPtr attr; 8860 const xmlChar *cur = NULL; 8861 8862 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8863 return (-1); 8864 /* Not a component, don't create it. */ 8865 type = ctxt->ctxtType; 8866 /* 8867 * Mark the simple type as being of variety "union". 8868 */ 8869 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8870 /* 8871 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8872 * then the `simple ur-type definition`." 8873 */ 8874 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8875 /* 8876 * Check for illegal attributes. 8877 */ 8878 attr = node->properties; 8879 while (attr != NULL) { 8880 if (attr->ns == NULL) { 8881 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8882 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8883 xmlSchemaPIllegalAttrErr(ctxt, 8884 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8885 } 8886 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8887 xmlSchemaPIllegalAttrErr(ctxt, 8888 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8889 } 8890 attr = attr->next; 8891 } 8892 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8893 /* 8894 * Attribute "memberTypes". This is a list of QNames. 8895 * TODO: Check the value to contain anything. 8896 */ 8897 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8898 if (attr != NULL) { 8899 const xmlChar *end; 8900 xmlChar *tmp; 8901 const xmlChar *localName, *nsName; 8902 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8903 xmlSchemaQNameRefPtr ref; 8904 8905 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8906 type->base = cur; 8907 do { 8908 while (IS_BLANK_CH(*cur)) 8909 cur++; 8910 end = cur; 8911 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8912 end++; 8913 if (end == cur) 8914 break; 8915 tmp = xmlStrndup(cur, end - cur); 8916 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8917 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8918 /* 8919 * Create the member type link. 8920 */ 8921 link = (xmlSchemaTypeLinkPtr) 8922 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8923 if (link == NULL) { 8924 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8925 "allocating a type link", NULL); 8926 return (-1); 8927 } 8928 link->type = NULL; 8929 link->next = NULL; 8930 if (lastLink == NULL) 8931 type->memberTypes = link; 8932 else 8933 lastLink->next = link; 8934 lastLink = link; 8935 /* 8936 * Create a reference item. 8937 */ 8938 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8939 localName, nsName); 8940 if (ref == NULL) { 8941 FREE_AND_NULL(tmp) 8942 return (-1); 8943 } 8944 /* 8945 * Assign the reference to the link, it will be resolved 8946 * later during fixup of the union simple type. 8947 */ 8948 link->type = (xmlSchemaTypePtr) ref; 8949 } 8950 FREE_AND_NULL(tmp) 8951 cur = end; 8952 } while (*cur != 0); 8953 8954 } 8955 /* 8956 * And now for the children... 8957 */ 8958 child = node->children; 8959 if (IS_SCHEMA(child, "annotation")) { 8960 /* 8961 * Add the annotation to the simple type ancestor. 8962 */ 8963 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8964 xmlSchemaParseAnnotation(ctxt, child, 1)); 8965 child = child->next; 8966 } 8967 if (IS_SCHEMA(child, "simpleType")) { 8968 xmlSchemaTypePtr subtype, last = NULL; 8969 8970 /* 8971 * Anchor the member types in the "subtypes" field of the 8972 * simple type. 8973 */ 8974 while (IS_SCHEMA(child, "simpleType")) { 8975 subtype = (xmlSchemaTypePtr) 8976 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8977 if (subtype != NULL) { 8978 if (last == NULL) { 8979 type->subtypes = subtype; 8980 last = subtype; 8981 } else { 8982 last->next = subtype; 8983 last = subtype; 8984 } 8985 last->next = NULL; 8986 } 8987 child = child->next; 8988 } 8989 } 8990 if (child != NULL) { 8991 xmlSchemaPContentErr(ctxt, 8992 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8993 NULL, node, child, NULL, "(annotation?, simpleType*)"); 8994 } 8995 if ((attr == NULL) && (type->subtypes == NULL)) { 8996 /* 8997 * src-union-memberTypes-or-simpleTypes 8998 * Either the memberTypes [attribute] of the <union> element must 8999 * be non-empty or there must be at least one simpleType [child]. 9000 */ 9001 xmlSchemaPCustomErr(ctxt, 9002 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9003 NULL, node, 9004 "Either the attribute 'memberTypes' or " 9005 "at least one <simpleType> child must be present", NULL); 9006 } 9007 return (0); 9008} 9009 9010/** 9011 * xmlSchemaParseList: 9012 * @ctxt: a schema validation context 9013 * @schema: the schema being built 9014 * @node: a subtree containing XML Schema informations 9015 * 9016 * parse a XML schema List definition 9017 * *WARNING* this interface is highly subject to change 9018 * 9019 * Returns -1 in case of error, 0 if the declaration is improper and 9020 * 1 in case of success. 9021 */ 9022static xmlSchemaTypePtr 9023xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9024 xmlNodePtr node) 9025{ 9026 xmlSchemaTypePtr type; 9027 xmlNodePtr child = NULL; 9028 xmlAttrPtr attr; 9029 9030 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9031 return (NULL); 9032 /* Not a component, don't create it. */ 9033 type = ctxt->ctxtType; 9034 /* 9035 * Mark the type as being of variety "list". 9036 */ 9037 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9038 /* 9039 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9040 * then the `simple ur-type definition`." 9041 */ 9042 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9043 /* 9044 * Check for illegal attributes. 9045 */ 9046 attr = node->properties; 9047 while (attr != NULL) { 9048 if (attr->ns == NULL) { 9049 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9050 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9051 xmlSchemaPIllegalAttrErr(ctxt, 9052 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9053 } 9054 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9055 xmlSchemaPIllegalAttrErr(ctxt, 9056 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9057 } 9058 attr = attr->next; 9059 } 9060 9061 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9062 9063 /* 9064 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9065 * fields for holding the reference to the itemType. 9066 * 9067 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9068 * the "ref" fields. 9069 */ 9070 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9071 node, "itemType", &(type->baseNs), &(type->base)); 9072 /* 9073 * And now for the children... 9074 */ 9075 child = node->children; 9076 if (IS_SCHEMA(child, "annotation")) { 9077 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9078 xmlSchemaParseAnnotation(ctxt, child, 1)); 9079 child = child->next; 9080 } 9081 if (IS_SCHEMA(child, "simpleType")) { 9082 /* 9083 * src-list-itemType-or-simpleType 9084 * Either the itemType [attribute] or the <simpleType> [child] of 9085 * the <list> element must be present, but not both. 9086 */ 9087 if (type->base != NULL) { 9088 xmlSchemaPCustomErr(ctxt, 9089 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9090 NULL, node, 9091 "The attribute 'itemType' and the <simpleType> child " 9092 "are mutually exclusive", NULL); 9093 } else { 9094 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9095 } 9096 child = child->next; 9097 } else if (type->base == NULL) { 9098 xmlSchemaPCustomErr(ctxt, 9099 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9100 NULL, node, 9101 "Either the attribute 'itemType' or the <simpleType> child " 9102 "must be present", NULL); 9103 } 9104 if (child != NULL) { 9105 xmlSchemaPContentErr(ctxt, 9106 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9107 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9108 } 9109 if ((type->base == NULL) && 9110 (type->subtypes == NULL) && 9111 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9112 xmlSchemaPCustomErr(ctxt, 9113 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9114 NULL, node, 9115 "Either the attribute 'itemType' or the <simpleType> child " 9116 "must be present", NULL); 9117 } 9118 return (NULL); 9119} 9120 9121/** 9122 * xmlSchemaParseSimpleType: 9123 * @ctxt: a schema validation context 9124 * @schema: the schema being built 9125 * @node: a subtree containing XML Schema informations 9126 * 9127 * parse a XML schema Simple Type definition 9128 * *WARNING* this interface is highly subject to change 9129 * 9130 * Returns -1 in case of error, 0 if the declaration is improper and 9131 * 1 in case of success. 9132 */ 9133static xmlSchemaTypePtr 9134xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9135 xmlNodePtr node, int topLevel) 9136{ 9137 xmlSchemaTypePtr type, oldCtxtType; 9138 xmlNodePtr child = NULL; 9139 const xmlChar *attrValue = NULL; 9140 xmlAttrPtr attr; 9141 int hasRestriction = 0; 9142 9143 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9144 return (NULL); 9145 9146 if (topLevel) { 9147 attr = xmlSchemaGetPropNode(node, "name"); 9148 if (attr == NULL) { 9149 xmlSchemaPMissingAttrErr(ctxt, 9150 XML_SCHEMAP_S4S_ATTR_MISSING, 9151 NULL, node, 9152 "name", NULL); 9153 return (NULL); 9154 } else { 9155 if (xmlSchemaPValAttrNode(ctxt, 9156 NULL, attr, 9157 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9158 return (NULL); 9159 /* 9160 * Skip built-in types. 9161 */ 9162 if (ctxt->isS4S) { 9163 xmlSchemaTypePtr biType; 9164 9165 if (ctxt->isRedefine) { 9166 /* 9167 * REDEFINE: Disallow redefinition of built-in-types. 9168 * TODO: It seems that the spec does not say anything 9169 * about this case. 9170 */ 9171 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9172 NULL, node, 9173 "Redefinition of built-in simple types is not " 9174 "supported", NULL); 9175 return(NULL); 9176 } 9177 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9178 if (biType != NULL) 9179 return (biType); 9180 } 9181 } 9182 } 9183 /* 9184 * TargetNamespace: 9185 * SPEC "The `actual value` of the targetNamespace [attribute] 9186 * of the <schema> ancestor element information item if present, 9187 * otherwise `absent`. 9188 */ 9189 if (topLevel == 0) { 9190#ifdef ENABLE_NAMED_LOCALS 9191 char buf[40]; 9192#endif 9193 /* 9194 * Parse as local simple type definition. 9195 */ 9196#ifdef ENABLE_NAMED_LOCALS 9197 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9198 type = xmlSchemaAddType(ctxt, schema, 9199 XML_SCHEMA_TYPE_SIMPLE, 9200 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9201 ctxt->targetNamespace, node, 0); 9202#else 9203 type = xmlSchemaAddType(ctxt, schema, 9204 XML_SCHEMA_TYPE_SIMPLE, 9205 NULL, ctxt->targetNamespace, node, 0); 9206#endif 9207 if (type == NULL) 9208 return (NULL); 9209 type->type = XML_SCHEMA_TYPE_SIMPLE; 9210 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9211 /* 9212 * Check for illegal attributes. 9213 */ 9214 attr = node->properties; 9215 while (attr != NULL) { 9216 if (attr->ns == NULL) { 9217 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9218 xmlSchemaPIllegalAttrErr(ctxt, 9219 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9220 } 9221 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9222 xmlSchemaPIllegalAttrErr(ctxt, 9223 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9224 } 9225 attr = attr->next; 9226 } 9227 } else { 9228 /* 9229 * Parse as global simple type definition. 9230 * 9231 * Note that attrValue is the value of the attribute "name" here. 9232 */ 9233 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9234 attrValue, ctxt->targetNamespace, node, 1); 9235 if (type == NULL) 9236 return (NULL); 9237 type->type = XML_SCHEMA_TYPE_SIMPLE; 9238 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9239 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9240 /* 9241 * Check for illegal attributes. 9242 */ 9243 attr = node->properties; 9244 while (attr != NULL) { 9245 if (attr->ns == NULL) { 9246 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9247 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9248 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9249 xmlSchemaPIllegalAttrErr(ctxt, 9250 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9251 } 9252 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9253 xmlSchemaPIllegalAttrErr(ctxt, 9254 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9255 } 9256 attr = attr->next; 9257 } 9258 /* 9259 * Attribute "final". 9260 */ 9261 attr = xmlSchemaGetPropNode(node, "final"); 9262 if (attr == NULL) { 9263 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9264 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9265 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9266 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9267 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9268 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9269 } else { 9270 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9271 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9272 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9273 XML_SCHEMAS_TYPE_FINAL_LIST, 9274 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9275 9276 xmlSchemaPSimpleTypeErr(ctxt, 9277 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9278 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9279 NULL, "(#all | List of (list | union | restriction)", 9280 attrValue, NULL, NULL, NULL); 9281 } 9282 } 9283 } 9284 type->targetNamespace = ctxt->targetNamespace; 9285 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9286 /* 9287 * And now for the children... 9288 */ 9289 oldCtxtType = ctxt->ctxtType; 9290 9291 ctxt->ctxtType = type; 9292 9293 child = node->children; 9294 if (IS_SCHEMA(child, "annotation")) { 9295 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9296 child = child->next; 9297 } 9298 if (child == NULL) { 9299 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9300 NULL, node, child, NULL, 9301 "(annotation?, (restriction | list | union))"); 9302 } else if (IS_SCHEMA(child, "restriction")) { 9303 xmlSchemaParseRestriction(ctxt, schema, child, 9304 XML_SCHEMA_TYPE_SIMPLE); 9305 hasRestriction = 1; 9306 child = child->next; 9307 } else if (IS_SCHEMA(child, "list")) { 9308 xmlSchemaParseList(ctxt, schema, child); 9309 child = child->next; 9310 } else if (IS_SCHEMA(child, "union")) { 9311 xmlSchemaParseUnion(ctxt, schema, child); 9312 child = child->next; 9313 } 9314 if (child != NULL) { 9315 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9316 NULL, node, child, NULL, 9317 "(annotation?, (restriction | list | union))"); 9318 } 9319 /* 9320 * REDEFINE: SPEC src-redefine (5) 9321 * "Within the [children], each <simpleType> must have a 9322 * <restriction> among its [children] ... the `actual value` of whose 9323 * base [attribute] must be the same as the `actual value` of its own 9324 * name attribute plus target namespace;" 9325 */ 9326 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9327 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9328 NULL, node, "This is a redefinition, thus the " 9329 "<simpleType> must have a <restriction> child", NULL); 9330 } 9331 9332 ctxt->ctxtType = oldCtxtType; 9333 return (type); 9334} 9335 9336/** 9337 * xmlSchemaParseModelGroupDefRef: 9338 * @ctxt: the parser context 9339 * @schema: the schema being built 9340 * @node: the node 9341 * 9342 * Parses a reference to a model group definition. 9343 * 9344 * We will return a particle component with a qname-component or 9345 * NULL in case of an error. 9346 */ 9347static xmlSchemaTreeItemPtr 9348xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9349 xmlSchemaPtr schema, 9350 xmlNodePtr node) 9351{ 9352 xmlSchemaParticlePtr item; 9353 xmlNodePtr child = NULL; 9354 xmlAttrPtr attr; 9355 const xmlChar *ref = NULL, *refNs = NULL; 9356 int min, max; 9357 9358 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9359 return (NULL); 9360 9361 attr = xmlSchemaGetPropNode(node, "ref"); 9362 if (attr == NULL) { 9363 xmlSchemaPMissingAttrErr(ctxt, 9364 XML_SCHEMAP_S4S_ATTR_MISSING, 9365 NULL, node, "ref", NULL); 9366 return (NULL); 9367 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9368 attr, &refNs, &ref) != 0) { 9369 return (NULL); 9370 } 9371 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9372 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9373 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9374 "(xs:nonNegativeInteger | unbounded)"); 9375 /* 9376 * Check for illegal attributes. 9377 */ 9378 attr = node->properties; 9379 while (attr != NULL) { 9380 if (attr->ns == NULL) { 9381 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9382 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9383 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9384 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9385 xmlSchemaPIllegalAttrErr(ctxt, 9386 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9387 } 9388 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9389 xmlSchemaPIllegalAttrErr(ctxt, 9390 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9391 } 9392 attr = attr->next; 9393 } 9394 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9395 item = xmlSchemaAddParticle(ctxt, node, min, max); 9396 if (item == NULL) 9397 return (NULL); 9398 /* 9399 * Create a qname-reference and set as the term; it will be substituted 9400 * for the model group after the reference has been resolved. 9401 */ 9402 item->children = (xmlSchemaTreeItemPtr) 9403 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9404 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9405 /* 9406 * And now for the children... 9407 */ 9408 child = node->children; 9409 /* TODO: Is annotation even allowed for a model group reference? */ 9410 if (IS_SCHEMA(child, "annotation")) { 9411 /* 9412 * TODO: What to do exactly with the annotation? 9413 */ 9414 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9415 child = child->next; 9416 } 9417 if (child != NULL) { 9418 xmlSchemaPContentErr(ctxt, 9419 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9420 NULL, node, child, NULL, 9421 "(annotation?)"); 9422 } 9423 /* 9424 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9425 */ 9426 if ((min == 0) && (max == 0)) 9427 return (NULL); 9428 9429 return ((xmlSchemaTreeItemPtr) item); 9430} 9431 9432/** 9433 * xmlSchemaParseModelGroupDefinition: 9434 * @ctxt: a schema validation context 9435 * @schema: the schema being built 9436 * @node: a subtree containing XML Schema informations 9437 * 9438 * Parses a XML schema model group definition. 9439 * 9440 * Note that the contraint src-redefine (6.2) can't be applied until 9441 * references have been resolved. So we will do this at the 9442 * component fixup level. 9443 * 9444 * *WARNING* this interface is highly subject to change 9445 * 9446 * Returns -1 in case of error, 0 if the declaration is improper and 9447 * 1 in case of success. 9448 */ 9449static xmlSchemaModelGroupDefPtr 9450xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9451 xmlSchemaPtr schema, 9452 xmlNodePtr node) 9453{ 9454 xmlSchemaModelGroupDefPtr item; 9455 xmlNodePtr child = NULL; 9456 xmlAttrPtr attr; 9457 const xmlChar *name; 9458 9459 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9460 return (NULL); 9461 9462 attr = xmlSchemaGetPropNode(node, "name"); 9463 if (attr == NULL) { 9464 xmlSchemaPMissingAttrErr(ctxt, 9465 XML_SCHEMAP_S4S_ATTR_MISSING, 9466 NULL, node, 9467 "name", NULL); 9468 return (NULL); 9469 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9470 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9471 return (NULL); 9472 } 9473 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9474 ctxt->targetNamespace, node); 9475 if (item == NULL) 9476 return (NULL); 9477 /* 9478 * Check for illegal attributes. 9479 */ 9480 attr = node->properties; 9481 while (attr != NULL) { 9482 if (attr->ns == NULL) { 9483 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9484 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9485 xmlSchemaPIllegalAttrErr(ctxt, 9486 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9487 } 9488 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9489 xmlSchemaPIllegalAttrErr(ctxt, 9490 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9491 } 9492 attr = attr->next; 9493 } 9494 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9495 /* 9496 * And now for the children... 9497 */ 9498 child = node->children; 9499 if (IS_SCHEMA(child, "annotation")) { 9500 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9501 child = child->next; 9502 } 9503 if (IS_SCHEMA(child, "all")) { 9504 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9505 XML_SCHEMA_TYPE_ALL, 0); 9506 child = child->next; 9507 } else if (IS_SCHEMA(child, "choice")) { 9508 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9509 XML_SCHEMA_TYPE_CHOICE, 0); 9510 child = child->next; 9511 } else if (IS_SCHEMA(child, "sequence")) { 9512 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9513 XML_SCHEMA_TYPE_SEQUENCE, 0); 9514 child = child->next; 9515 } 9516 9517 9518 9519 if (child != NULL) { 9520 xmlSchemaPContentErr(ctxt, 9521 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9522 NULL, node, child, NULL, 9523 "(annotation?, (all | choice | sequence)?)"); 9524 } 9525 return (item); 9526} 9527 9528/** 9529 * xmlSchemaCleanupDoc: 9530 * @ctxt: a schema validation context 9531 * @node: the root of the document. 9532 * 9533 * removes unwanted nodes in a schemas document tree 9534 */ 9535static void 9536xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9537{ 9538 xmlNodePtr delete, cur; 9539 9540 if ((ctxt == NULL) || (root == NULL)) return; 9541 9542 /* 9543 * Remove all the blank text nodes 9544 */ 9545 delete = NULL; 9546 cur = root; 9547 while (cur != NULL) { 9548 if (delete != NULL) { 9549 xmlUnlinkNode(delete); 9550 xmlFreeNode(delete); 9551 delete = NULL; 9552 } 9553 if (cur->type == XML_TEXT_NODE) { 9554 if (IS_BLANK_NODE(cur)) { 9555 if (xmlNodeGetSpacePreserve(cur) != 1) { 9556 delete = cur; 9557 } 9558 } 9559 } else if ((cur->type != XML_ELEMENT_NODE) && 9560 (cur->type != XML_CDATA_SECTION_NODE)) { 9561 delete = cur; 9562 goto skip_children; 9563 } 9564 9565 /* 9566 * Skip to next node 9567 */ 9568 if (cur->children != NULL) { 9569 if ((cur->children->type != XML_ENTITY_DECL) && 9570 (cur->children->type != XML_ENTITY_REF_NODE) && 9571 (cur->children->type != XML_ENTITY_NODE)) { 9572 cur = cur->children; 9573 continue; 9574 } 9575 } 9576 skip_children: 9577 if (cur->next != NULL) { 9578 cur = cur->next; 9579 continue; 9580 } 9581 9582 do { 9583 cur = cur->parent; 9584 if (cur == NULL) 9585 break; 9586 if (cur == root) { 9587 cur = NULL; 9588 break; 9589 } 9590 if (cur->next != NULL) { 9591 cur = cur->next; 9592 break; 9593 } 9594 } while (cur != NULL); 9595 } 9596 if (delete != NULL) { 9597 xmlUnlinkNode(delete); 9598 xmlFreeNode(delete); 9599 delete = NULL; 9600 } 9601} 9602 9603 9604static void 9605xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9606{ 9607 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9608 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9609 9610 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9611 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9612 9613 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9614 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9615 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9616 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9617 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9618 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9619 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9620 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9621 9622 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9623 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9624 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9625 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9626 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9627 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9628} 9629 9630static int 9631xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9632 xmlSchemaPtr schema, 9633 xmlNodePtr node) 9634{ 9635 xmlAttrPtr attr; 9636 const xmlChar *val; 9637 int res = 0, oldErrs = ctxt->nberrors; 9638 9639 /* 9640 * Those flags should be moved to the parser context flags, 9641 * since they are not visible at the component level. I.e. 9642 * they are used if processing schema *documents* only. 9643 */ 9644 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9645 HFAILURE; 9646 9647 /* 9648 * Since the version is of type xs:token, we won't bother to 9649 * check it. 9650 */ 9651 /* REMOVED: 9652 attr = xmlSchemaGetPropNode(node, "version"); 9653 if (attr != NULL) { 9654 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9655 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9656 HFAILURE; 9657 } 9658 */ 9659 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9660 if (attr != NULL) { 9661 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9662 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9663 HFAILURE; 9664 if (res != 0) { 9665 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9666 goto exit; 9667 } 9668 } 9669 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9670 if (attr != NULL) { 9671 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9672 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9673 XML_SCHEMAS_QUALIF_ELEM); 9674 HFAILURE; 9675 if (res != 0) { 9676 xmlSchemaPSimpleTypeErr(ctxt, 9677 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9678 NULL, (xmlNodePtr) attr, NULL, 9679 "(qualified | unqualified)", val, NULL, NULL, NULL); 9680 } 9681 } 9682 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9683 if (attr != NULL) { 9684 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9685 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9686 XML_SCHEMAS_QUALIF_ATTR); 9687 HFAILURE; 9688 if (res != 0) { 9689 xmlSchemaPSimpleTypeErr(ctxt, 9690 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9691 NULL, (xmlNodePtr) attr, NULL, 9692 "(qualified | unqualified)", val, NULL, NULL, NULL); 9693 } 9694 } 9695 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9696 if (attr != NULL) { 9697 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9698 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9699 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9700 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9701 -1, 9702 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9703 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9704 HFAILURE; 9705 if (res != 0) { 9706 xmlSchemaPSimpleTypeErr(ctxt, 9707 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9708 NULL, (xmlNodePtr) attr, NULL, 9709 "(#all | List of (extension | restriction | list | union))", 9710 val, NULL, NULL, NULL); 9711 } 9712 } 9713 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9714 if (attr != NULL) { 9715 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9716 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9717 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9718 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9719 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9720 HFAILURE; 9721 if (res != 0) { 9722 xmlSchemaPSimpleTypeErr(ctxt, 9723 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9724 NULL, (xmlNodePtr) attr, NULL, 9725 "(#all | List of (extension | restriction | substitution))", 9726 val, NULL, NULL, NULL); 9727 } 9728 } 9729 9730exit: 9731 if (oldErrs != ctxt->nberrors) 9732 res = ctxt->err; 9733 return(res); 9734exit_failure: 9735 return(-1); 9736} 9737 9738/** 9739 * xmlSchemaParseSchemaTopLevel: 9740 * @ctxt: a schema validation context 9741 * @schema: the schemas 9742 * @nodes: the list of top level nodes 9743 * 9744 * Returns the internal XML Schema structure built from the resource or 9745 * NULL in case of error 9746 */ 9747static int 9748xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9749 xmlSchemaPtr schema, xmlNodePtr nodes) 9750{ 9751 xmlNodePtr child; 9752 xmlSchemaAnnotPtr annot; 9753 int res = 0, oldErrs, tmpOldErrs; 9754 9755 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9756 return(-1); 9757 9758 oldErrs = ctxt->nberrors; 9759 child = nodes; 9760 while ((IS_SCHEMA(child, "include")) || 9761 (IS_SCHEMA(child, "import")) || 9762 (IS_SCHEMA(child, "redefine")) || 9763 (IS_SCHEMA(child, "annotation"))) { 9764 if (IS_SCHEMA(child, "annotation")) { 9765 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9766 if (schema->annot == NULL) 9767 schema->annot = annot; 9768 else 9769 xmlSchemaFreeAnnot(annot); 9770 } else if (IS_SCHEMA(child, "import")) { 9771 tmpOldErrs = ctxt->nberrors; 9772 res = xmlSchemaParseImport(ctxt, schema, child); 9773 HFAILURE; 9774 HSTOP(ctxt); 9775 if (tmpOldErrs != ctxt->nberrors) 9776 goto exit; 9777 } else if (IS_SCHEMA(child, "include")) { 9778 tmpOldErrs = ctxt->nberrors; 9779 res = xmlSchemaParseInclude(ctxt, schema, child); 9780 HFAILURE; 9781 HSTOP(ctxt); 9782 if (tmpOldErrs != ctxt->nberrors) 9783 goto exit; 9784 } else if (IS_SCHEMA(child, "redefine")) { 9785 tmpOldErrs = ctxt->nberrors; 9786 res = xmlSchemaParseRedefine(ctxt, schema, child); 9787 HFAILURE; 9788 HSTOP(ctxt); 9789 if (tmpOldErrs != ctxt->nberrors) 9790 goto exit; 9791 } 9792 child = child->next; 9793 } 9794 /* 9795 * URGENT TODO: Change the functions to return int results. 9796 * We need especially to catch internal errors. 9797 */ 9798 while (child != NULL) { 9799 if (IS_SCHEMA(child, "complexType")) { 9800 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9801 child = child->next; 9802 } else if (IS_SCHEMA(child, "simpleType")) { 9803 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9804 child = child->next; 9805 } else if (IS_SCHEMA(child, "element")) { 9806 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9807 child = child->next; 9808 } else if (IS_SCHEMA(child, "attribute")) { 9809 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9810 child = child->next; 9811 } else if (IS_SCHEMA(child, "attributeGroup")) { 9812 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9813 child = child->next; 9814 } else if (IS_SCHEMA(child, "group")) { 9815 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9816 child = child->next; 9817 } else if (IS_SCHEMA(child, "notation")) { 9818 xmlSchemaParseNotation(ctxt, schema, child); 9819 child = child->next; 9820 } else { 9821 xmlSchemaPContentErr(ctxt, 9822 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9823 NULL, child->parent, child, 9824 NULL, "((include | import | redefine | annotation)*, " 9825 "(((simpleType | complexType | group | attributeGroup) " 9826 "| element | attribute | notation), annotation*)*)"); 9827 child = child->next; 9828 } 9829 while (IS_SCHEMA(child, "annotation")) { 9830 /* 9831 * TODO: We should add all annotations. 9832 */ 9833 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9834 if (schema->annot == NULL) 9835 schema->annot = annot; 9836 else 9837 xmlSchemaFreeAnnot(annot); 9838 child = child->next; 9839 } 9840 } 9841exit: 9842 ctxt->ctxtType = NULL; 9843 if (oldErrs != ctxt->nberrors) 9844 res = ctxt->err; 9845 return(res); 9846exit_failure: 9847 return(-1); 9848} 9849 9850static xmlSchemaSchemaRelationPtr 9851xmlSchemaSchemaRelationCreate(void) 9852{ 9853 xmlSchemaSchemaRelationPtr ret; 9854 9855 ret = (xmlSchemaSchemaRelationPtr) 9856 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9857 if (ret == NULL) { 9858 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9859 return(NULL); 9860 } 9861 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9862 return(ret); 9863} 9864 9865#if 0 9866static void 9867xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9868{ 9869 xmlFree(rel); 9870} 9871#endif 9872 9873static void 9874xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9875{ 9876 xmlSchemaRedefPtr prev; 9877 9878 while (redef != NULL) { 9879 prev = redef; 9880 redef = redef->next; 9881 xmlFree(prev); 9882 } 9883} 9884 9885static void 9886xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9887{ 9888 /* 9889 * After the construction context has been freed, there will be 9890 * no schema graph available any more. Only the schema buckets 9891 * will stay alive, which are put into the "schemasImports" and 9892 * "includes" slots of the xmlSchema. 9893 */ 9894 if (con->buckets != NULL) 9895 xmlSchemaItemListFree(con->buckets); 9896 if (con->pending != NULL) 9897 xmlSchemaItemListFree(con->pending); 9898 if (con->substGroups != NULL) 9899 xmlHashFree(con->substGroups, 9900 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9901 if (con->redefs != NULL) 9902 xmlSchemaRedefListFree(con->redefs); 9903 if (con->dict != NULL) 9904 xmlDictFree(con->dict); 9905 xmlFree(con); 9906} 9907 9908static xmlSchemaConstructionCtxtPtr 9909xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9910{ 9911 xmlSchemaConstructionCtxtPtr ret; 9912 9913 ret = (xmlSchemaConstructionCtxtPtr) 9914 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9915 if (ret == NULL) { 9916 xmlSchemaPErrMemory(NULL, 9917 "allocating schema construction context", NULL); 9918 return (NULL); 9919 } 9920 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9921 9922 ret->buckets = xmlSchemaItemListCreate(); 9923 if (ret->buckets == NULL) { 9924 xmlSchemaPErrMemory(NULL, 9925 "allocating list of schema buckets", NULL); 9926 xmlFree(ret); 9927 return (NULL); 9928 } 9929 ret->pending = xmlSchemaItemListCreate(); 9930 if (ret->pending == NULL) { 9931 xmlSchemaPErrMemory(NULL, 9932 "allocating list of pending global components", NULL); 9933 xmlSchemaConstructionCtxtFree(ret); 9934 return (NULL); 9935 } 9936 ret->dict = dict; 9937 xmlDictReference(dict); 9938 return(ret); 9939} 9940 9941static xmlSchemaParserCtxtPtr 9942xmlSchemaParserCtxtCreate(void) 9943{ 9944 xmlSchemaParserCtxtPtr ret; 9945 9946 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9947 if (ret == NULL) { 9948 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9949 NULL); 9950 return (NULL); 9951 } 9952 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9953 ret->type = XML_SCHEMA_CTXT_PARSER; 9954 ret->attrProhibs = xmlSchemaItemListCreate(); 9955 if (ret->attrProhibs == NULL) { 9956 xmlFree(ret); 9957 return(NULL); 9958 } 9959 return(ret); 9960} 9961 9962/** 9963 * xmlSchemaNewParserCtxtUseDict: 9964 * @URL: the location of the schema 9965 * @dict: the dictionary to be used 9966 * 9967 * Create an XML Schemas parse context for that file/resource expected 9968 * to contain an XML Schemas file. 9969 * 9970 * Returns the parser context or NULL in case of error 9971 */ 9972static xmlSchemaParserCtxtPtr 9973xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9974{ 9975 xmlSchemaParserCtxtPtr ret; 9976 9977 ret = xmlSchemaParserCtxtCreate(); 9978 if (ret == NULL) 9979 return (NULL); 9980 ret->dict = dict; 9981 xmlDictReference(dict); 9982 if (URL != NULL) 9983 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9984 return (ret); 9985} 9986 9987static int 9988xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 9989{ 9990 if (vctxt->pctxt == NULL) { 9991 if (vctxt->schema != NULL) 9992 vctxt->pctxt = 9993 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 9994 else 9995 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 9996 if (vctxt->pctxt == NULL) { 9997 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 9998 "failed to create a temp. parser context"); 9999 return (-1); 10000 } 10001 /* TODO: Pass user data. */ 10002 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10003 vctxt->warning, vctxt->errCtxt); 10004 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10005 vctxt->errCtxt); 10006 } 10007 return (0); 10008} 10009 10010/** 10011 * xmlSchemaGetSchemaBucket: 10012 * @pctxt: the schema parser context 10013 * @schemaLocation: the URI of the schema document 10014 * 10015 * Returns a schema bucket if it was already parsed. 10016 * 10017 * Returns a schema bucket if it was already parsed from 10018 * @schemaLocation, NULL otherwise. 10019 */ 10020static xmlSchemaBucketPtr 10021xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10022 const xmlChar *schemaLocation) 10023{ 10024 xmlSchemaBucketPtr cur; 10025 xmlSchemaItemListPtr list; 10026 10027 list = pctxt->constructor->buckets; 10028 if (list->nbItems == 0) 10029 return(NULL); 10030 else { 10031 int i; 10032 for (i = 0; i < list->nbItems; i++) { 10033 cur = (xmlSchemaBucketPtr) list->items[i]; 10034 /* Pointer comparison! */ 10035 if (cur->schemaLocation == schemaLocation) 10036 return(cur); 10037 } 10038 } 10039 return(NULL); 10040} 10041 10042static xmlSchemaBucketPtr 10043xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10044 const xmlChar *schemaLocation, 10045 const xmlChar *targetNamespace) 10046{ 10047 xmlSchemaBucketPtr cur; 10048 xmlSchemaItemListPtr list; 10049 10050 list = pctxt->constructor->buckets; 10051 if (list->nbItems == 0) 10052 return(NULL); 10053 else { 10054 int i; 10055 for (i = 0; i < list->nbItems; i++) { 10056 cur = (xmlSchemaBucketPtr) list->items[i]; 10057 /* Pointer comparison! */ 10058 if ((cur->origTargetNamespace == NULL) && 10059 (cur->schemaLocation == schemaLocation) && 10060 (cur->targetNamespace == targetNamespace)) 10061 return(cur); 10062 } 10063 } 10064 return(NULL); 10065} 10066 10067 10068#define IS_BAD_SCHEMA_DOC(b) \ 10069 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10070 10071static xmlSchemaBucketPtr 10072xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10073 const xmlChar *targetNamespace, 10074 int imported) 10075{ 10076 xmlSchemaBucketPtr cur; 10077 xmlSchemaItemListPtr list; 10078 10079 list = pctxt->constructor->buckets; 10080 if (list->nbItems == 0) 10081 return(NULL); 10082 else { 10083 int i; 10084 for (i = 0; i < list->nbItems; i++) { 10085 cur = (xmlSchemaBucketPtr) list->items[i]; 10086 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10087 (cur->origTargetNamespace == targetNamespace) && 10088 ((imported && cur->imported) || 10089 ((!imported) && (!cur->imported)))) 10090 return(cur); 10091 } 10092 } 10093 return(NULL); 10094} 10095 10096static int 10097xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10098 xmlSchemaPtr schema, 10099 xmlSchemaBucketPtr bucket) 10100{ 10101 int oldFlags; 10102 xmlDocPtr oldDoc; 10103 xmlNodePtr node; 10104 int ret, oldErrs; 10105 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10106 10107 /* 10108 * Save old values; reset the *main* schema. 10109 * URGENT TODO: This is not good; move the per-document information 10110 * to the parser. Get rid of passing the main schema to the 10111 * parsing functions. 10112 */ 10113 oldFlags = schema->flags; 10114 oldDoc = schema->doc; 10115 if (schema->flags != 0) 10116 xmlSchemaClearSchemaDefaults(schema); 10117 schema->doc = bucket->doc; 10118 pctxt->schema = schema; 10119 /* 10120 * Keep the current target namespace on the parser *not* on the 10121 * main schema. 10122 */ 10123 pctxt->targetNamespace = bucket->targetNamespace; 10124 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10125 10126 if ((bucket->targetNamespace != NULL) && 10127 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10128 /* 10129 * We are parsing the schema for schemas! 10130 */ 10131 pctxt->isS4S = 1; 10132 } 10133 /* Mark it as parsed, even if parsing fails. */ 10134 bucket->parsed++; 10135 /* Compile the schema doc. */ 10136 node = xmlDocGetRootElement(bucket->doc); 10137 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10138 if (ret != 0) 10139 goto exit; 10140 /* An empty schema; just get out. */ 10141 if (node->children == NULL) 10142 goto exit; 10143 oldErrs = pctxt->nberrors; 10144 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10145 if (ret != 0) 10146 goto exit; 10147 /* 10148 * TODO: Not nice, but I'm not 100% sure we will get always an error 10149 * as a result of the obove functions; so better rely on pctxt->err 10150 * as well. 10151 */ 10152 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10153 ret = pctxt->err; 10154 goto exit; 10155 } 10156 10157exit: 10158 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10159 /* Restore schema values. */ 10160 schema->doc = oldDoc; 10161 schema->flags = oldFlags; 10162 return(ret); 10163} 10164 10165static int 10166xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10167 xmlSchemaPtr schema, 10168 xmlSchemaBucketPtr bucket) 10169{ 10170 xmlSchemaParserCtxtPtr newpctxt; 10171 int res = 0; 10172 10173 if (bucket == NULL) 10174 return(0); 10175 if (bucket->parsed) { 10176 PERROR_INT("xmlSchemaParseNewDoc", 10177 "reparsing a schema doc"); 10178 return(-1); 10179 } 10180 if (bucket->doc == NULL) { 10181 PERROR_INT("xmlSchemaParseNewDoc", 10182 "parsing a schema doc, but there's no doc"); 10183 return(-1); 10184 } 10185 if (pctxt->constructor == NULL) { 10186 PERROR_INT("xmlSchemaParseNewDoc", 10187 "no constructor"); 10188 return(-1); 10189 } 10190 /* Create and init the temporary parser context. */ 10191 newpctxt = xmlSchemaNewParserCtxtUseDict( 10192 (const char *) bucket->schemaLocation, pctxt->dict); 10193 if (newpctxt == NULL) 10194 return(-1); 10195 newpctxt->constructor = pctxt->constructor; 10196 /* 10197 * TODO: Can we avoid that the parser knows about the main schema? 10198 * It would be better if he knows about the current schema bucket 10199 * only. 10200 */ 10201 newpctxt->schema = schema; 10202 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10203 pctxt->errCtxt); 10204 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10205 pctxt->errCtxt); 10206 newpctxt->counter = pctxt->counter; 10207 10208 10209 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10210 10211 /* Channel back errors and cleanup the temporary parser context. */ 10212 if (res != 0) 10213 pctxt->err = res; 10214 pctxt->nberrors += newpctxt->nberrors; 10215 pctxt->counter = newpctxt->counter; 10216 newpctxt->constructor = NULL; 10217 /* Free the parser context. */ 10218 xmlSchemaFreeParserCtxt(newpctxt); 10219 return(res); 10220} 10221 10222static void 10223xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10224 xmlSchemaSchemaRelationPtr rel) 10225{ 10226 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10227 10228 if (cur == NULL) { 10229 bucket->relations = rel; 10230 return; 10231 } 10232 while (cur->next != NULL) 10233 cur = cur->next; 10234 cur->next = rel; 10235} 10236 10237 10238static const xmlChar * 10239xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10240 xmlNodePtr ctxtNode) 10241{ 10242 /* 10243 * Build an absolue location URI. 10244 */ 10245 if (location != NULL) { 10246 if (ctxtNode == NULL) 10247 return(location); 10248 else { 10249 xmlChar *base, *URI; 10250 const xmlChar *ret = NULL; 10251 10252 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10253 if (base == NULL) { 10254 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10255 } else { 10256 URI = xmlBuildURI(location, base); 10257 xmlFree(base); 10258 } 10259 if (URI != NULL) { 10260 ret = xmlDictLookup(dict, URI, -1); 10261 xmlFree(URI); 10262 return(ret); 10263 } 10264 } 10265 } 10266 return(NULL); 10267} 10268 10269 10270 10271/** 10272 * xmlSchemaAddSchemaDoc: 10273 * @pctxt: a schema validation context 10274 * @schema: the schema being built 10275 * @node: a subtree containing XML Schema informations 10276 * 10277 * Parse an included (and to-be-redefined) XML schema document. 10278 * 10279 * Returns 0 on success, a positive error code on errors and 10280 * -1 in case of an internal or API error. 10281 */ 10282 10283static int 10284xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10285 int type, /* import or include or redefine */ 10286 const xmlChar *schemaLocation, 10287 xmlDocPtr schemaDoc, 10288 const char *schemaBuffer, 10289 int schemaBufferLen, 10290 xmlNodePtr invokingNode, 10291 const xmlChar *sourceTargetNamespace, 10292 const xmlChar *importNamespace, 10293 xmlSchemaBucketPtr *bucket) 10294{ 10295 const xmlChar *targetNamespace = NULL; 10296 xmlSchemaSchemaRelationPtr relation = NULL; 10297 xmlDocPtr doc = NULL; 10298 int res = 0, err = 0, located = 0, preserveDoc = 0; 10299 xmlSchemaBucketPtr bkt = NULL; 10300 10301 if (bucket != NULL) 10302 *bucket = NULL; 10303 10304 switch (type) { 10305 case XML_SCHEMA_SCHEMA_IMPORT: 10306 case XML_SCHEMA_SCHEMA_MAIN: 10307 err = XML_SCHEMAP_SRC_IMPORT; 10308 break; 10309 case XML_SCHEMA_SCHEMA_INCLUDE: 10310 err = XML_SCHEMAP_SRC_INCLUDE; 10311 break; 10312 case XML_SCHEMA_SCHEMA_REDEFINE: 10313 err = XML_SCHEMAP_SRC_REDEFINE; 10314 break; 10315 } 10316 10317 10318 /* Special handling for the main schema: 10319 * skip the location and relation logic and just parse the doc. 10320 * We need just a bucket to be returned in this case. 10321 */ 10322 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10323 goto doc_load; 10324 10325 /* Note that we expect the location to be an absulute URI. */ 10326 if (schemaLocation != NULL) { 10327 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10328 if ((bkt != NULL) && 10329 (pctxt->constructor->bucket == bkt)) { 10330 /* Report self-imports/inclusions/redefinitions. */ 10331 10332 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10333 invokingNode, NULL, 10334 "The schema must not import/include/redefine itself", 10335 NULL, NULL); 10336 goto exit; 10337 } 10338 } 10339 /* 10340 * Create a relation for the graph of schemas. 10341 */ 10342 relation = xmlSchemaSchemaRelationCreate(); 10343 if (relation == NULL) 10344 return(-1); 10345 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10346 relation); 10347 relation->type = type; 10348 10349 /* 10350 * Save the namespace import information. 10351 */ 10352 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10353 relation->importNamespace = importNamespace; 10354 if (schemaLocation == NULL) { 10355 /* 10356 * No location; this is just an import of the namespace. 10357 * Note that we don't assign a bucket to the relation 10358 * in this case. 10359 */ 10360 goto exit; 10361 } 10362 targetNamespace = importNamespace; 10363 } 10364 10365 /* Did we already fetch the doc? */ 10366 if (bkt != NULL) { 10367 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10368 /* 10369 * We included/redefined and then try to import a schema, 10370 * but the new location provided for import was different. 10371 */ 10372 if (schemaLocation == NULL) 10373 schemaLocation = BAD_CAST "in_memory_buffer"; 10374 if (!xmlStrEqual(schemaLocation, 10375 bkt->schemaLocation)) { 10376 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10377 invokingNode, NULL, 10378 "The schema document '%s' cannot be imported, since " 10379 "it was already included or redefined", 10380 schemaLocation, NULL); 10381 goto exit; 10382 } 10383 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10384 /* 10385 * We imported and then try to include/redefine a schema, 10386 * but the new location provided for the include/redefine 10387 * was different. 10388 */ 10389 if (schemaLocation == NULL) 10390 schemaLocation = BAD_CAST "in_memory_buffer"; 10391 if (!xmlStrEqual(schemaLocation, 10392 bkt->schemaLocation)) { 10393 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10394 invokingNode, NULL, 10395 "The schema document '%s' cannot be included or " 10396 "redefined, since it was already imported", 10397 schemaLocation, NULL); 10398 goto exit; 10399 } 10400 } 10401 } 10402 10403 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10404 /* 10405 * Given that the schemaLocation [attribute] is only a hint, it is open 10406 * to applications to ignore all but the first <import> for a given 10407 * namespace, regardless of the `actual value` of schemaLocation, but 10408 * such a strategy risks missing useful information when new 10409 * schemaLocations are offered. 10410 * 10411 * We will use the first <import> that comes with a location. 10412 * Further <import>s *with* a location, will result in an error. 10413 * TODO: Better would be to just report a warning here, but 10414 * we'll try it this way until someone complains. 10415 * 10416 * Schema Document Location Strategy: 10417 * 3 Based on the namespace name, identify an existing schema document, 10418 * either as a resource which is an XML document or a <schema> element 10419 * information item, in some local schema repository; 10420 * 5 Attempt to resolve the namespace name to locate such a resource. 10421 * 10422 * NOTE: (3) and (5) are not supported. 10423 */ 10424 if (bkt != NULL) { 10425 relation->bucket = bkt; 10426 goto exit; 10427 } 10428 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10429 importNamespace, 1); 10430 10431 if (bkt != NULL) { 10432 relation->bucket = bkt; 10433 if (bkt->schemaLocation == NULL) { 10434 /* First given location of the schema; load the doc. */ 10435 bkt->schemaLocation = schemaLocation; 10436 } else { 10437 if (!xmlStrEqual(schemaLocation, 10438 bkt->schemaLocation)) { 10439 /* 10440 * Additional location given; just skip it. 10441 * URGENT TODO: We should report a warning here. 10442 * res = XML_SCHEMAP_SRC_IMPORT; 10443 */ 10444 if (schemaLocation == NULL) 10445 schemaLocation = BAD_CAST "in_memory_buffer"; 10446 10447 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10448 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10449 invokingNode, NULL, 10450 "Skipping import of schema located at '%s' for the " 10451 "namespace '%s', since this namespace was already " 10452 "imported with the schema located at '%s'", 10453 schemaLocation, importNamespace, bkt->schemaLocation); 10454 } 10455 goto exit; 10456 } 10457 } 10458 /* 10459 * No bucket + first location: load the doc and create a 10460 * bucket. 10461 */ 10462 } else { 10463 /* <include> and <redefine> */ 10464 if (bkt != NULL) { 10465 10466 if ((bkt->origTargetNamespace == NULL) && 10467 (bkt->targetNamespace != sourceTargetNamespace)) { 10468 xmlSchemaBucketPtr chamel; 10469 10470 /* 10471 * Chameleon include/redefine: skip loading only if it was 10472 * aleady build for the targetNamespace of the including 10473 * schema. 10474 */ 10475 /* 10476 * URGENT TODO: If the schema is a chameleon-include then copy 10477 * the components into the including schema and modify the 10478 * targetNamespace of those components, do nothing otherwise. 10479 * NOTE: This is currently worked-around by compiling the 10480 * chameleon for every destinct including targetNamespace; thus 10481 * not performant at the moment. 10482 * TODO: Check when the namespace in wildcards for chameleons 10483 * needs to be converted: before we built wildcard intersections 10484 * or after. 10485 * Answer: after! 10486 */ 10487 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10488 schemaLocation, sourceTargetNamespace); 10489 if (chamel != NULL) { 10490 /* A fitting chameleon was already parsed; NOP. */ 10491 relation->bucket = chamel; 10492 goto exit; 10493 } 10494 /* 10495 * We need to parse the chameleon again for a different 10496 * targetNamespace. 10497 * CHAMELEON TODO: Optimize this by only parsing the 10498 * chameleon once, and then copying the components to 10499 * the new targetNamespace. 10500 */ 10501 bkt = NULL; 10502 } else { 10503 relation->bucket = bkt; 10504 goto exit; 10505 } 10506 } 10507 } 10508 if ((bkt != NULL) && (bkt->doc != NULL)) { 10509 PERROR_INT("xmlSchemaAddSchemaDoc", 10510 "trying to load a schema doc, but a doc is already " 10511 "assigned to the schema bucket"); 10512 goto exit_failure; 10513 } 10514 10515doc_load: 10516 /* 10517 * Load the document. 10518 */ 10519 if (schemaDoc != NULL) { 10520 doc = schemaDoc; 10521 /* Don' free this one, since it was provided by the caller. */ 10522 preserveDoc = 1; 10523 /* TODO: Does the context or the doc hold the location? */ 10524 if (schemaDoc->URL != NULL) 10525 schemaLocation = xmlDictLookup(pctxt->dict, 10526 schemaDoc->URL, -1); 10527 else 10528 schemaLocation = BAD_CAST "in_memory_buffer"; 10529 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10530 xmlParserCtxtPtr parserCtxt; 10531 10532 parserCtxt = xmlNewParserCtxt(); 10533 if (parserCtxt == NULL) { 10534 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10535 "allocating a parser context", NULL); 10536 goto exit_failure; 10537 } 10538 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10539 /* 10540 * TODO: Do we have to burden the schema parser dict with all 10541 * the content of the schema doc? 10542 */ 10543 xmlDictFree(parserCtxt->dict); 10544 parserCtxt->dict = pctxt->dict; 10545 xmlDictReference(parserCtxt->dict); 10546 } 10547 if (schemaLocation != NULL) { 10548 /* Parse from file. */ 10549 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10550 NULL, SCHEMAS_PARSE_OPTIONS); 10551 } else if (schemaBuffer != NULL) { 10552 /* Parse from memory buffer. */ 10553 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10554 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10555 schemaLocation = BAD_CAST "in_memory_buffer"; 10556 if (doc != NULL) 10557 doc->URL = xmlStrdup(schemaLocation); 10558 } 10559 /* 10560 * For <import>: 10561 * 2.1 The referent is (a fragment of) a resource which is an 10562 * XML document (see clause 1.1), which in turn corresponds to 10563 * a <schema> element information item in a well-formed information 10564 * set, which in turn corresponds to a valid schema. 10565 * TODO: (2.1) fragments of XML documents are not supported. 10566 * 10567 * 2.2 The referent is a <schema> element information item in 10568 * a well-formed information set, which in turn corresponds 10569 * to a valid schema. 10570 * TODO: (2.2) is not supported. 10571 */ 10572 if (doc == NULL) { 10573 xmlErrorPtr lerr; 10574 lerr = xmlGetLastError(); 10575 /* 10576 * Check if this a parser error, or if the document could 10577 * just not be located. 10578 * TODO: Try to find specific error codes to react only on 10579 * localisation failures. 10580 */ 10581 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10582 /* 10583 * We assume a parser error here. 10584 */ 10585 located = 1; 10586 /* TODO: Error code ?? */ 10587 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10588 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10589 invokingNode, NULL, 10590 "Failed to parse the XML resource '%s'", 10591 schemaLocation, NULL); 10592 } 10593 } 10594 xmlFreeParserCtxt(parserCtxt); 10595 if ((doc == NULL) && located) 10596 goto exit_error; 10597 } else { 10598 xmlSchemaPErr(pctxt, NULL, 10599 XML_SCHEMAP_NOTHING_TO_PARSE, 10600 "No information for parsing was provided with the " 10601 "given schema parser context.\n", 10602 NULL, NULL); 10603 goto exit_failure; 10604 } 10605 /* 10606 * Preprocess the document. 10607 */ 10608 if (doc != NULL) { 10609 xmlNodePtr docElem = NULL; 10610 10611 located = 1; 10612 docElem = xmlDocGetRootElement(doc); 10613 if (docElem == NULL) { 10614 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10615 invokingNode, NULL, 10616 "The document '%s' has no document element", 10617 schemaLocation, NULL); 10618 goto exit_error; 10619 } 10620 /* 10621 * Remove all the blank text nodes. 10622 */ 10623 xmlSchemaCleanupDoc(pctxt, docElem); 10624 /* 10625 * Check the schema's top level element. 10626 */ 10627 if (!IS_SCHEMA(docElem, "schema")) { 10628 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10629 invokingNode, NULL, 10630 "The XML document '%s' is not a schema document", 10631 schemaLocation, NULL); 10632 goto exit_error; 10633 } 10634 /* 10635 * Note that we don't apply a type check for the 10636 * targetNamespace value here. 10637 */ 10638 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10639 "targetNamespace"); 10640 } 10641 10642/* after_doc_loading: */ 10643 if ((bkt == NULL) && located) { 10644 /* Only create a bucket if the schema was located. */ 10645 bkt = xmlSchemaBucketCreate(pctxt, type, 10646 targetNamespace); 10647 if (bkt == NULL) 10648 goto exit_failure; 10649 } 10650 if (bkt != NULL) { 10651 bkt->schemaLocation = schemaLocation; 10652 bkt->located = located; 10653 if (doc != NULL) { 10654 bkt->doc = doc; 10655 bkt->targetNamespace = targetNamespace; 10656 bkt->origTargetNamespace = targetNamespace; 10657 if (preserveDoc) 10658 bkt->preserveDoc = 1; 10659 } 10660 if (WXS_IS_BUCKET_IMPMAIN(type)) 10661 bkt->imported++; 10662 /* 10663 * Add it to the graph of schemas. 10664 */ 10665 if (relation != NULL) 10666 relation->bucket = bkt; 10667 } 10668 10669exit: 10670 /* 10671 * Return the bucket explicitely; this is needed for the 10672 * main schema. 10673 */ 10674 if (bucket != NULL) 10675 *bucket = bkt; 10676 return (0); 10677 10678exit_error: 10679 if ((doc != NULL) && (! preserveDoc)) { 10680 xmlFreeDoc(doc); 10681 if (bkt != NULL) 10682 bkt->doc = NULL; 10683 } 10684 return(pctxt->err); 10685 10686exit_failure: 10687 if ((doc != NULL) && (! preserveDoc)) { 10688 xmlFreeDoc(doc); 10689 if (bkt != NULL) 10690 bkt->doc = NULL; 10691 } 10692 return (-1); 10693} 10694 10695/** 10696 * xmlSchemaParseImport: 10697 * @ctxt: a schema validation context 10698 * @schema: the schema being built 10699 * @node: a subtree containing XML Schema informations 10700 * 10701 * parse a XML schema Import definition 10702 * *WARNING* this interface is highly subject to change 10703 * 10704 * Returns 0 in case of success, a positive error code if 10705 * not valid and -1 in case of an internal error. 10706 */ 10707static int 10708xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10709 xmlNodePtr node) 10710{ 10711 xmlNodePtr child; 10712 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10713 const xmlChar *thisTargetNamespace; 10714 xmlAttrPtr attr; 10715 int ret = 0; 10716 xmlSchemaBucketPtr bucket = NULL; 10717 10718 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10719 return (-1); 10720 10721 /* 10722 * Check for illegal attributes. 10723 */ 10724 attr = node->properties; 10725 while (attr != NULL) { 10726 if (attr->ns == NULL) { 10727 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10728 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10729 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10730 xmlSchemaPIllegalAttrErr(pctxt, 10731 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10732 } 10733 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10734 xmlSchemaPIllegalAttrErr(pctxt, 10735 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10736 } 10737 attr = attr->next; 10738 } 10739 /* 10740 * Extract and validate attributes. 10741 */ 10742 if (xmlSchemaPValAttr(pctxt, NULL, node, 10743 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10744 &namespaceName) != 0) { 10745 xmlSchemaPSimpleTypeErr(pctxt, 10746 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10747 NULL, node, 10748 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10749 NULL, namespaceName, NULL, NULL, NULL); 10750 return (pctxt->err); 10751 } 10752 10753 if (xmlSchemaPValAttr(pctxt, NULL, node, 10754 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10755 &schemaLocation) != 0) { 10756 xmlSchemaPSimpleTypeErr(pctxt, 10757 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10758 NULL, node, 10759 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10760 NULL, schemaLocation, NULL, NULL, NULL); 10761 return (pctxt->err); 10762 } 10763 /* 10764 * And now for the children... 10765 */ 10766 child = node->children; 10767 if (IS_SCHEMA(child, "annotation")) { 10768 /* 10769 * the annotation here is simply discarded ... 10770 * TODO: really? 10771 */ 10772 child = child->next; 10773 } 10774 if (child != NULL) { 10775 xmlSchemaPContentErr(pctxt, 10776 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10777 NULL, node, child, NULL, 10778 "(annotation?)"); 10779 } 10780 /* 10781 * Apply additional constraints. 10782 * 10783 * Note that it is important to use the original @targetNamespace 10784 * (or none at all), to rule out imports of schemas _with_ a 10785 * @targetNamespace if the importing schema is a chameleon schema 10786 * (with no @targetNamespace). 10787 */ 10788 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10789 if (namespaceName != NULL) { 10790 /* 10791 * 1.1 If the namespace [attribute] is present, then its `actual value` 10792 * must not match the `actual value` of the enclosing <schema>'s 10793 * targetNamespace [attribute]. 10794 */ 10795 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10796 xmlSchemaPCustomErr(pctxt, 10797 XML_SCHEMAP_SRC_IMPORT_1_1, 10798 NULL, node, 10799 "The value of the attribute 'namespace' must not match " 10800 "the target namespace '%s' of the importing schema", 10801 thisTargetNamespace); 10802 return (pctxt->err); 10803 } 10804 } else { 10805 /* 10806 * 1.2 If the namespace [attribute] is not present, then the enclosing 10807 * <schema> must have a targetNamespace [attribute]. 10808 */ 10809 if (thisTargetNamespace == NULL) { 10810 xmlSchemaPCustomErr(pctxt, 10811 XML_SCHEMAP_SRC_IMPORT_1_2, 10812 NULL, node, 10813 "The attribute 'namespace' must be existent if " 10814 "the importing schema has no target namespace", 10815 NULL); 10816 return (pctxt->err); 10817 } 10818 } 10819 /* 10820 * Locate and acquire the schema document. 10821 */ 10822 if (schemaLocation != NULL) 10823 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10824 schemaLocation, node); 10825 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10826 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10827 namespaceName, &bucket); 10828 10829 if (ret != 0) 10830 return(ret); 10831 10832 /* 10833 * For <import>: "It is *not* an error for the application 10834 * schema reference strategy to fail." 10835 * So just don't parse if no schema document was found. 10836 * Note that we will get no bucket if the schema could not be 10837 * located or if there was no schemaLocation. 10838 */ 10839 if ((bucket == NULL) && (schemaLocation != NULL)) { 10840 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10841 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10842 node, NULL, 10843 "Failed to locate a schema at location '%s'. " 10844 "Skipping the import", schemaLocation, NULL, NULL); 10845 } 10846 10847 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10848 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10849 } 10850 10851 return (ret); 10852} 10853 10854static int 10855xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10856 xmlSchemaPtr schema, 10857 xmlNodePtr node, 10858 xmlChar **schemaLocation, 10859 int type) 10860{ 10861 xmlAttrPtr attr; 10862 10863 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10864 (schemaLocation == NULL)) 10865 return (-1); 10866 10867 *schemaLocation = NULL; 10868 /* 10869 * Check for illegal attributes. 10870 * Applies for both <include> and <redefine>. 10871 */ 10872 attr = node->properties; 10873 while (attr != NULL) { 10874 if (attr->ns == NULL) { 10875 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10876 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10877 xmlSchemaPIllegalAttrErr(pctxt, 10878 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10879 } 10880 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10881 xmlSchemaPIllegalAttrErr(pctxt, 10882 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10883 } 10884 attr = attr->next; 10885 } 10886 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10887 /* 10888 * Preliminary step, extract the URI-Reference and make an URI 10889 * from the base. 10890 */ 10891 /* 10892 * Attribute "schemaLocation" is mandatory. 10893 */ 10894 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10895 if (attr != NULL) { 10896 xmlChar *base = NULL; 10897 xmlChar *uri = NULL; 10898 10899 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10900 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10901 (const xmlChar **) schemaLocation) != 0) 10902 goto exit_error; 10903 base = xmlNodeGetBase(node->doc, node); 10904 if (base == NULL) { 10905 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10906 } else { 10907 uri = xmlBuildURI(*schemaLocation, base); 10908 xmlFree(base); 10909 } 10910 if (uri == NULL) { 10911 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10912 "could not build an URI from the schemaLocation") 10913 goto exit_failure; 10914 } 10915 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10916 xmlFree(uri); 10917 } else { 10918 xmlSchemaPMissingAttrErr(pctxt, 10919 XML_SCHEMAP_S4S_ATTR_MISSING, 10920 NULL, node, "schemaLocation", NULL); 10921 goto exit_error; 10922 } 10923 /* 10924 * Report self-inclusion and self-redefinition. 10925 */ 10926 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10927 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10928 xmlSchemaPCustomErr(pctxt, 10929 XML_SCHEMAP_SRC_REDEFINE, 10930 NULL, node, 10931 "The schema document '%s' cannot redefine itself.", 10932 *schemaLocation); 10933 } else { 10934 xmlSchemaPCustomErr(pctxt, 10935 XML_SCHEMAP_SRC_INCLUDE, 10936 NULL, node, 10937 "The schema document '%s' cannot include itself.", 10938 *schemaLocation); 10939 } 10940 goto exit_error; 10941 } 10942 10943 return(0); 10944exit_error: 10945 return(pctxt->err); 10946exit_failure: 10947 return(-1); 10948} 10949 10950static int 10951xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10952 xmlSchemaPtr schema, 10953 xmlNodePtr node, 10954 int type) 10955{ 10956 xmlNodePtr child = NULL; 10957 const xmlChar *schemaLocation = NULL; 10958 int res = 0; /* hasRedefinitions = 0 */ 10959 int isChameleon = 0, wasChameleon = 0; 10960 xmlSchemaBucketPtr bucket = NULL; 10961 10962 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10963 return (-1); 10964 10965 /* 10966 * Parse attributes. Note that the returned schemaLocation will 10967 * be already converted to an absolute URI. 10968 */ 10969 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10970 node, (xmlChar **) (&schemaLocation), type); 10971 if (res != 0) 10972 return(res); 10973 /* 10974 * Load and add the schema document. 10975 */ 10976 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10977 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10978 if (res != 0) 10979 return(res); 10980 /* 10981 * If we get no schema bucket back, then this means that the schema 10982 * document could not be located or was broken XML or was not 10983 * a schema document. 10984 */ 10985 if ((bucket == NULL) || (bucket->doc == NULL)) { 10986 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 10987 /* 10988 * WARNING for <include>: 10989 * We will raise an error if the schema cannot be located 10990 * for inclusions, since the that was the feedback from the 10991 * schema people. I.e. the following spec piece will *not* be 10992 * satisfied: 10993 * SPEC src-include: "It is not an error for the `actual value` of the 10994 * schemaLocation [attribute] to fail to resolve it all, in which 10995 * case no corresponding inclusion is performed. 10996 * So do we need a warning report here?" 10997 */ 10998 res = XML_SCHEMAP_SRC_INCLUDE; 10999 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11000 node, NULL, 11001 "Failed to load the document '%s' for inclusion", 11002 schemaLocation, NULL); 11003 } else { 11004 /* 11005 * NOTE: This was changed to raise an error even if no redefinitions 11006 * are specified. 11007 * 11008 * SPEC src-redefine (1) 11009 * "If there are any element information items among the [children] 11010 * other than <annotation> then the `actual value` of the 11011 * schemaLocation [attribute] must successfully resolve." 11012 * TODO: Ask the WG if a the location has always to resolve 11013 * here as well! 11014 */ 11015 res = XML_SCHEMAP_SRC_REDEFINE; 11016 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11017 node, NULL, 11018 "Failed to load the document '%s' for redefinition", 11019 schemaLocation, NULL); 11020 } 11021 } else { 11022 /* 11023 * Check targetNamespace sanity before parsing the new schema. 11024 * TODO: Note that we won't check further content if the 11025 * targetNamespace was bad. 11026 */ 11027 if (bucket->origTargetNamespace != NULL) { 11028 /* 11029 * SPEC src-include (2.1) 11030 * "SII has a targetNamespace [attribute], and its `actual 11031 * value` is identical to the `actual value` of the targetNamespace 11032 * [attribute] of SII' (which must have such an [attribute])." 11033 */ 11034 if (pctxt->targetNamespace == NULL) { 11035 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11036 XML_SCHEMAP_SRC_INCLUDE, 11037 node, NULL, 11038 "The target namespace of the included/redefined schema " 11039 "'%s' has to be absent, since the including/redefining " 11040 "schema has no target namespace", 11041 schemaLocation, NULL); 11042 goto exit_error; 11043 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11044 pctxt->targetNamespace)) { 11045 /* TODO: Change error function. */ 11046 xmlSchemaPCustomErrExt(pctxt, 11047 XML_SCHEMAP_SRC_INCLUDE, 11048 NULL, node, 11049 "The target namespace '%s' of the included/redefined " 11050 "schema '%s' differs from '%s' of the " 11051 "including/redefining schema", 11052 bucket->origTargetNamespace, schemaLocation, 11053 pctxt->targetNamespace); 11054 goto exit_error; 11055 } 11056 } else if (pctxt->targetNamespace != NULL) { 11057 /* 11058 * Chameleons: the original target namespace will 11059 * differ from the resulting namespace. 11060 */ 11061 isChameleon = 1; 11062 if (bucket->parsed && 11063 bucket->origTargetNamespace != NULL) { 11064 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11065 XML_SCHEMAP_SRC_INCLUDE, 11066 node, NULL, 11067 "The target namespace of the included/redefined schema " 11068 "'%s' has to be absent or the same as the " 11069 "including/redefining schema's target namespace", 11070 schemaLocation, NULL); 11071 goto exit_error; 11072 } 11073 bucket->targetNamespace = pctxt->targetNamespace; 11074 } 11075 } 11076 /* 11077 * Parse the schema. 11078 */ 11079 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11080 if (isChameleon) { 11081 /* TODO: Get rid of this flag on the schema itself. */ 11082 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11083 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11084 } else 11085 wasChameleon = 1; 11086 } 11087 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11088 /* Restore chameleon flag. */ 11089 if (isChameleon && (!wasChameleon)) 11090 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11091 } 11092 /* 11093 * And now for the children... 11094 */ 11095 child = node->children; 11096 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11097 /* 11098 * Parse (simpleType | complexType | group | attributeGroup))* 11099 */ 11100 pctxt->redefined = bucket; 11101 /* 11102 * How to proceed if the redefined schema was not located? 11103 */ 11104 pctxt->isRedefine = 1; 11105 while (IS_SCHEMA(child, "annotation") || 11106 IS_SCHEMA(child, "simpleType") || 11107 IS_SCHEMA(child, "complexType") || 11108 IS_SCHEMA(child, "group") || 11109 IS_SCHEMA(child, "attributeGroup")) { 11110 if (IS_SCHEMA(child, "annotation")) { 11111 /* 11112 * TODO: discard or not? 11113 */ 11114 } else if (IS_SCHEMA(child, "simpleType")) { 11115 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11116 } else if (IS_SCHEMA(child, "complexType")) { 11117 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11118 /* hasRedefinitions = 1; */ 11119 } else if (IS_SCHEMA(child, "group")) { 11120 /* hasRedefinitions = 1; */ 11121 xmlSchemaParseModelGroupDefinition(pctxt, 11122 schema, child); 11123 } else if (IS_SCHEMA(child, "attributeGroup")) { 11124 /* hasRedefinitions = 1; */ 11125 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11126 child); 11127 } 11128 child = child->next; 11129 } 11130 pctxt->redefined = NULL; 11131 pctxt->isRedefine = 0; 11132 } else { 11133 if (IS_SCHEMA(child, "annotation")) { 11134 /* 11135 * TODO: discard or not? 11136 */ 11137 child = child->next; 11138 } 11139 } 11140 if (child != NULL) { 11141 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11142 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11143 xmlSchemaPContentErr(pctxt, res, 11144 NULL, node, child, NULL, 11145 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11146 } else { 11147 xmlSchemaPContentErr(pctxt, res, 11148 NULL, node, child, NULL, 11149 "(annotation?)"); 11150 } 11151 } 11152 return(res); 11153 11154exit_error: 11155 return(pctxt->err); 11156} 11157 11158static int 11159xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11160 xmlNodePtr node) 11161{ 11162 int res; 11163#ifndef ENABLE_REDEFINE 11164 TODO 11165 return(0); 11166#endif 11167 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11168 XML_SCHEMA_SCHEMA_REDEFINE); 11169 if (res != 0) 11170 return(res); 11171 return(0); 11172} 11173 11174static int 11175xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11176 xmlNodePtr node) 11177{ 11178 int res; 11179 11180 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11181 XML_SCHEMA_SCHEMA_INCLUDE); 11182 if (res != 0) 11183 return(res); 11184 return(0); 11185} 11186 11187/** 11188 * xmlSchemaParseModelGroup: 11189 * @ctxt: a schema validation context 11190 * @schema: the schema being built 11191 * @node: a subtree containing XML Schema informations 11192 * @type: the "compositor" type 11193 * @particleNeeded: if a a model group with a particle 11194 * 11195 * parse a XML schema Sequence definition. 11196 * Applies parts of: 11197 * Schema Representation Constraint: 11198 * Redefinition Constraints and Semantics (src-redefine) 11199 * (6.1), (6.1.1), (6.1.2) 11200 * 11201 * Schema Component Constraint: 11202 * All Group Limited (cos-all-limited) (2) 11203 * TODO: Actually this should go to component-level checks, 11204 * but is done here due to performance. Move it to an other layer 11205 * is schema construction via an API is implemented. 11206 * 11207 * *WARNING* this interface is highly subject to change 11208 * 11209 * Returns -1 in case of error, 0 if the declaration is improper and 11210 * 1 in case of success. 11211 */ 11212static xmlSchemaTreeItemPtr 11213xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11214 xmlNodePtr node, xmlSchemaTypeType type, 11215 int withParticle) 11216{ 11217 xmlSchemaModelGroupPtr item; 11218 xmlSchemaParticlePtr particle = NULL; 11219 xmlNodePtr child = NULL; 11220 xmlAttrPtr attr; 11221 int min = 1, max = 1, isElemRef, hasRefs = 0; 11222 11223 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11224 return (NULL); 11225 /* 11226 * Create a model group with the given compositor. 11227 */ 11228 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11229 if (item == NULL) 11230 return (NULL); 11231 11232 if (withParticle) { 11233 if (type == XML_SCHEMA_TYPE_ALL) { 11234 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11235 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11236 } else { 11237 /* choice + sequence */ 11238 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11239 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11240 "(xs:nonNegativeInteger | unbounded)"); 11241 } 11242 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11243 /* 11244 * Create a particle 11245 */ 11246 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11247 if (particle == NULL) 11248 return (NULL); 11249 particle->children = (xmlSchemaTreeItemPtr) item; 11250 /* 11251 * Check for illegal attributes. 11252 */ 11253 attr = node->properties; 11254 while (attr != NULL) { 11255 if (attr->ns == NULL) { 11256 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11257 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11258 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11259 xmlSchemaPIllegalAttrErr(ctxt, 11260 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11261 } 11262 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11263 xmlSchemaPIllegalAttrErr(ctxt, 11264 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11265 } 11266 attr = attr->next; 11267 } 11268 } else { 11269 /* 11270 * Check for illegal attributes. 11271 */ 11272 attr = node->properties; 11273 while (attr != NULL) { 11274 if (attr->ns == NULL) { 11275 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11276 xmlSchemaPIllegalAttrErr(ctxt, 11277 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11278 } 11279 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11280 xmlSchemaPIllegalAttrErr(ctxt, 11281 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11282 } 11283 attr = attr->next; 11284 } 11285 } 11286 11287 /* 11288 * Extract and validate attributes. 11289 */ 11290 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11291 /* 11292 * And now for the children... 11293 */ 11294 child = node->children; 11295 if (IS_SCHEMA(child, "annotation")) { 11296 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11297 child = child->next; 11298 } 11299 if (type == XML_SCHEMA_TYPE_ALL) { 11300 xmlSchemaParticlePtr part, last = NULL; 11301 11302 while (IS_SCHEMA(child, "element")) { 11303 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11304 schema, child, &isElemRef, 0); 11305 /* 11306 * SPEC cos-all-limited (2) 11307 * "The {max occurs} of all the particles in the {particles} 11308 * of the ('all') group must be 0 or 1. 11309 */ 11310 if (part != NULL) { 11311 if (isElemRef) 11312 hasRefs++; 11313 if (part->minOccurs > 1) { 11314 xmlSchemaPCustomErr(ctxt, 11315 XML_SCHEMAP_COS_ALL_LIMITED, 11316 NULL, child, 11317 "Invalid value for minOccurs (must be 0 or 1)", 11318 NULL); 11319 /* Reset to 1. */ 11320 part->minOccurs = 1; 11321 } 11322 if (part->maxOccurs > 1) { 11323 xmlSchemaPCustomErr(ctxt, 11324 XML_SCHEMAP_COS_ALL_LIMITED, 11325 NULL, child, 11326 "Invalid value for maxOccurs (must be 0 or 1)", 11327 NULL); 11328 /* Reset to 1. */ 11329 part->maxOccurs = 1; 11330 } 11331 if (last == NULL) 11332 item->children = (xmlSchemaTreeItemPtr) part; 11333 else 11334 last->next = (xmlSchemaTreeItemPtr) part; 11335 last = part; 11336 } 11337 child = child->next; 11338 } 11339 if (child != NULL) { 11340 xmlSchemaPContentErr(ctxt, 11341 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11342 NULL, node, child, NULL, 11343 "(annotation?, (annotation?, element*)"); 11344 } 11345 } else { 11346 /* choice + sequence */ 11347 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11348 11349 while ((IS_SCHEMA(child, "element")) || 11350 (IS_SCHEMA(child, "group")) || 11351 (IS_SCHEMA(child, "any")) || 11352 (IS_SCHEMA(child, "choice")) || 11353 (IS_SCHEMA(child, "sequence"))) { 11354 11355 if (IS_SCHEMA(child, "element")) { 11356 part = (xmlSchemaTreeItemPtr) 11357 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11358 if (part && isElemRef) 11359 hasRefs++; 11360 } else if (IS_SCHEMA(child, "group")) { 11361 part = 11362 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11363 if (part != NULL) 11364 hasRefs++; 11365 /* 11366 * Handle redefinitions. 11367 */ 11368 if (ctxt->isRedefine && ctxt->redef && 11369 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11370 part && part->children) 11371 { 11372 if ((xmlSchemaGetQNameRefName(part->children) == 11373 ctxt->redef->refName) && 11374 (xmlSchemaGetQNameRefTargetNs(part->children) == 11375 ctxt->redef->refTargetNs)) 11376 { 11377 /* 11378 * SPEC src-redefine: 11379 * (6.1) "If it has a <group> among its contents at 11380 * some level the `actual value` of whose ref 11381 * [attribute] is the same as the `actual value` of 11382 * its own name attribute plus target namespace, then 11383 * all of the following must be true:" 11384 * (6.1.1) "It must have exactly one such group." 11385 */ 11386 if (ctxt->redefCounter != 0) { 11387 xmlChar *str = NULL; 11388 11389 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11390 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11391 "The redefining model group definition " 11392 "'%s' must not contain more than one " 11393 "reference to the redefined definition", 11394 xmlSchemaFormatQName(&str, 11395 ctxt->redef->refTargetNs, 11396 ctxt->redef->refName), 11397 NULL); 11398 FREE_AND_NULL(str) 11399 part = NULL; 11400 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11401 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11402 { 11403 xmlChar *str = NULL; 11404 /* 11405 * SPEC src-redefine: 11406 * (6.1.2) "The `actual value` of both that 11407 * group's minOccurs and maxOccurs [attribute] 11408 * must be 1 (or `absent`). 11409 */ 11410 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11411 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11412 "The redefining model group definition " 11413 "'%s' must not contain a reference to the " 11414 "redefined definition with a " 11415 "maxOccurs/minOccurs other than 1", 11416 xmlSchemaFormatQName(&str, 11417 ctxt->redef->refTargetNs, 11418 ctxt->redef->refName), 11419 NULL); 11420 FREE_AND_NULL(str) 11421 part = NULL; 11422 } 11423 ctxt->redef->reference = WXS_BASIC_CAST part; 11424 ctxt->redefCounter++; 11425 } 11426 } 11427 } else if (IS_SCHEMA(child, "any")) { 11428 part = (xmlSchemaTreeItemPtr) 11429 xmlSchemaParseAny(ctxt, schema, child); 11430 } else if (IS_SCHEMA(child, "choice")) { 11431 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11432 XML_SCHEMA_TYPE_CHOICE, 1); 11433 } else if (IS_SCHEMA(child, "sequence")) { 11434 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11435 XML_SCHEMA_TYPE_SEQUENCE, 1); 11436 } 11437 if (part != NULL) { 11438 if (last == NULL) 11439 item->children = part; 11440 else 11441 last->next = part; 11442 last = part; 11443 } 11444 child = child->next; 11445 } 11446 if (child != NULL) { 11447 xmlSchemaPContentErr(ctxt, 11448 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11449 NULL, node, child, NULL, 11450 "(annotation?, (element | group | choice | sequence | any)*)"); 11451 } 11452 } 11453 if ((max == 0) && (min == 0)) 11454 return (NULL); 11455 if (hasRefs) { 11456 /* 11457 * We need to resolve references. 11458 */ 11459 WXS_ADD_PENDING(ctxt, item); 11460 } 11461 if (withParticle) 11462 return ((xmlSchemaTreeItemPtr) particle); 11463 else 11464 return ((xmlSchemaTreeItemPtr) item); 11465} 11466 11467/** 11468 * xmlSchemaParseRestriction: 11469 * @ctxt: a schema validation context 11470 * @schema: the schema being built 11471 * @node: a subtree containing XML Schema informations 11472 * 11473 * parse a XML schema Restriction definition 11474 * *WARNING* this interface is highly subject to change 11475 * 11476 * Returns the type definition or NULL in case of error 11477 */ 11478static xmlSchemaTypePtr 11479xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11480 xmlNodePtr node, xmlSchemaTypeType parentType) 11481{ 11482 xmlSchemaTypePtr type; 11483 xmlNodePtr child = NULL; 11484 xmlAttrPtr attr; 11485 11486 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11487 return (NULL); 11488 /* Not a component, don't create it. */ 11489 type = ctxt->ctxtType; 11490 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11491 11492 /* 11493 * Check for illegal attributes. 11494 */ 11495 attr = node->properties; 11496 while (attr != NULL) { 11497 if (attr->ns == NULL) { 11498 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11499 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11500 xmlSchemaPIllegalAttrErr(ctxt, 11501 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11502 } 11503 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11504 xmlSchemaPIllegalAttrErr(ctxt, 11505 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11506 } 11507 attr = attr->next; 11508 } 11509 /* 11510 * Extract and validate attributes. 11511 */ 11512 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11513 /* 11514 * Attribute 11515 */ 11516 /* 11517 * Extract the base type. The "base" attribute is mandatory if inside 11518 * a complex type or if redefining. 11519 * 11520 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11521 * among its [children]), the simple type definition which is 11522 * the {content type} of the type definition `resolved` to by 11523 * the `actual value` of the base [attribute]" 11524 */ 11525 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11526 &(type->baseNs), &(type->base)) == 0) 11527 { 11528 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11529 xmlSchemaPMissingAttrErr(ctxt, 11530 XML_SCHEMAP_S4S_ATTR_MISSING, 11531 NULL, node, "base", NULL); 11532 } else if ((ctxt->isRedefine) && 11533 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11534 { 11535 if (type->base == NULL) { 11536 xmlSchemaPMissingAttrErr(ctxt, 11537 XML_SCHEMAP_S4S_ATTR_MISSING, 11538 NULL, node, "base", NULL); 11539 } else if ((! xmlStrEqual(type->base, type->name)) || 11540 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11541 { 11542 xmlChar *str1 = NULL, *str2 = NULL; 11543 /* 11544 * REDEFINE: SPEC src-redefine (5) 11545 * "Within the [children], each <simpleType> must have a 11546 * <restriction> among its [children] ... the `actual value` of 11547 * whose base [attribute] must be the same as the `actual value` 11548 * of its own name attribute plus target namespace;" 11549 */ 11550 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11551 NULL, node, "This is a redefinition, but the QName " 11552 "value '%s' of the 'base' attribute does not match the " 11553 "type's designation '%s'", 11554 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11555 xmlSchemaFormatQName(&str2, type->targetNamespace, 11556 type->name), NULL); 11557 FREE_AND_NULL(str1); 11558 FREE_AND_NULL(str2); 11559 /* Avoid confusion and erase the values. */ 11560 type->base = NULL; 11561 type->baseNs = NULL; 11562 } 11563 } 11564 } 11565 /* 11566 * And now for the children... 11567 */ 11568 child = node->children; 11569 if (IS_SCHEMA(child, "annotation")) { 11570 /* 11571 * Add the annotation to the simple type ancestor. 11572 */ 11573 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11574 xmlSchemaParseAnnotation(ctxt, child, 1)); 11575 child = child->next; 11576 } 11577 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11578 /* 11579 * Corresponds to <simpleType><restriction><simpleType>. 11580 */ 11581 if (IS_SCHEMA(child, "simpleType")) { 11582 if (type->base != NULL) { 11583 /* 11584 * src-restriction-base-or-simpleType 11585 * Either the base [attribute] or the simpleType [child] of the 11586 * <restriction> element must be present, but not both. 11587 */ 11588 xmlSchemaPContentErr(ctxt, 11589 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11590 NULL, node, child, 11591 "The attribute 'base' and the <simpleType> child are " 11592 "mutually exclusive", NULL); 11593 } else { 11594 type->baseType = (xmlSchemaTypePtr) 11595 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11596 } 11597 child = child->next; 11598 } else if (type->base == NULL) { 11599 xmlSchemaPContentErr(ctxt, 11600 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11601 NULL, node, child, 11602 "Either the attribute 'base' or a <simpleType> child " 11603 "must be present", NULL); 11604 } 11605 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11606 /* 11607 * Corresponds to <complexType><complexContent><restriction>... 11608 * followed by: 11609 * 11610 * Model groups <all>, <choice> and <sequence>. 11611 */ 11612 if (IS_SCHEMA(child, "all")) { 11613 type->subtypes = (xmlSchemaTypePtr) 11614 xmlSchemaParseModelGroup(ctxt, schema, child, 11615 XML_SCHEMA_TYPE_ALL, 1); 11616 child = child->next; 11617 } else if (IS_SCHEMA(child, "choice")) { 11618 type->subtypes = (xmlSchemaTypePtr) 11619 xmlSchemaParseModelGroup(ctxt, 11620 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11621 child = child->next; 11622 } else if (IS_SCHEMA(child, "sequence")) { 11623 type->subtypes = (xmlSchemaTypePtr) 11624 xmlSchemaParseModelGroup(ctxt, schema, child, 11625 XML_SCHEMA_TYPE_SEQUENCE, 1); 11626 child = child->next; 11627 /* 11628 * Model group reference <group>. 11629 */ 11630 } else if (IS_SCHEMA(child, "group")) { 11631 type->subtypes = (xmlSchemaTypePtr) 11632 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11633 /* 11634 * Note that the reference will be resolved in 11635 * xmlSchemaResolveTypeReferences(); 11636 */ 11637 child = child->next; 11638 } 11639 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11640 /* 11641 * Corresponds to <complexType><simpleContent><restriction>... 11642 * 11643 * "1.1 the simple type definition corresponding to the <simpleType> 11644 * among the [children] of <restriction> if there is one;" 11645 */ 11646 if (IS_SCHEMA(child, "simpleType")) { 11647 /* 11648 * We will store the to-be-restricted simple type in 11649 * type->contentTypeDef *temporarily*. 11650 */ 11651 type->contentTypeDef = (xmlSchemaTypePtr) 11652 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11653 if ( type->contentTypeDef == NULL) 11654 return (NULL); 11655 child = child->next; 11656 } 11657 } 11658 11659 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11660 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11661 xmlSchemaFacetPtr facet, lastfacet = NULL; 11662 /* 11663 * Corresponds to <complexType><simpleContent><restriction>... 11664 * <simpleType><restriction>... 11665 */ 11666 11667 /* 11668 * Add the facets to the simple type ancestor. 11669 */ 11670 /* 11671 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11672 * Simple Type Definition Schema Representation Constraint: 11673 * *Single Facet Value* 11674 */ 11675 while ((IS_SCHEMA(child, "minInclusive")) || 11676 (IS_SCHEMA(child, "minExclusive")) || 11677 (IS_SCHEMA(child, "maxInclusive")) || 11678 (IS_SCHEMA(child, "maxExclusive")) || 11679 (IS_SCHEMA(child, "totalDigits")) || 11680 (IS_SCHEMA(child, "fractionDigits")) || 11681 (IS_SCHEMA(child, "pattern")) || 11682 (IS_SCHEMA(child, "enumeration")) || 11683 (IS_SCHEMA(child, "whiteSpace")) || 11684 (IS_SCHEMA(child, "length")) || 11685 (IS_SCHEMA(child, "maxLength")) || 11686 (IS_SCHEMA(child, "minLength"))) { 11687 facet = xmlSchemaParseFacet(ctxt, schema, child); 11688 if (facet != NULL) { 11689 if (lastfacet == NULL) 11690 type->facets = facet; 11691 else 11692 lastfacet->next = facet; 11693 lastfacet = facet; 11694 lastfacet->next = NULL; 11695 } 11696 child = child->next; 11697 } 11698 /* 11699 * Create links for derivation and validation. 11700 */ 11701 if (type->facets != NULL) { 11702 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11703 11704 facet = type->facets; 11705 do { 11706 facetLink = (xmlSchemaFacetLinkPtr) 11707 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11708 if (facetLink == NULL) { 11709 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11710 xmlFree(facetLink); 11711 return (NULL); 11712 } 11713 facetLink->facet = facet; 11714 facetLink->next = NULL; 11715 if (lastFacetLink == NULL) 11716 type->facetSet = facetLink; 11717 else 11718 lastFacetLink->next = facetLink; 11719 lastFacetLink = facetLink; 11720 facet = facet->next; 11721 } while (facet != NULL); 11722 } 11723 } 11724 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11725 /* 11726 * Attribute uses/declarations. 11727 */ 11728 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11729 (xmlSchemaItemListPtr *) &(type->attrUses), 11730 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11731 return(NULL); 11732 /* 11733 * Attribute wildcard. 11734 */ 11735 if (IS_SCHEMA(child, "anyAttribute")) { 11736 type->attributeWildcard = 11737 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11738 child = child->next; 11739 } 11740 } 11741 if (child != NULL) { 11742 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11743 xmlSchemaPContentErr(ctxt, 11744 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11745 NULL, node, child, NULL, 11746 "annotation?, (group | all | choice | sequence)?, " 11747 "((attribute | attributeGroup)*, anyAttribute?))"); 11748 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11749 xmlSchemaPContentErr(ctxt, 11750 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11751 NULL, node, child, NULL, 11752 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11753 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11754 "length | minLength | maxLength | enumeration | whiteSpace | " 11755 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11756 } else { 11757 /* Simple type */ 11758 xmlSchemaPContentErr(ctxt, 11759 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11760 NULL, node, child, NULL, 11761 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11762 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11763 "length | minLength | maxLength | enumeration | whiteSpace | " 11764 "pattern)*))"); 11765 } 11766 } 11767 return (NULL); 11768} 11769 11770/** 11771 * xmlSchemaParseExtension: 11772 * @ctxt: a schema validation context 11773 * @schema: the schema being built 11774 * @node: a subtree containing XML Schema informations 11775 * 11776 * Parses an <extension>, which is found inside a 11777 * <simpleContent> or <complexContent>. 11778 * *WARNING* this interface is highly subject to change. 11779 * 11780 * TODO: Returns the type definition or NULL in case of error 11781 */ 11782static xmlSchemaTypePtr 11783xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11784 xmlNodePtr node, xmlSchemaTypeType parentType) 11785{ 11786 xmlSchemaTypePtr type; 11787 xmlNodePtr child = NULL; 11788 xmlAttrPtr attr; 11789 11790 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11791 return (NULL); 11792 /* Not a component, don't create it. */ 11793 type = ctxt->ctxtType; 11794 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11795 11796 /* 11797 * Check for illegal attributes. 11798 */ 11799 attr = node->properties; 11800 while (attr != NULL) { 11801 if (attr->ns == NULL) { 11802 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11803 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11804 xmlSchemaPIllegalAttrErr(ctxt, 11805 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11806 } 11807 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11808 xmlSchemaPIllegalAttrErr(ctxt, 11809 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11810 } 11811 attr = attr->next; 11812 } 11813 11814 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11815 11816 /* 11817 * Attribute "base" - mandatory. 11818 */ 11819 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11820 "base", &(type->baseNs), &(type->base)) == 0) && 11821 (type->base == NULL)) { 11822 xmlSchemaPMissingAttrErr(ctxt, 11823 XML_SCHEMAP_S4S_ATTR_MISSING, 11824 NULL, node, "base", NULL); 11825 } 11826 /* 11827 * And now for the children... 11828 */ 11829 child = node->children; 11830 if (IS_SCHEMA(child, "annotation")) { 11831 /* 11832 * Add the annotation to the type ancestor. 11833 */ 11834 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11835 xmlSchemaParseAnnotation(ctxt, child, 1)); 11836 child = child->next; 11837 } 11838 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11839 /* 11840 * Corresponds to <complexType><complexContent><extension>... and: 11841 * 11842 * Model groups <all>, <choice>, <sequence> and <group>. 11843 */ 11844 if (IS_SCHEMA(child, "all")) { 11845 type->subtypes = (xmlSchemaTypePtr) 11846 xmlSchemaParseModelGroup(ctxt, schema, 11847 child, XML_SCHEMA_TYPE_ALL, 1); 11848 child = child->next; 11849 } else if (IS_SCHEMA(child, "choice")) { 11850 type->subtypes = (xmlSchemaTypePtr) 11851 xmlSchemaParseModelGroup(ctxt, schema, 11852 child, XML_SCHEMA_TYPE_CHOICE, 1); 11853 child = child->next; 11854 } else if (IS_SCHEMA(child, "sequence")) { 11855 type->subtypes = (xmlSchemaTypePtr) 11856 xmlSchemaParseModelGroup(ctxt, schema, 11857 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11858 child = child->next; 11859 } else if (IS_SCHEMA(child, "group")) { 11860 type->subtypes = (xmlSchemaTypePtr) 11861 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11862 /* 11863 * Note that the reference will be resolved in 11864 * xmlSchemaResolveTypeReferences(); 11865 */ 11866 child = child->next; 11867 } 11868 } 11869 if (child != NULL) { 11870 /* 11871 * Attribute uses/declarations. 11872 */ 11873 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11874 (xmlSchemaItemListPtr *) &(type->attrUses), 11875 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11876 return(NULL); 11877 /* 11878 * Attribute wildcard. 11879 */ 11880 if (IS_SCHEMA(child, "anyAttribute")) { 11881 ctxt->ctxtType->attributeWildcard = 11882 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11883 child = child->next; 11884 } 11885 } 11886 if (child != NULL) { 11887 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11888 /* Complex content extension. */ 11889 xmlSchemaPContentErr(ctxt, 11890 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11891 NULL, node, child, NULL, 11892 "(annotation?, ((group | all | choice | sequence)?, " 11893 "((attribute | attributeGroup)*, anyAttribute?)))"); 11894 } else { 11895 /* Simple content extension. */ 11896 xmlSchemaPContentErr(ctxt, 11897 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11898 NULL, node, child, NULL, 11899 "(annotation?, ((attribute | attributeGroup)*, " 11900 "anyAttribute?))"); 11901 } 11902 } 11903 return (NULL); 11904} 11905 11906/** 11907 * xmlSchemaParseSimpleContent: 11908 * @ctxt: a schema validation context 11909 * @schema: the schema being built 11910 * @node: a subtree containing XML Schema informations 11911 * 11912 * parse a XML schema SimpleContent definition 11913 * *WARNING* this interface is highly subject to change 11914 * 11915 * Returns the type definition or NULL in case of error 11916 */ 11917static int 11918xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11919 xmlSchemaPtr schema, xmlNodePtr node, 11920 int *hasRestrictionOrExtension) 11921{ 11922 xmlSchemaTypePtr type; 11923 xmlNodePtr child = NULL; 11924 xmlAttrPtr attr; 11925 11926 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11927 (hasRestrictionOrExtension == NULL)) 11928 return (-1); 11929 *hasRestrictionOrExtension = 0; 11930 /* Not a component, don't create it. */ 11931 type = ctxt->ctxtType; 11932 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11933 /* 11934 * Check for illegal attributes. 11935 */ 11936 attr = node->properties; 11937 while (attr != NULL) { 11938 if (attr->ns == NULL) { 11939 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11940 xmlSchemaPIllegalAttrErr(ctxt, 11941 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11942 } 11943 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11944 xmlSchemaPIllegalAttrErr(ctxt, 11945 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11946 } 11947 attr = attr->next; 11948 } 11949 11950 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11951 11952 /* 11953 * And now for the children... 11954 */ 11955 child = node->children; 11956 if (IS_SCHEMA(child, "annotation")) { 11957 /* 11958 * Add the annotation to the complex type ancestor. 11959 */ 11960 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11961 xmlSchemaParseAnnotation(ctxt, child, 1)); 11962 child = child->next; 11963 } 11964 if (child == NULL) { 11965 xmlSchemaPContentErr(ctxt, 11966 XML_SCHEMAP_S4S_ELEM_MISSING, 11967 NULL, node, NULL, NULL, 11968 "(annotation?, (restriction | extension))"); 11969 } 11970 if (child == NULL) { 11971 xmlSchemaPContentErr(ctxt, 11972 XML_SCHEMAP_S4S_ELEM_MISSING, 11973 NULL, node, NULL, NULL, 11974 "(annotation?, (restriction | extension))"); 11975 } 11976 if (IS_SCHEMA(child, "restriction")) { 11977 xmlSchemaParseRestriction(ctxt, schema, child, 11978 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11979 (*hasRestrictionOrExtension) = 1; 11980 child = child->next; 11981 } else if (IS_SCHEMA(child, "extension")) { 11982 xmlSchemaParseExtension(ctxt, schema, child, 11983 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11984 (*hasRestrictionOrExtension) = 1; 11985 child = child->next; 11986 } 11987 if (child != NULL) { 11988 xmlSchemaPContentErr(ctxt, 11989 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11990 NULL, node, child, NULL, 11991 "(annotation?, (restriction | extension))"); 11992 } 11993 return (0); 11994} 11995 11996/** 11997 * xmlSchemaParseComplexContent: 11998 * @ctxt: a schema validation context 11999 * @schema: the schema being built 12000 * @node: a subtree containing XML Schema informations 12001 * 12002 * parse a XML schema ComplexContent definition 12003 * *WARNING* this interface is highly subject to change 12004 * 12005 * Returns the type definition or NULL in case of error 12006 */ 12007static int 12008xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12009 xmlSchemaPtr schema, xmlNodePtr node, 12010 int *hasRestrictionOrExtension) 12011{ 12012 xmlSchemaTypePtr type; 12013 xmlNodePtr child = NULL; 12014 xmlAttrPtr attr; 12015 12016 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12017 (hasRestrictionOrExtension == NULL)) 12018 return (-1); 12019 *hasRestrictionOrExtension = 0; 12020 /* Not a component, don't create it. */ 12021 type = ctxt->ctxtType; 12022 /* 12023 * Check for illegal attributes. 12024 */ 12025 attr = node->properties; 12026 while (attr != NULL) { 12027 if (attr->ns == NULL) { 12028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12029 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12030 { 12031 xmlSchemaPIllegalAttrErr(ctxt, 12032 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12033 } 12034 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12035 xmlSchemaPIllegalAttrErr(ctxt, 12036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12037 } 12038 attr = attr->next; 12039 } 12040 12041 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12042 12043 /* 12044 * Set the 'mixed' on the complex type ancestor. 12045 */ 12046 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12047 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12048 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12049 } 12050 child = node->children; 12051 if (IS_SCHEMA(child, "annotation")) { 12052 /* 12053 * Add the annotation to the complex type ancestor. 12054 */ 12055 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12056 xmlSchemaParseAnnotation(ctxt, child, 1)); 12057 child = child->next; 12058 } 12059 if (child == NULL) { 12060 xmlSchemaPContentErr(ctxt, 12061 XML_SCHEMAP_S4S_ELEM_MISSING, 12062 NULL, node, NULL, 12063 NULL, "(annotation?, (restriction | extension))"); 12064 } 12065 if (child == NULL) { 12066 xmlSchemaPContentErr(ctxt, 12067 XML_SCHEMAP_S4S_ELEM_MISSING, 12068 NULL, node, NULL, 12069 NULL, "(annotation?, (restriction | extension))"); 12070 } 12071 if (IS_SCHEMA(child, "restriction")) { 12072 xmlSchemaParseRestriction(ctxt, schema, child, 12073 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12074 (*hasRestrictionOrExtension) = 1; 12075 child = child->next; 12076 } else if (IS_SCHEMA(child, "extension")) { 12077 xmlSchemaParseExtension(ctxt, schema, child, 12078 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12079 (*hasRestrictionOrExtension) = 1; 12080 child = child->next; 12081 } 12082 if (child != NULL) { 12083 xmlSchemaPContentErr(ctxt, 12084 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12085 NULL, node, child, 12086 NULL, "(annotation?, (restriction | extension))"); 12087 } 12088 return (0); 12089} 12090 12091/** 12092 * xmlSchemaParseComplexType: 12093 * @ctxt: a schema validation context 12094 * @schema: the schema being built 12095 * @node: a subtree containing XML Schema informations 12096 * 12097 * parse a XML schema Complex Type definition 12098 * *WARNING* this interface is highly subject to change 12099 * 12100 * Returns the type definition or NULL in case of error 12101 */ 12102static xmlSchemaTypePtr 12103xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12104 xmlNodePtr node, int topLevel) 12105{ 12106 xmlSchemaTypePtr type, ctxtType; 12107 xmlNodePtr child = NULL; 12108 const xmlChar *name = NULL; 12109 xmlAttrPtr attr; 12110 const xmlChar *attrValue; 12111#ifdef ENABLE_NAMED_LOCALS 12112 char buf[40]; 12113#endif 12114 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12115 12116 12117 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12118 return (NULL); 12119 12120 ctxtType = ctxt->ctxtType; 12121 12122 if (topLevel) { 12123 attr = xmlSchemaGetPropNode(node, "name"); 12124 if (attr == NULL) { 12125 xmlSchemaPMissingAttrErr(ctxt, 12126 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12127 return (NULL); 12128 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12129 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12130 return (NULL); 12131 } 12132 } 12133 12134 if (topLevel == 0) { 12135 /* 12136 * Parse as local complex type definition. 12137 */ 12138#ifdef ENABLE_NAMED_LOCALS 12139 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12140 type = xmlSchemaAddType(ctxt, schema, 12141 XML_SCHEMA_TYPE_COMPLEX, 12142 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12143 ctxt->targetNamespace, node, 0); 12144#else 12145 type = xmlSchemaAddType(ctxt, schema, 12146 XML_SCHEMA_TYPE_COMPLEX, 12147 NULL, ctxt->targetNamespace, node, 0); 12148#endif 12149 if (type == NULL) 12150 return (NULL); 12151 name = type->name; 12152 type->node = node; 12153 type->type = XML_SCHEMA_TYPE_COMPLEX; 12154 /* 12155 * TODO: We need the target namespace. 12156 */ 12157 } else { 12158 /* 12159 * Parse as global complex type definition. 12160 */ 12161 type = xmlSchemaAddType(ctxt, schema, 12162 XML_SCHEMA_TYPE_COMPLEX, 12163 name, ctxt->targetNamespace, node, 1); 12164 if (type == NULL) 12165 return (NULL); 12166 type->node = node; 12167 type->type = XML_SCHEMA_TYPE_COMPLEX; 12168 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12169 } 12170 type->targetNamespace = ctxt->targetNamespace; 12171 /* 12172 * Handle attributes. 12173 */ 12174 attr = node->properties; 12175 while (attr != NULL) { 12176 if (attr->ns == NULL) { 12177 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12178 /* 12179 * Attribute "id". 12180 */ 12181 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12182 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12183 /* 12184 * Attribute "mixed". 12185 */ 12186 if (xmlSchemaPGetBoolNodeValue(ctxt, 12187 NULL, (xmlNodePtr) attr)) 12188 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12189 } else if (topLevel) { 12190 /* 12191 * Attributes of global complex type definitions. 12192 */ 12193 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12194 /* Pass. */ 12195 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12196 /* 12197 * Attribute "abstract". 12198 */ 12199 if (xmlSchemaPGetBoolNodeValue(ctxt, 12200 NULL, (xmlNodePtr) attr)) 12201 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12202 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12203 /* 12204 * Attribute "final". 12205 */ 12206 attrValue = xmlSchemaGetNodeContent(ctxt, 12207 (xmlNodePtr) attr); 12208 if (xmlSchemaPValAttrBlockFinal(attrValue, 12209 &(type->flags), 12210 -1, 12211 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12212 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12213 -1, -1, -1) != 0) 12214 { 12215 xmlSchemaPSimpleTypeErr(ctxt, 12216 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12217 NULL, (xmlNodePtr) attr, NULL, 12218 "(#all | List of (extension | restriction))", 12219 attrValue, NULL, NULL, NULL); 12220 } else 12221 final = 1; 12222 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12223 /* 12224 * Attribute "block". 12225 */ 12226 attrValue = xmlSchemaGetNodeContent(ctxt, 12227 (xmlNodePtr) attr); 12228 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12229 -1, 12230 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12231 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12232 -1, -1, -1) != 0) { 12233 xmlSchemaPSimpleTypeErr(ctxt, 12234 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12235 NULL, (xmlNodePtr) attr, NULL, 12236 "(#all | List of (extension | restriction)) ", 12237 attrValue, NULL, NULL, NULL); 12238 } else 12239 block = 1; 12240 } else { 12241 xmlSchemaPIllegalAttrErr(ctxt, 12242 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12243 } 12244 } else { 12245 xmlSchemaPIllegalAttrErr(ctxt, 12246 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12247 } 12248 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12249 xmlSchemaPIllegalAttrErr(ctxt, 12250 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12251 } 12252 attr = attr->next; 12253 } 12254 if (! block) { 12255 /* 12256 * Apply default "block" values. 12257 */ 12258 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12259 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12260 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12261 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12262 } 12263 if (! final) { 12264 /* 12265 * Apply default "block" values. 12266 */ 12267 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12268 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12269 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12270 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12271 } 12272 /* 12273 * And now for the children... 12274 */ 12275 child = node->children; 12276 if (IS_SCHEMA(child, "annotation")) { 12277 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12278 child = child->next; 12279 } 12280 ctxt->ctxtType = type; 12281 if (IS_SCHEMA(child, "simpleContent")) { 12282 /* 12283 * <complexType><simpleContent>... 12284 * 3.4.3 : 2.2 12285 * Specifying mixed='true' when the <simpleContent> 12286 * alternative is chosen has no effect 12287 */ 12288 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12289 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12290 xmlSchemaParseSimpleContent(ctxt, schema, child, 12291 &hasRestrictionOrExtension); 12292 child = child->next; 12293 } else if (IS_SCHEMA(child, "complexContent")) { 12294 /* 12295 * <complexType><complexContent>... 12296 */ 12297 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12298 xmlSchemaParseComplexContent(ctxt, schema, child, 12299 &hasRestrictionOrExtension); 12300 child = child->next; 12301 } else { 12302 /* 12303 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12304 * 12305 * SPEC 12306 * "...the third alternative (neither <simpleContent> nor 12307 * <complexContent>) is chosen. This case is understood as shorthand 12308 * for complex content restricting the `ur-type definition`, and the 12309 * details of the mappings should be modified as necessary. 12310 */ 12311 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12312 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12313 /* 12314 * Parse model groups. 12315 */ 12316 if (IS_SCHEMA(child, "all")) { 12317 type->subtypes = (xmlSchemaTypePtr) 12318 xmlSchemaParseModelGroup(ctxt, schema, child, 12319 XML_SCHEMA_TYPE_ALL, 1); 12320 child = child->next; 12321 } else if (IS_SCHEMA(child, "choice")) { 12322 type->subtypes = (xmlSchemaTypePtr) 12323 xmlSchemaParseModelGroup(ctxt, schema, child, 12324 XML_SCHEMA_TYPE_CHOICE, 1); 12325 child = child->next; 12326 } else if (IS_SCHEMA(child, "sequence")) { 12327 type->subtypes = (xmlSchemaTypePtr) 12328 xmlSchemaParseModelGroup(ctxt, schema, child, 12329 XML_SCHEMA_TYPE_SEQUENCE, 1); 12330 child = child->next; 12331 } else if (IS_SCHEMA(child, "group")) { 12332 type->subtypes = (xmlSchemaTypePtr) 12333 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12334 /* 12335 * Note that the reference will be resolved in 12336 * xmlSchemaResolveTypeReferences(); 12337 */ 12338 child = child->next; 12339 } 12340 /* 12341 * Parse attribute decls/refs. 12342 */ 12343 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12344 (xmlSchemaItemListPtr *) &(type->attrUses), 12345 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12346 return(NULL); 12347 /* 12348 * Parse attribute wildcard. 12349 */ 12350 if (IS_SCHEMA(child, "anyAttribute")) { 12351 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12352 child = child->next; 12353 } 12354 } 12355 if (child != NULL) { 12356 xmlSchemaPContentErr(ctxt, 12357 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12358 NULL, node, child, 12359 NULL, "(annotation?, (simpleContent | complexContent | " 12360 "((group | all | choice | sequence)?, ((attribute | " 12361 "attributeGroup)*, anyAttribute?))))"); 12362 } 12363 /* 12364 * REDEFINE: SPEC src-redefine (5) 12365 */ 12366 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12367 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12368 NULL, node, "This is a redefinition, thus the " 12369 "<complexType> must have a <restriction> or <extension> " 12370 "grand-child", NULL); 12371 } 12372 ctxt->ctxtType = ctxtType; 12373 return (type); 12374} 12375 12376/************************************************************************ 12377 * * 12378 * Validating using Schemas * 12379 * * 12380 ************************************************************************/ 12381 12382/************************************************************************ 12383 * * 12384 * Reading/Writing Schemas * 12385 * * 12386 ************************************************************************/ 12387 12388#if 0 /* Will be enabled if it is clear what options are needed. */ 12389/** 12390 * xmlSchemaParserCtxtSetOptions: 12391 * @ctxt: a schema parser context 12392 * @options: a combination of xmlSchemaParserOption 12393 * 12394 * Sets the options to be used during the parse. 12395 * 12396 * Returns 0 in case of success, -1 in case of an 12397 * API error. 12398 */ 12399static int 12400xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12401 int options) 12402 12403{ 12404 int i; 12405 12406 if (ctxt == NULL) 12407 return (-1); 12408 /* 12409 * WARNING: Change the start value if adding to the 12410 * xmlSchemaParseOption. 12411 */ 12412 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12413 if (options & 1<<i) { 12414 return (-1); 12415 } 12416 } 12417 ctxt->options = options; 12418 return (0); 12419} 12420 12421/** 12422 * xmlSchemaValidCtxtGetOptions: 12423 * @ctxt: a schema parser context 12424 * 12425 * Returns the option combination of the parser context. 12426 */ 12427static int 12428xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12429 12430{ 12431 if (ctxt == NULL) 12432 return (-1); 12433 else 12434 return (ctxt->options); 12435} 12436#endif 12437 12438/** 12439 * xmlSchemaNewParserCtxt: 12440 * @URL: the location of the schema 12441 * 12442 * Create an XML Schemas parse context for that file/resource expected 12443 * to contain an XML Schemas file. 12444 * 12445 * Returns the parser context or NULL in case of error 12446 */ 12447xmlSchemaParserCtxtPtr 12448xmlSchemaNewParserCtxt(const char *URL) 12449{ 12450 xmlSchemaParserCtxtPtr ret; 12451 12452 if (URL == NULL) 12453 return (NULL); 12454 12455 ret = xmlSchemaParserCtxtCreate(); 12456 if (ret == NULL) 12457 return(NULL); 12458 ret->dict = xmlDictCreate(); 12459 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12460 return (ret); 12461} 12462 12463/** 12464 * xmlSchemaNewMemParserCtxt: 12465 * @buffer: a pointer to a char array containing the schemas 12466 * @size: the size of the array 12467 * 12468 * Create an XML Schemas parse context for that memory buffer expected 12469 * to contain an XML Schemas file. 12470 * 12471 * Returns the parser context or NULL in case of error 12472 */ 12473xmlSchemaParserCtxtPtr 12474xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12475{ 12476 xmlSchemaParserCtxtPtr ret; 12477 12478 if ((buffer == NULL) || (size <= 0)) 12479 return (NULL); 12480 ret = xmlSchemaParserCtxtCreate(); 12481 if (ret == NULL) 12482 return(NULL); 12483 ret->buffer = buffer; 12484 ret->size = size; 12485 ret->dict = xmlDictCreate(); 12486 return (ret); 12487} 12488 12489/** 12490 * xmlSchemaNewDocParserCtxt: 12491 * @doc: a preparsed document tree 12492 * 12493 * Create an XML Schemas parse context for that document. 12494 * NB. The document may be modified during the parsing process. 12495 * 12496 * Returns the parser context or NULL in case of error 12497 */ 12498xmlSchemaParserCtxtPtr 12499xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12500{ 12501 xmlSchemaParserCtxtPtr ret; 12502 12503 if (doc == NULL) 12504 return (NULL); 12505 ret = xmlSchemaParserCtxtCreate(); 12506 if (ret == NULL) 12507 return(NULL); 12508 ret->doc = doc; 12509 ret->dict = xmlDictCreate(); 12510 /* The application has responsibility for the document */ 12511 ret->preserve = 1; 12512 12513 return (ret); 12514} 12515 12516/** 12517 * xmlSchemaFreeParserCtxt: 12518 * @ctxt: the schema parser context 12519 * 12520 * Free the resources associated to the schema parser context 12521 */ 12522void 12523xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12524{ 12525 if (ctxt == NULL) 12526 return; 12527 if (ctxt->doc != NULL && !ctxt->preserve) 12528 xmlFreeDoc(ctxt->doc); 12529 if (ctxt->vctxt != NULL) { 12530 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12531 } 12532 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12533 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12534 ctxt->constructor = NULL; 12535 ctxt->ownsConstructor = 0; 12536 } 12537 if (ctxt->attrProhibs != NULL) 12538 xmlSchemaItemListFree(ctxt->attrProhibs); 12539 xmlDictFree(ctxt->dict); 12540 xmlFree(ctxt); 12541} 12542 12543/************************************************************************ 12544 * * 12545 * Building the content models * 12546 * * 12547 ************************************************************************/ 12548 12549/** 12550 * xmlSchemaBuildContentModelForSubstGroup: 12551 * 12552 * Returns 1 if nillable, 0 otherwise 12553 */ 12554static int 12555xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12556 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12557{ 12558 xmlAutomataStatePtr start, tmp; 12559 xmlSchemaElementPtr elemDecl, member; 12560 xmlSchemaSubstGroupPtr substGroup; 12561 int i; 12562 int ret = 0; 12563 12564 elemDecl = (xmlSchemaElementPtr) particle->children; 12565 /* 12566 * Wrap the substitution group with a CHOICE. 12567 */ 12568 start = pctxt->state; 12569 if (end == NULL) 12570 end = xmlAutomataNewState(pctxt->am); 12571 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12572 if (substGroup == NULL) { 12573 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12574 XML_SCHEMAP_INTERNAL, 12575 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12576 "declaration is marked having a subst. group but none " 12577 "available.\n", elemDecl->name, NULL); 12578 return(0); 12579 } 12580 if (counter >= 0) { 12581 /* 12582 * NOTE that we put the declaration in, even if it's abstract. 12583 * However, an error will be raised during *validation* if an element 12584 * information item shall be validated against an abstract element 12585 * declaration. 12586 */ 12587 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12588 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12589 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12590 /* 12591 * Add subst. group members. 12592 */ 12593 for (i = 0; i < substGroup->members->nbItems; i++) { 12594 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12595 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12596 member->name, member->targetNamespace, member); 12597 } 12598 } else if (particle->maxOccurs == 1) { 12599 /* 12600 * NOTE that we put the declaration in, even if it's abstract, 12601 */ 12602 xmlAutomataNewEpsilon(pctxt->am, 12603 xmlAutomataNewTransition2(pctxt->am, 12604 start, NULL, 12605 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12606 /* 12607 * Add subst. group members. 12608 */ 12609 for (i = 0; i < substGroup->members->nbItems; i++) { 12610 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12611 /* 12612 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12613 * was incorrectly used instead of xmlAutomataNewTransition2() 12614 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12615 * section in xmlSchemaBuildAContentModel() ). 12616 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12617 * intended for the above "counter" section originally. I.e., 12618 * check xs:all with subst-groups. 12619 * 12620 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12621 * member->name, member->targetNamespace, 12622 * 1, 1, member); 12623 */ 12624 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12625 member->name, member->targetNamespace, member); 12626 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12627 } 12628 } else { 12629 xmlAutomataStatePtr hop; 12630 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12631 UNBOUNDED : particle->maxOccurs - 1; 12632 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12633 12634 counter = 12635 xmlAutomataNewCounter(pctxt->am, minOccurs, 12636 maxOccurs); 12637 hop = xmlAutomataNewState(pctxt->am); 12638 12639 xmlAutomataNewEpsilon(pctxt->am, 12640 xmlAutomataNewTransition2(pctxt->am, 12641 start, NULL, 12642 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12643 hop); 12644 /* 12645 * Add subst. group members. 12646 */ 12647 for (i = 0; i < substGroup->members->nbItems; i++) { 12648 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12649 xmlAutomataNewEpsilon(pctxt->am, 12650 xmlAutomataNewTransition2(pctxt->am, 12651 start, NULL, 12652 member->name, member->targetNamespace, member), 12653 hop); 12654 } 12655 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12656 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12657 } 12658 if (particle->minOccurs == 0) { 12659 xmlAutomataNewEpsilon(pctxt->am, start, end); 12660 ret = 1; 12661 } 12662 pctxt->state = end; 12663 return(ret); 12664} 12665 12666/** 12667 * xmlSchemaBuildContentModelForElement: 12668 * 12669 * Returns 1 if nillable, 0 otherwise 12670 */ 12671static int 12672xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12673 xmlSchemaParticlePtr particle) 12674{ 12675 int ret = 0; 12676 12677 if (((xmlSchemaElementPtr) particle->children)->flags & 12678 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12679 /* 12680 * Substitution groups. 12681 */ 12682 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12683 } else { 12684 xmlSchemaElementPtr elemDecl; 12685 xmlAutomataStatePtr start; 12686 12687 elemDecl = (xmlSchemaElementPtr) particle->children; 12688 12689 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12690 return(0); 12691 if (particle->maxOccurs == 1) { 12692 start = ctxt->state; 12693 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12694 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12695 } else if ((particle->maxOccurs >= UNBOUNDED) && 12696 (particle->minOccurs < 2)) { 12697 /* Special case. */ 12698 start = ctxt->state; 12699 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12700 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12701 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12702 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12703 } else { 12704 int counter; 12705 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12706 UNBOUNDED : particle->maxOccurs - 1; 12707 int minOccurs = particle->minOccurs < 1 ? 12708 0 : particle->minOccurs - 1; 12709 12710 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12711 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12712 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12713 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12714 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12715 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12716 NULL, counter); 12717 } 12718 if (particle->minOccurs == 0) { 12719 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12720 ret = 1; 12721 } 12722 } 12723 return(ret); 12724} 12725 12726/** 12727 * xmlSchemaBuildAContentModel: 12728 * @ctxt: the schema parser context 12729 * @particle: the particle component 12730 * @name: the complex type's name whose content is being built 12731 * 12732 * Create the automaton for the {content type} of a complex type. 12733 * 12734 * Returns 1 if the content is nillable, 0 otherwise 12735 */ 12736static int 12737xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12738 xmlSchemaParticlePtr particle) 12739{ 12740 int ret = 0, tmp2; 12741 12742 if (particle == NULL) { 12743 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12744 return(1); 12745 } 12746 if (particle->children == NULL) { 12747 /* 12748 * Just return in this case. A missing "term" of the particle 12749 * might arise due to an invalid "term" component. 12750 */ 12751 return(1); 12752 } 12753 12754 switch (particle->children->type) { 12755 case XML_SCHEMA_TYPE_ANY: { 12756 xmlAutomataStatePtr start, end; 12757 xmlSchemaWildcardPtr wild; 12758 xmlSchemaWildcardNsPtr ns; 12759 12760 wild = (xmlSchemaWildcardPtr) particle->children; 12761 12762 start = pctxt->state; 12763 end = xmlAutomataNewState(pctxt->am); 12764 12765 if (particle->maxOccurs == 1) { 12766 if (wild->any == 1) { 12767 /* 12768 * We need to add both transitions: 12769 * 12770 * 1. the {"*", "*"} for elements in a namespace. 12771 */ 12772 pctxt->state = 12773 xmlAutomataNewTransition2(pctxt->am, 12774 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12775 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12776 /* 12777 * 2. the {"*"} for elements in no namespace. 12778 */ 12779 pctxt->state = 12780 xmlAutomataNewTransition2(pctxt->am, 12781 start, NULL, BAD_CAST "*", NULL, wild); 12782 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12783 12784 } else if (wild->nsSet != NULL) { 12785 ns = wild->nsSet; 12786 do { 12787 pctxt->state = start; 12788 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12789 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12790 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12791 ns = ns->next; 12792 } while (ns != NULL); 12793 12794 } else if (wild->negNsSet != NULL) { 12795 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12796 start, end, BAD_CAST "*", wild->negNsSet->value, 12797 wild); 12798 } 12799 } else { 12800 int counter; 12801 xmlAutomataStatePtr hop; 12802 int maxOccurs = 12803 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12804 particle->maxOccurs - 1; 12805 int minOccurs = 12806 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12807 12808 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12809 hop = xmlAutomataNewState(pctxt->am); 12810 if (wild->any == 1) { 12811 pctxt->state = 12812 xmlAutomataNewTransition2(pctxt->am, 12813 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12814 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12815 pctxt->state = 12816 xmlAutomataNewTransition2(pctxt->am, 12817 start, NULL, BAD_CAST "*", NULL, wild); 12818 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12819 } else if (wild->nsSet != NULL) { 12820 ns = wild->nsSet; 12821 do { 12822 pctxt->state = 12823 xmlAutomataNewTransition2(pctxt->am, 12824 start, NULL, BAD_CAST "*", ns->value, wild); 12825 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12826 ns = ns->next; 12827 } while (ns != NULL); 12828 12829 } else if (wild->negNsSet != NULL) { 12830 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12831 start, hop, BAD_CAST "*", wild->negNsSet->value, 12832 wild); 12833 } 12834 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12835 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12836 } 12837 if (particle->minOccurs == 0) { 12838 xmlAutomataNewEpsilon(pctxt->am, start, end); 12839 ret = 1; 12840 } 12841 pctxt->state = end; 12842 break; 12843 } 12844 case XML_SCHEMA_TYPE_ELEMENT: 12845 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12846 break; 12847 case XML_SCHEMA_TYPE_SEQUENCE:{ 12848 xmlSchemaTreeItemPtr sub; 12849 12850 ret = 1; 12851 /* 12852 * If max and min occurances are default (1) then 12853 * simply iterate over the particles of the <sequence>. 12854 */ 12855 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12856 sub = particle->children->children; 12857 12858 while (sub != NULL) { 12859 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12860 (xmlSchemaParticlePtr) sub); 12861 if (tmp2 != 1) ret = 0; 12862 sub = sub->next; 12863 } 12864 } else { 12865 xmlAutomataStatePtr oldstate = pctxt->state; 12866 12867 if (particle->maxOccurs >= UNBOUNDED) { 12868 if (particle->minOccurs > 1) { 12869 xmlAutomataStatePtr tmp; 12870 int counter; 12871 12872 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12873 oldstate, NULL); 12874 oldstate = pctxt->state; 12875 12876 counter = xmlAutomataNewCounter(pctxt->am, 12877 particle->minOccurs - 1, UNBOUNDED); 12878 12879 sub = particle->children->children; 12880 while (sub != NULL) { 12881 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12882 (xmlSchemaParticlePtr) sub); 12883 if (tmp2 != 1) ret = 0; 12884 sub = sub->next; 12885 } 12886 tmp = pctxt->state; 12887 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12888 oldstate, counter); 12889 pctxt->state = 12890 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12891 NULL, counter); 12892 if (ret == 1) 12893 xmlAutomataNewEpsilon(pctxt->am, 12894 oldstate, pctxt->state); 12895 12896 } else { 12897 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12898 oldstate, NULL); 12899 oldstate = pctxt->state; 12900 12901 sub = particle->children->children; 12902 while (sub != NULL) { 12903 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12904 (xmlSchemaParticlePtr) sub); 12905 if (tmp2 != 1) ret = 0; 12906 sub = sub->next; 12907 } 12908 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12909 oldstate); 12910 /* 12911 * epsilon needed to block previous trans from 12912 * being allowed to enter back from another 12913 * construct 12914 */ 12915 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12916 pctxt->state, NULL); 12917 if (particle->minOccurs == 0) { 12918 xmlAutomataNewEpsilon(pctxt->am, 12919 oldstate, pctxt->state); 12920 ret = 1; 12921 } 12922 } 12923 } else if ((particle->maxOccurs > 1) 12924 || (particle->minOccurs > 1)) { 12925 xmlAutomataStatePtr tmp; 12926 int counter; 12927 12928 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12929 oldstate, NULL); 12930 oldstate = pctxt->state; 12931 12932 counter = xmlAutomataNewCounter(pctxt->am, 12933 particle->minOccurs - 1, 12934 particle->maxOccurs - 1); 12935 12936 sub = particle->children->children; 12937 while (sub != NULL) { 12938 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12939 (xmlSchemaParticlePtr) sub); 12940 if (tmp2 != 1) ret = 0; 12941 sub = sub->next; 12942 } 12943 tmp = pctxt->state; 12944 xmlAutomataNewCountedTrans(pctxt->am, 12945 tmp, oldstate, counter); 12946 pctxt->state = 12947 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12948 counter); 12949 if ((particle->minOccurs == 0) || (ret == 1)) { 12950 xmlAutomataNewEpsilon(pctxt->am, 12951 oldstate, pctxt->state); 12952 ret = 1; 12953 } 12954 } else { 12955 sub = particle->children->children; 12956 while (sub != NULL) { 12957 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12958 (xmlSchemaParticlePtr) sub); 12959 if (tmp2 != 1) ret = 0; 12960 sub = sub->next; 12961 } 12962 12963 /* 12964 * epsilon needed to block previous trans from 12965 * being allowed to enter back from another 12966 * construct 12967 */ 12968 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12969 pctxt->state, NULL); 12970 12971 if (particle->minOccurs == 0) { 12972 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12973 pctxt->state); 12974 ret = 1; 12975 } 12976 } 12977 } 12978 break; 12979 } 12980 case XML_SCHEMA_TYPE_CHOICE:{ 12981 xmlSchemaTreeItemPtr sub; 12982 xmlAutomataStatePtr start, end; 12983 12984 ret = 0; 12985 start = pctxt->state; 12986 end = xmlAutomataNewState(pctxt->am); 12987 12988 /* 12989 * iterate over the subtypes and remerge the end with an 12990 * epsilon transition 12991 */ 12992 if (particle->maxOccurs == 1) { 12993 sub = particle->children->children; 12994 while (sub != NULL) { 12995 pctxt->state = start; 12996 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12997 (xmlSchemaParticlePtr) sub); 12998 if (tmp2 == 1) ret = 1; 12999 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13000 sub = sub->next; 13001 } 13002 } else { 13003 int counter; 13004 xmlAutomataStatePtr hop, base; 13005 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13006 UNBOUNDED : particle->maxOccurs - 1; 13007 int minOccurs = 13008 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13009 13010 /* 13011 * use a counter to keep track of the number of transtions 13012 * which went through the choice. 13013 */ 13014 counter = 13015 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13016 hop = xmlAutomataNewState(pctxt->am); 13017 base = xmlAutomataNewState(pctxt->am); 13018 13019 sub = particle->children->children; 13020 while (sub != NULL) { 13021 pctxt->state = base; 13022 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13023 (xmlSchemaParticlePtr) sub); 13024 if (tmp2 == 1) ret = 1; 13025 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13026 sub = sub->next; 13027 } 13028 xmlAutomataNewEpsilon(pctxt->am, start, base); 13029 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13030 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13031 if (ret == 1) 13032 xmlAutomataNewEpsilon(pctxt->am, base, end); 13033 } 13034 if (particle->minOccurs == 0) { 13035 xmlAutomataNewEpsilon(pctxt->am, start, end); 13036 ret = 1; 13037 } 13038 pctxt->state = end; 13039 break; 13040 } 13041 case XML_SCHEMA_TYPE_ALL:{ 13042 xmlAutomataStatePtr start, tmp; 13043 xmlSchemaParticlePtr sub; 13044 xmlSchemaElementPtr elemDecl; 13045 13046 ret = 1; 13047 13048 sub = (xmlSchemaParticlePtr) particle->children->children; 13049 if (sub == NULL) 13050 break; 13051 13052 ret = 0; 13053 13054 start = pctxt->state; 13055 tmp = xmlAutomataNewState(pctxt->am); 13056 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13057 pctxt->state = tmp; 13058 while (sub != NULL) { 13059 pctxt->state = tmp; 13060 13061 elemDecl = (xmlSchemaElementPtr) sub->children; 13062 if (elemDecl == NULL) { 13063 PERROR_INT("xmlSchemaBuildAContentModel", 13064 "<element> particle has no term"); 13065 return(ret); 13066 }; 13067 /* 13068 * NOTE: The {max occurs} of all the particles in the 13069 * {particles} of the group must be 0 or 1; this is 13070 * already ensured during the parse of the content of 13071 * <all>. 13072 */ 13073 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13074 int counter; 13075 13076 /* 13077 * This is an abstract group, we need to share 13078 * the same counter for all the element transitions 13079 * derived from the group 13080 */ 13081 counter = xmlAutomataNewCounter(pctxt->am, 13082 sub->minOccurs, sub->maxOccurs); 13083 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13084 sub, counter, pctxt->state); 13085 } else { 13086 if ((sub->minOccurs == 1) && 13087 (sub->maxOccurs == 1)) { 13088 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13089 pctxt->state, 13090 elemDecl->name, 13091 elemDecl->targetNamespace, 13092 1, 1, elemDecl); 13093 } else if ((sub->minOccurs == 0) && 13094 (sub->maxOccurs == 1)) { 13095 13096 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13097 pctxt->state, 13098 elemDecl->name, 13099 elemDecl->targetNamespace, 13100 0, 13101 1, 13102 elemDecl); 13103 } 13104 } 13105 sub = (xmlSchemaParticlePtr) sub->next; 13106 } 13107 pctxt->state = 13108 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13109 if (particle->minOccurs == 0) { 13110 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13111 ret = 1; 13112 } 13113 break; 13114 } 13115 case XML_SCHEMA_TYPE_GROUP: 13116 /* 13117 * If we hit a model group definition, then this means that 13118 * it was empty, thus was not substituted for the containing 13119 * model group. Just do nothing in this case. 13120 * TODO: But the group should be substituted and not occur at 13121 * all in the content model at this point. Fix this. 13122 */ 13123 ret = 1; 13124 break; 13125 default: 13126 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13127 "xmlSchemaBuildAContentModel", 13128 "found unexpected term of type '%s' in content model", 13129 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13130 return(ret); 13131 } 13132 return(ret); 13133} 13134 13135/** 13136 * xmlSchemaBuildContentModel: 13137 * @ctxt: the schema parser context 13138 * @type: the complex type definition 13139 * @name: the element name 13140 * 13141 * Builds the content model of the complex type. 13142 */ 13143static void 13144xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13145 xmlSchemaParserCtxtPtr ctxt) 13146{ 13147 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13148 (type->contModel != NULL) || 13149 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13150 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13151 return; 13152 13153#ifdef DEBUG_CONTENT 13154 xmlGenericError(xmlGenericErrorContext, 13155 "Building content model for %s\n", name); 13156#endif 13157 ctxt->am = NULL; 13158 ctxt->am = xmlNewAutomata(); 13159 if (ctxt->am == NULL) { 13160 xmlGenericError(xmlGenericErrorContext, 13161 "Cannot create automata for complex type %s\n", type->name); 13162 return; 13163 } 13164 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13165 /* 13166 * Build the automaton. 13167 */ 13168 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13169 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13170 type->contModel = xmlAutomataCompile(ctxt->am); 13171 if (type->contModel == NULL) { 13172 xmlSchemaPCustomErr(ctxt, 13173 XML_SCHEMAP_INTERNAL, 13174 WXS_BASIC_CAST type, type->node, 13175 "Failed to compile the content model", NULL); 13176 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13177 xmlSchemaPCustomErr(ctxt, 13178 XML_SCHEMAP_NOT_DETERMINISTIC, 13179 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13180 WXS_BASIC_CAST type, type->node, 13181 "The content model is not determinist", NULL); 13182 } else { 13183#ifdef DEBUG_CONTENT_REGEXP 13184 xmlGenericError(xmlGenericErrorContext, 13185 "Content model of %s:\n", type->name); 13186 xmlRegexpPrint(stderr, type->contModel); 13187#endif 13188 } 13189 ctxt->state = NULL; 13190 xmlFreeAutomata(ctxt->am); 13191 ctxt->am = NULL; 13192} 13193 13194/** 13195 * xmlSchemaResolveElementReferences: 13196 * @elem: the schema element context 13197 * @ctxt: the schema parser context 13198 * 13199 * Resolves the references of an element declaration 13200 * or particle, which has an element declaration as it's 13201 * term. 13202 */ 13203static void 13204xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13205 xmlSchemaParserCtxtPtr ctxt) 13206{ 13207 if ((ctxt == NULL) || (elemDecl == NULL) || 13208 ((elemDecl != NULL) && 13209 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13210 return; 13211 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13212 13213 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13214 xmlSchemaTypePtr type; 13215 13216 /* (type definition) ... otherwise the type definition `resolved` 13217 * to by the `actual value` of the type [attribute] ... 13218 */ 13219 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13220 elemDecl->namedTypeNs); 13221 if (type == NULL) { 13222 xmlSchemaPResCompAttrErr(ctxt, 13223 XML_SCHEMAP_SRC_RESOLVE, 13224 WXS_BASIC_CAST elemDecl, elemDecl->node, 13225 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13226 XML_SCHEMA_TYPE_BASIC, "type definition"); 13227 } else 13228 elemDecl->subtypes = type; 13229 } 13230 if (elemDecl->substGroup != NULL) { 13231 xmlSchemaElementPtr substHead; 13232 13233 /* 13234 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13235 * substitutionGroup? 13236 */ 13237 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13238 elemDecl->substGroupNs); 13239 if (substHead == NULL) { 13240 xmlSchemaPResCompAttrErr(ctxt, 13241 XML_SCHEMAP_SRC_RESOLVE, 13242 WXS_BASIC_CAST elemDecl, NULL, 13243 "substitutionGroup", elemDecl->substGroup, 13244 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13245 } else { 13246 xmlSchemaResolveElementReferences(substHead, ctxt); 13247 /* 13248 * Set the "substitution group affiliation". 13249 * NOTE that now we use the "refDecl" field for this. 13250 */ 13251 WXS_SUBST_HEAD(elemDecl) = substHead; 13252 /* 13253 * The type definitions is set to: 13254 * SPEC "...the {type definition} of the element 13255 * declaration `resolved` to by the `actual value` 13256 * of the substitutionGroup [attribute], if present" 13257 */ 13258 if (elemDecl->subtypes == NULL) 13259 elemDecl->subtypes = substHead->subtypes; 13260 } 13261 } 13262 /* 13263 * SPEC "The definition of anyType serves as the default type definition 13264 * for element declarations whose XML representation does not specify one." 13265 */ 13266 if ((elemDecl->subtypes == NULL) && 13267 (elemDecl->namedType == NULL) && 13268 (elemDecl->substGroup == NULL)) 13269 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13270} 13271 13272/** 13273 * xmlSchemaResolveUnionMemberTypes: 13274 * @ctxt: the schema parser context 13275 * @type: the schema simple type definition 13276 * 13277 * Checks and builds the "member type definitions" property of the union 13278 * simple type. This handles part (1), part (2) is done in 13279 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13280 * 13281 * Returns -1 in case of an internal error, 0 otherwise. 13282 */ 13283static int 13284xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13285 xmlSchemaTypePtr type) 13286{ 13287 13288 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13289 xmlSchemaTypePtr memberType; 13290 13291 /* 13292 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13293 * define the explicit members as the type definitions `resolved` 13294 * to by the items in the `actual value` of the memberTypes [attribute], 13295 * if any, followed by the type definitions corresponding to the 13296 * <simpleType>s among the [children] of <union>, if any." 13297 */ 13298 /* 13299 * Resolve references. 13300 */ 13301 link = type->memberTypes; 13302 lastLink = NULL; 13303 while (link != NULL) { 13304 const xmlChar *name, *nsName; 13305 13306 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13307 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13308 13309 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13310 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13311 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13312 WXS_BASIC_CAST type, type->node, "memberTypes", 13313 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13314 /* 13315 * Remove the member type link. 13316 */ 13317 if (lastLink == NULL) 13318 type->memberTypes = link->next; 13319 else 13320 lastLink->next = link->next; 13321 newLink = link; 13322 link = link->next; 13323 xmlFree(newLink); 13324 } else { 13325 link->type = memberType; 13326 lastLink = link; 13327 link = link->next; 13328 } 13329 } 13330 /* 13331 * Add local simple types, 13332 */ 13333 memberType = type->subtypes; 13334 while (memberType != NULL) { 13335 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13336 if (link == NULL) { 13337 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13338 return (-1); 13339 } 13340 link->type = memberType; 13341 link->next = NULL; 13342 if (lastLink == NULL) 13343 type->memberTypes = link; 13344 else 13345 lastLink->next = link; 13346 lastLink = link; 13347 memberType = memberType->next; 13348 } 13349 return (0); 13350} 13351 13352/** 13353 * xmlSchemaIsDerivedFromBuiltInType: 13354 * @ctxt: the schema parser context 13355 * @type: the type definition 13356 * @valType: the value type 13357 * 13358 * 13359 * Returns 1 if the type has the given value type, or 13360 * is derived from such a type. 13361 */ 13362static int 13363xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13364{ 13365 if (type == NULL) 13366 return (0); 13367 if (WXS_IS_COMPLEX(type)) 13368 return (0); 13369 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13370 if (type->builtInType == valType) 13371 return(1); 13372 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13373 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13374 return (0); 13375 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13376 } 13377 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13378} 13379 13380#if 0 13381/** 13382 * xmlSchemaIsDerivedFromBuiltInType: 13383 * @ctxt: the schema parser context 13384 * @type: the type definition 13385 * @valType: the value type 13386 * 13387 * 13388 * Returns 1 if the type has the given value type, or 13389 * is derived from such a type. 13390 */ 13391static int 13392xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13393{ 13394 if (type == NULL) 13395 return (0); 13396 if (WXS_IS_COMPLEX(type)) 13397 return (0); 13398 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13399 if (type->builtInType == valType) 13400 return(1); 13401 return (0); 13402 } else 13403 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13404 13405 return (0); 13406} 13407 13408static xmlSchemaTypePtr 13409xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13410{ 13411 if (type == NULL) 13412 return (NULL); 13413 if (WXS_IS_COMPLEX(type)) 13414 return (NULL); 13415 if (type->type == XML_SCHEMA_TYPE_BASIC) 13416 return(type); 13417 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13418} 13419#endif 13420 13421/** 13422 * xmlSchemaGetPrimitiveType: 13423 * @type: the simpleType definition 13424 * 13425 * Returns the primitive type of the given type or 13426 * NULL in case of error. 13427 */ 13428static xmlSchemaTypePtr 13429xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13430{ 13431 13432 while (type != NULL) { 13433 /* 13434 * Note that anySimpleType is actually not a primitive type 13435 * but we need that here. 13436 */ 13437 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13438 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13439 return (type); 13440 type = type->baseType; 13441 } 13442 13443 return (NULL); 13444} 13445 13446#if 0 13447/** 13448 * xmlSchemaGetBuiltInTypeAncestor: 13449 * @type: the simpleType definition 13450 * 13451 * Returns the primitive type of the given type or 13452 * NULL in case of error. 13453 */ 13454static xmlSchemaTypePtr 13455xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13456{ 13457 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13458 return (0); 13459 while (type != NULL) { 13460 if (type->type == XML_SCHEMA_TYPE_BASIC) 13461 return (type); 13462 type = type->baseType; 13463 } 13464 13465 return (NULL); 13466} 13467#endif 13468 13469/** 13470 * xmlSchemaCloneWildcardNsConstraints: 13471 * @ctxt: the schema parser context 13472 * @dest: the destination wildcard 13473 * @source: the source wildcard 13474 * 13475 * Clones the namespace constraints of source 13476 * and assignes them to dest. 13477 * Returns -1 on internal error, 0 otherwise. 13478 */ 13479static int 13480xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13481 xmlSchemaWildcardPtr dest, 13482 xmlSchemaWildcardPtr source) 13483{ 13484 xmlSchemaWildcardNsPtr cur, tmp, last; 13485 13486 if ((source == NULL) || (dest == NULL)) 13487 return(-1); 13488 dest->any = source->any; 13489 cur = source->nsSet; 13490 last = NULL; 13491 while (cur != NULL) { 13492 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13493 if (tmp == NULL) 13494 return(-1); 13495 tmp->value = cur->value; 13496 if (last == NULL) 13497 dest->nsSet = tmp; 13498 else 13499 last->next = tmp; 13500 last = tmp; 13501 cur = cur->next; 13502 } 13503 if (dest->negNsSet != NULL) 13504 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13505 if (source->negNsSet != NULL) { 13506 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13507 if (dest->negNsSet == NULL) 13508 return(-1); 13509 dest->negNsSet->value = source->negNsSet->value; 13510 } else 13511 dest->negNsSet = NULL; 13512 return(0); 13513} 13514 13515/** 13516 * xmlSchemaUnionWildcards: 13517 * @ctxt: the schema parser context 13518 * @completeWild: the first wildcard 13519 * @curWild: the second wildcard 13520 * 13521 * Unions the namespace constraints of the given wildcards. 13522 * @completeWild will hold the resulting union. 13523 * Returns a positive error code on failure, -1 in case of an 13524 * internal error, 0 otherwise. 13525 */ 13526static int 13527xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13528 xmlSchemaWildcardPtr completeWild, 13529 xmlSchemaWildcardPtr curWild) 13530{ 13531 xmlSchemaWildcardNsPtr cur, curB, tmp; 13532 13533 /* 13534 * 1 If O1 and O2 are the same value, then that value must be the 13535 * value. 13536 */ 13537 if ((completeWild->any == curWild->any) && 13538 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13539 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13540 13541 if ((completeWild->negNsSet == NULL) || 13542 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13543 13544 if (completeWild->nsSet != NULL) { 13545 int found = 0; 13546 13547 /* 13548 * Check equality of sets. 13549 */ 13550 cur = completeWild->nsSet; 13551 while (cur != NULL) { 13552 found = 0; 13553 curB = curWild->nsSet; 13554 while (curB != NULL) { 13555 if (cur->value == curB->value) { 13556 found = 1; 13557 break; 13558 } 13559 curB = curB->next; 13560 } 13561 if (!found) 13562 break; 13563 cur = cur->next; 13564 } 13565 if (found) 13566 return(0); 13567 } else 13568 return(0); 13569 } 13570 } 13571 /* 13572 * 2 If either O1 or O2 is any, then any must be the value 13573 */ 13574 if (completeWild->any != curWild->any) { 13575 if (completeWild->any == 0) { 13576 completeWild->any = 1; 13577 if (completeWild->nsSet != NULL) { 13578 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13579 completeWild->nsSet = NULL; 13580 } 13581 if (completeWild->negNsSet != NULL) { 13582 xmlFree(completeWild->negNsSet); 13583 completeWild->negNsSet = NULL; 13584 } 13585 } 13586 return (0); 13587 } 13588 /* 13589 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13590 * then the union of those sets must be the value. 13591 */ 13592 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13593 int found; 13594 xmlSchemaWildcardNsPtr start; 13595 13596 cur = curWild->nsSet; 13597 start = completeWild->nsSet; 13598 while (cur != NULL) { 13599 found = 0; 13600 curB = start; 13601 while (curB != NULL) { 13602 if (cur->value == curB->value) { 13603 found = 1; 13604 break; 13605 } 13606 curB = curB->next; 13607 } 13608 if (!found) { 13609 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13610 if (tmp == NULL) 13611 return (-1); 13612 tmp->value = cur->value; 13613 tmp->next = completeWild->nsSet; 13614 completeWild->nsSet = tmp; 13615 } 13616 cur = cur->next; 13617 } 13618 13619 return(0); 13620 } 13621 /* 13622 * 4 If the two are negations of different values (namespace names 13623 * or `absent`), then a pair of not and `absent` must be the value. 13624 */ 13625 if ((completeWild->negNsSet != NULL) && 13626 (curWild->negNsSet != NULL) && 13627 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13628 completeWild->negNsSet->value = NULL; 13629 13630 return(0); 13631 } 13632 /* 13633 * 5. 13634 */ 13635 if (((completeWild->negNsSet != NULL) && 13636 (completeWild->negNsSet->value != NULL) && 13637 (curWild->nsSet != NULL)) || 13638 ((curWild->negNsSet != NULL) && 13639 (curWild->negNsSet->value != NULL) && 13640 (completeWild->nsSet != NULL))) { 13641 13642 int nsFound, absentFound = 0; 13643 13644 if (completeWild->nsSet != NULL) { 13645 cur = completeWild->nsSet; 13646 curB = curWild->negNsSet; 13647 } else { 13648 cur = curWild->nsSet; 13649 curB = completeWild->negNsSet; 13650 } 13651 nsFound = 0; 13652 while (cur != NULL) { 13653 if (cur->value == NULL) 13654 absentFound = 1; 13655 else if (cur->value == curB->value) 13656 nsFound = 1; 13657 if (nsFound && absentFound) 13658 break; 13659 cur = cur->next; 13660 } 13661 13662 if (nsFound && absentFound) { 13663 /* 13664 * 5.1 If the set S includes both the negated namespace 13665 * name and `absent`, then any must be the value. 13666 */ 13667 completeWild->any = 1; 13668 if (completeWild->nsSet != NULL) { 13669 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13670 completeWild->nsSet = NULL; 13671 } 13672 if (completeWild->negNsSet != NULL) { 13673 xmlFree(completeWild->negNsSet); 13674 completeWild->negNsSet = NULL; 13675 } 13676 } else if (nsFound && (!absentFound)) { 13677 /* 13678 * 5.2 If the set S includes the negated namespace name 13679 * but not `absent`, then a pair of not and `absent` must 13680 * be the value. 13681 */ 13682 if (completeWild->nsSet != NULL) { 13683 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13684 completeWild->nsSet = NULL; 13685 } 13686 if (completeWild->negNsSet == NULL) { 13687 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13688 if (completeWild->negNsSet == NULL) 13689 return (-1); 13690 } 13691 completeWild->negNsSet->value = NULL; 13692 } else if ((!nsFound) && absentFound) { 13693 /* 13694 * 5.3 If the set S includes `absent` but not the negated 13695 * namespace name, then the union is not expressible. 13696 */ 13697 xmlSchemaPErr(ctxt, completeWild->node, 13698 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13699 "The union of the wilcard is not expressible.\n", 13700 NULL, NULL); 13701 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13702 } else if ((!nsFound) && (!absentFound)) { 13703 /* 13704 * 5.4 If the set S does not include either the negated namespace 13705 * name or `absent`, then whichever of O1 or O2 is a pair of not 13706 * and a namespace name must be the value. 13707 */ 13708 if (completeWild->negNsSet == NULL) { 13709 if (completeWild->nsSet != NULL) { 13710 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13711 completeWild->nsSet = NULL; 13712 } 13713 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13714 if (completeWild->negNsSet == NULL) 13715 return (-1); 13716 completeWild->negNsSet->value = curWild->negNsSet->value; 13717 } 13718 } 13719 return (0); 13720 } 13721 /* 13722 * 6. 13723 */ 13724 if (((completeWild->negNsSet != NULL) && 13725 (completeWild->negNsSet->value == NULL) && 13726 (curWild->nsSet != NULL)) || 13727 ((curWild->negNsSet != NULL) && 13728 (curWild->negNsSet->value == NULL) && 13729 (completeWild->nsSet != NULL))) { 13730 13731 if (completeWild->nsSet != NULL) { 13732 cur = completeWild->nsSet; 13733 } else { 13734 cur = curWild->nsSet; 13735 } 13736 while (cur != NULL) { 13737 if (cur->value == NULL) { 13738 /* 13739 * 6.1 If the set S includes `absent`, then any must be the 13740 * value. 13741 */ 13742 completeWild->any = 1; 13743 if (completeWild->nsSet != NULL) { 13744 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13745 completeWild->nsSet = NULL; 13746 } 13747 if (completeWild->negNsSet != NULL) { 13748 xmlFree(completeWild->negNsSet); 13749 completeWild->negNsSet = NULL; 13750 } 13751 return (0); 13752 } 13753 cur = cur->next; 13754 } 13755 if (completeWild->negNsSet == NULL) { 13756 /* 13757 * 6.2 If the set S does not include `absent`, then a pair of not 13758 * and `absent` must be the value. 13759 */ 13760 if (completeWild->nsSet != NULL) { 13761 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13762 completeWild->nsSet = NULL; 13763 } 13764 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13765 if (completeWild->negNsSet == NULL) 13766 return (-1); 13767 completeWild->negNsSet->value = NULL; 13768 } 13769 return (0); 13770 } 13771 return (0); 13772 13773} 13774 13775/** 13776 * xmlSchemaIntersectWildcards: 13777 * @ctxt: the schema parser context 13778 * @completeWild: the first wildcard 13779 * @curWild: the second wildcard 13780 * 13781 * Intersects the namespace constraints of the given wildcards. 13782 * @completeWild will hold the resulting intersection. 13783 * Returns a positive error code on failure, -1 in case of an 13784 * internal error, 0 otherwise. 13785 */ 13786static int 13787xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13788 xmlSchemaWildcardPtr completeWild, 13789 xmlSchemaWildcardPtr curWild) 13790{ 13791 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13792 13793 /* 13794 * 1 If O1 and O2 are the same value, then that value must be the 13795 * value. 13796 */ 13797 if ((completeWild->any == curWild->any) && 13798 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13799 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13800 13801 if ((completeWild->negNsSet == NULL) || 13802 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13803 13804 if (completeWild->nsSet != NULL) { 13805 int found = 0; 13806 13807 /* 13808 * Check equality of sets. 13809 */ 13810 cur = completeWild->nsSet; 13811 while (cur != NULL) { 13812 found = 0; 13813 curB = curWild->nsSet; 13814 while (curB != NULL) { 13815 if (cur->value == curB->value) { 13816 found = 1; 13817 break; 13818 } 13819 curB = curB->next; 13820 } 13821 if (!found) 13822 break; 13823 cur = cur->next; 13824 } 13825 if (found) 13826 return(0); 13827 } else 13828 return(0); 13829 } 13830 } 13831 /* 13832 * 2 If either O1 or O2 is any, then the other must be the value. 13833 */ 13834 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13835 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13836 return(-1); 13837 return(0); 13838 } 13839 /* 13840 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13841 * name or `absent`) and the other is a set of (namespace names or 13842 * `absent`), then that set, minus the negated value if it was in 13843 * the set, minus `absent` if it was in the set, must be the value. 13844 */ 13845 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13846 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13847 const xmlChar *neg; 13848 13849 if (completeWild->nsSet == NULL) { 13850 neg = completeWild->negNsSet->value; 13851 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13852 return(-1); 13853 } else 13854 neg = curWild->negNsSet->value; 13855 /* 13856 * Remove absent and negated. 13857 */ 13858 prev = NULL; 13859 cur = completeWild->nsSet; 13860 while (cur != NULL) { 13861 if (cur->value == NULL) { 13862 if (prev == NULL) 13863 completeWild->nsSet = cur->next; 13864 else 13865 prev->next = cur->next; 13866 xmlFree(cur); 13867 break; 13868 } 13869 prev = cur; 13870 cur = cur->next; 13871 } 13872 if (neg != NULL) { 13873 prev = NULL; 13874 cur = completeWild->nsSet; 13875 while (cur != NULL) { 13876 if (cur->value == neg) { 13877 if (prev == NULL) 13878 completeWild->nsSet = cur->next; 13879 else 13880 prev->next = cur->next; 13881 xmlFree(cur); 13882 break; 13883 } 13884 prev = cur; 13885 cur = cur->next; 13886 } 13887 } 13888 13889 return(0); 13890 } 13891 /* 13892 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13893 * then the intersection of those sets must be the value. 13894 */ 13895 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13896 int found; 13897 13898 cur = completeWild->nsSet; 13899 prev = NULL; 13900 while (cur != NULL) { 13901 found = 0; 13902 curB = curWild->nsSet; 13903 while (curB != NULL) { 13904 if (cur->value == curB->value) { 13905 found = 1; 13906 break; 13907 } 13908 curB = curB->next; 13909 } 13910 if (!found) { 13911 if (prev == NULL) 13912 completeWild->nsSet = cur->next; 13913 else 13914 prev->next = cur->next; 13915 tmp = cur->next; 13916 xmlFree(cur); 13917 cur = tmp; 13918 continue; 13919 } 13920 prev = cur; 13921 cur = cur->next; 13922 } 13923 13924 return(0); 13925 } 13926 /* 5 If the two are negations of different namespace names, 13927 * then the intersection is not expressible 13928 */ 13929 if ((completeWild->negNsSet != NULL) && 13930 (curWild->negNsSet != NULL) && 13931 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13932 (completeWild->negNsSet->value != NULL) && 13933 (curWild->negNsSet->value != NULL)) { 13934 13935 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13936 "The intersection of the wilcard is not expressible.\n", 13937 NULL, NULL); 13938 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13939 } 13940 /* 13941 * 6 If the one is a negation of a namespace name and the other 13942 * is a negation of `absent`, then the one which is the negation 13943 * of a namespace name must be the value. 13944 */ 13945 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13946 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13947 (completeWild->negNsSet->value == NULL)) { 13948 completeWild->negNsSet->value = curWild->negNsSet->value; 13949 } 13950 return(0); 13951} 13952 13953/** 13954 * xmlSchemaIsWildcardNsConstraintSubset: 13955 * @ctxt: the schema parser context 13956 * @sub: the first wildcard 13957 * @super: the second wildcard 13958 * 13959 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13960 * 13961 * Returns 0 if the namespace constraint of @sub is an intensional 13962 * subset of @super, 1 otherwise. 13963 */ 13964static int 13965xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13966 xmlSchemaWildcardPtr super) 13967{ 13968 /* 13969 * 1 super must be any. 13970 */ 13971 if (super->any) 13972 return (0); 13973 /* 13974 * 2.1 sub must be a pair of not and a namespace name or `absent`. 13975 * 2.2 super must be a pair of not and the same value. 13976 */ 13977 if ((sub->negNsSet != NULL) && 13978 (super->negNsSet != NULL) && 13979 (sub->negNsSet->value == super->negNsSet->value)) 13980 return (0); 13981 /* 13982 * 3.1 sub must be a set whose members are either namespace names or `absent`. 13983 */ 13984 if (sub->nsSet != NULL) { 13985 /* 13986 * 3.2.1 super must be the same set or a superset thereof. 13987 */ 13988 if (super->nsSet != NULL) { 13989 xmlSchemaWildcardNsPtr cur, curB; 13990 int found = 0; 13991 13992 cur = sub->nsSet; 13993 while (cur != NULL) { 13994 found = 0; 13995 curB = super->nsSet; 13996 while (curB != NULL) { 13997 if (cur->value == curB->value) { 13998 found = 1; 13999 break; 14000 } 14001 curB = curB->next; 14002 } 14003 if (!found) 14004 return (1); 14005 cur = cur->next; 14006 } 14007 if (found) 14008 return (0); 14009 } else if (super->negNsSet != NULL) { 14010 xmlSchemaWildcardNsPtr cur; 14011 /* 14012 * 3.2.2 super must be a pair of not and a namespace name or 14013 * `absent` and that value must not be in sub's set. 14014 */ 14015 cur = sub->nsSet; 14016 while (cur != NULL) { 14017 if (cur->value == super->negNsSet->value) 14018 return (1); 14019 cur = cur->next; 14020 } 14021 return (0); 14022 } 14023 } 14024 return (1); 14025} 14026 14027static int 14028xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14029 int *fixed, 14030 const xmlChar **value, 14031 xmlSchemaValPtr *val) 14032{ 14033 *fixed = 0; 14034 *value = NULL; 14035 if (val != 0) 14036 *val = NULL; 14037 14038 if (attruse->defValue != NULL) { 14039 *value = attruse->defValue; 14040 if (val != NULL) 14041 *val = attruse->defVal; 14042 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14043 *fixed = 1; 14044 return(1); 14045 } else if ((attruse->attrDecl != NULL) && 14046 (attruse->attrDecl->defValue != NULL)) { 14047 *value = attruse->attrDecl->defValue; 14048 if (val != NULL) 14049 *val = attruse->attrDecl->defVal; 14050 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14051 *fixed = 1; 14052 return(1); 14053 } 14054 return(0); 14055} 14056/** 14057 * xmlSchemaCheckCVCWildcardNamespace: 14058 * @wild: the wildcard 14059 * @ns: the namespace 14060 * 14061 * Validation Rule: Wildcard allows Namespace Name 14062 * (cvc-wildcard-namespace) 14063 * 14064 * Returns 0 if the given namespace matches the wildcard, 14065 * 1 otherwise and -1 on API errors. 14066 */ 14067static int 14068xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14069 const xmlChar* ns) 14070{ 14071 if (wild == NULL) 14072 return(-1); 14073 14074 if (wild->any) 14075 return(0); 14076 else if (wild->nsSet != NULL) { 14077 xmlSchemaWildcardNsPtr cur; 14078 14079 cur = wild->nsSet; 14080 while (cur != NULL) { 14081 if (xmlStrEqual(cur->value, ns)) 14082 return(0); 14083 cur = cur->next; 14084 } 14085 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14086 (!xmlStrEqual(wild->negNsSet->value, ns))) 14087 return(0); 14088 14089 return(1); 14090} 14091 14092#define XML_SCHEMA_ACTION_DERIVE 0 14093#define XML_SCHEMA_ACTION_REDEFINE 1 14094 14095#define WXS_ACTION_STR(a) \ 14096((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14097 14098/* 14099* Schema Component Constraint: 14100* Derivation Valid (Restriction, Complex) 14101* derivation-ok-restriction (2) - (4) 14102* 14103* ATTENTION: 14104* In XML Schema 1.1 this will be: 14105* Validation Rule: 14106* Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14107* 14108*/ 14109static int 14110xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14111 int action, 14112 xmlSchemaBasicItemPtr item, 14113 xmlSchemaBasicItemPtr baseItem, 14114 xmlSchemaItemListPtr uses, 14115 xmlSchemaItemListPtr baseUses, 14116 xmlSchemaWildcardPtr wild, 14117 xmlSchemaWildcardPtr baseWild) 14118{ 14119 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14120 int i, j, found; /* err = 0; */ 14121 const xmlChar *bEffValue; 14122 int effFixed; 14123 14124 if (uses != NULL) { 14125 for (i = 0; i < uses->nbItems; i++) { 14126 cur = uses->items[i]; 14127 found = 0; 14128 if (baseUses == NULL) 14129 goto not_found; 14130 for (j = 0; j < baseUses->nbItems; j++) { 14131 bcur = baseUses->items[j]; 14132 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14133 WXS_ATTRUSE_DECL_NAME(bcur)) && 14134 (WXS_ATTRUSE_DECL_TNS(cur) == 14135 WXS_ATTRUSE_DECL_TNS(bcur))) 14136 { 14137 /* 14138 * (2.1) "If there is an attribute use in the {attribute 14139 * uses} of the {base type definition} (call this B) whose 14140 * {attribute declaration} has the same {name} and {target 14141 * namespace}, then all of the following must be true:" 14142 */ 14143 found = 1; 14144 14145 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14146 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14147 { 14148 xmlChar *str = NULL; 14149 /* 14150 * (2.1.1) "one of the following must be true:" 14151 * (2.1.1.1) "B's {required} is false." 14152 * (2.1.1.2) "R's {required} is true." 14153 */ 14154 xmlSchemaPAttrUseErr4(pctxt, 14155 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14156 WXS_ITEM_NODE(item), item, cur, 14157 "The 'optional' attribute use is inconsistent " 14158 "with the corresponding 'required' attribute use of " 14159 "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 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14166 WXS_ATTRUSE_TYPEDEF(cur), 14167 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14168 { 14169 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14170 14171 /* 14172 * SPEC (2.1.2) "R's {attribute declaration}'s 14173 * {type definition} must be validly derived from 14174 * B's {type definition} given the empty set as 14175 * defined in Type Derivation OK (Simple) ($3.14.6)." 14176 */ 14177 xmlSchemaPAttrUseErr4(pctxt, 14178 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14179 WXS_ITEM_NODE(item), item, cur, 14180 "The attribute declaration's %s " 14181 "is not validly derived from " 14182 "the corresponding %s of the " 14183 "attribute declaration in the %s %s", 14184 xmlSchemaGetComponentDesignation(&strA, 14185 WXS_ATTRUSE_TYPEDEF(cur)), 14186 xmlSchemaGetComponentDesignation(&strB, 14187 WXS_ATTRUSE_TYPEDEF(bcur)), 14188 WXS_ACTION_STR(action), 14189 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14190 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14191 FREE_AND_NULL(strA); 14192 FREE_AND_NULL(strB); 14193 FREE_AND_NULL(strC); 14194 /* err = pctxt->err; */ 14195 } else { 14196 /* 14197 * 2.1.3 [Definition:] Let the effective value 14198 * constraint of an attribute use be its {value 14199 * constraint}, if present, otherwise its {attribute 14200 * declaration}'s {value constraint} . 14201 */ 14202 xmlSchemaGetEffectiveValueConstraint(bcur, 14203 &effFixed, &bEffValue, NULL); 14204 /* 14205 * 2.1.3 ... one of the following must be true 14206 * 14207 * 2.1.3.1 B's `effective value constraint` is 14208 * `absent` or default. 14209 */ 14210 if ((bEffValue != NULL) && 14211 (effFixed == 1)) { 14212 const xmlChar *rEffValue = NULL; 14213 14214 xmlSchemaGetEffectiveValueConstraint(bcur, 14215 &effFixed, &rEffValue, NULL); 14216 /* 14217 * 2.1.3.2 R's `effective value constraint` is 14218 * fixed with the same string as B's. 14219 * MAYBE TODO: Compare the computed values. 14220 * Hmm, it says "same string" so 14221 * string-equality might really be sufficient. 14222 */ 14223 if ((effFixed == 0) || 14224 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14225 { 14226 xmlChar *str = NULL; 14227 14228 xmlSchemaPAttrUseErr4(pctxt, 14229 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14230 WXS_ITEM_NODE(item), item, cur, 14231 "The effective value constraint of the " 14232 "attribute use is inconsistent with " 14233 "its correspondent in the %s %s", 14234 WXS_ACTION_STR(action), 14235 xmlSchemaGetComponentDesignation(&str, 14236 baseItem), 14237 NULL, NULL); 14238 FREE_AND_NULL(str); 14239 /* err = pctxt->err; */ 14240 } 14241 } 14242 } 14243 break; 14244 } 14245 } 14246not_found: 14247 if (!found) { 14248 /* 14249 * (2.2) "otherwise the {base type definition} must have an 14250 * {attribute wildcard} and the {target namespace} of the 14251 * R's {attribute declaration} must be `valid` with respect 14252 * to that wildcard, as defined in Wildcard allows Namespace 14253 * Name ($3.10.4)." 14254 */ 14255 if ((baseWild == NULL) || 14256 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14257 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14258 { 14259 xmlChar *str = NULL; 14260 14261 xmlSchemaPAttrUseErr4(pctxt, 14262 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14263 WXS_ITEM_NODE(item), item, cur, 14264 "Neither a matching attribute use, " 14265 "nor a matching wildcard exists in the %s %s", 14266 WXS_ACTION_STR(action), 14267 xmlSchemaGetComponentDesignation(&str, baseItem), 14268 NULL, NULL); 14269 FREE_AND_NULL(str); 14270 /* err = pctxt->err; */ 14271 } 14272 } 14273 } 14274 } 14275 /* 14276 * SPEC derivation-ok-restriction (3): 14277 * (3) "For each attribute use in the {attribute uses} of the {base type 14278 * definition} whose {required} is true, there must be an attribute 14279 * use with an {attribute declaration} with the same {name} and 14280 * {target namespace} as its {attribute declaration} in the {attribute 14281 * uses} of the complex type definition itself whose {required} is true. 14282 */ 14283 if (baseUses != NULL) { 14284 for (j = 0; j < baseUses->nbItems; j++) { 14285 bcur = baseUses->items[j]; 14286 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14287 continue; 14288 found = 0; 14289 if (uses != NULL) { 14290 for (i = 0; i < uses->nbItems; i++) { 14291 cur = uses->items[i]; 14292 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14293 WXS_ATTRUSE_DECL_NAME(bcur)) && 14294 (WXS_ATTRUSE_DECL_TNS(cur) == 14295 WXS_ATTRUSE_DECL_TNS(bcur))) { 14296 found = 1; 14297 break; 14298 } 14299 } 14300 } 14301 if (!found) { 14302 xmlChar *strA = NULL, *strB = NULL; 14303 14304 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14305 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14306 NULL, item, 14307 "A matching attribute use for the " 14308 "'required' %s of the %s %s is missing", 14309 xmlSchemaGetComponentDesignation(&strA, bcur), 14310 WXS_ACTION_STR(action), 14311 xmlSchemaGetComponentDesignation(&strB, baseItem), 14312 NULL); 14313 FREE_AND_NULL(strA); 14314 FREE_AND_NULL(strB); 14315 } 14316 } 14317 } 14318 /* 14319 * derivation-ok-restriction (4) 14320 */ 14321 if (wild != NULL) { 14322 /* 14323 * (4) "If there is an {attribute wildcard}, all of the 14324 * following must be true:" 14325 */ 14326 if (baseWild == NULL) { 14327 xmlChar *str = NULL; 14328 14329 /* 14330 * (4.1) "The {base type definition} must also have one." 14331 */ 14332 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14333 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14334 NULL, item, 14335 "The %s has an attribute wildcard, " 14336 "but the %s %s '%s' does not have one", 14337 WXS_ITEM_TYPE_NAME(item), 14338 WXS_ACTION_STR(action), 14339 WXS_ITEM_TYPE_NAME(baseItem), 14340 xmlSchemaGetComponentQName(&str, baseItem)); 14341 FREE_AND_NULL(str); 14342 return(pctxt->err); 14343 } else if ((baseWild->any == 0) && 14344 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14345 { 14346 xmlChar *str = NULL; 14347 /* 14348 * (4.2) "The complex type definition's {attribute wildcard}'s 14349 * {namespace constraint} must be a subset of the {base type 14350 * definition}'s {attribute wildcard}'s {namespace constraint}, 14351 * as defined by Wildcard Subset ($3.10.6)." 14352 */ 14353 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14354 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14355 NULL, item, 14356 "The attribute wildcard is not a valid " 14357 "subset of the wildcard in the %s %s '%s'", 14358 WXS_ACTION_STR(action), 14359 WXS_ITEM_TYPE_NAME(baseItem), 14360 xmlSchemaGetComponentQName(&str, baseItem), 14361 NULL); 14362 FREE_AND_NULL(str); 14363 return(pctxt->err); 14364 } 14365 /* 4.3 Unless the {base type definition} is the `ur-type 14366 * definition`, the complex type definition's {attribute 14367 * wildcard}'s {process contents} must be identical to or 14368 * stronger than the {base type definition}'s {attribute 14369 * wildcard}'s {process contents}, where strict is stronger 14370 * than lax is stronger than skip. 14371 */ 14372 if ((! WXS_IS_ANYTYPE(baseItem)) && 14373 (wild->processContents < baseWild->processContents)) { 14374 xmlChar *str = NULL; 14375 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14376 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14377 NULL, baseItem, 14378 "The {process contents} of the attribute wildcard is " 14379 "weaker than the one in the %s %s '%s'", 14380 WXS_ACTION_STR(action), 14381 WXS_ITEM_TYPE_NAME(baseItem), 14382 xmlSchemaGetComponentQName(&str, baseItem), 14383 NULL); 14384 FREE_AND_NULL(str) 14385 return(pctxt->err); 14386 } 14387 } 14388 return(0); 14389} 14390 14391 14392static int 14393xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14394 xmlSchemaBasicItemPtr item, 14395 xmlSchemaWildcardPtr *completeWild, 14396 xmlSchemaItemListPtr list, 14397 xmlSchemaItemListPtr prohibs); 14398/** 14399 * xmlSchemaFixupTypeAttributeUses: 14400 * @ctxt: the schema parser context 14401 * @type: the complex type definition 14402 * 14403 * 14404 * Builds the wildcard and the attribute uses on the given complex type. 14405 * Returns -1 if an internal error occurs, 0 otherwise. 14406 * 14407 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14408 * strings, so recheck this if we start to hardcode some schemata, since 14409 * they might not be in the same dict. 14410 * NOTE: It is allowed to "extend" the xs:anyType type. 14411 */ 14412static int 14413xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14414 xmlSchemaTypePtr type) 14415{ 14416 xmlSchemaTypePtr baseType = NULL; 14417 xmlSchemaAttributeUsePtr use; 14418 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14419 14420 if (type->baseType == NULL) { 14421 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14422 "no base type"); 14423 return (-1); 14424 } 14425 baseType = type->baseType; 14426 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14427 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14428 return(-1); 14429 14430 uses = type->attrUses; 14431 baseUses = baseType->attrUses; 14432 /* 14433 * Expand attribute group references. And build the 'complete' 14434 * wildcard, i.e. intersect multiple wildcards. 14435 * Move attribute prohibitions into a separate list. 14436 */ 14437 if (uses != NULL) { 14438 if (WXS_IS_RESTRICTION(type)) { 14439 /* 14440 * This one will transfer all attr. prohibitions 14441 * into pctxt->attrProhibs. 14442 */ 14443 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14444 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14445 pctxt->attrProhibs) == -1) 14446 { 14447 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14448 "failed to expand attributes"); 14449 } 14450 if (pctxt->attrProhibs->nbItems != 0) 14451 prohibs = pctxt->attrProhibs; 14452 } else { 14453 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14454 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14455 NULL) == -1) 14456 { 14457 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14458 "failed to expand attributes"); 14459 } 14460 } 14461 } 14462 /* 14463 * Inherit the attribute uses of the base type. 14464 */ 14465 if (baseUses != NULL) { 14466 int i, j; 14467 xmlSchemaAttributeUseProhibPtr pro; 14468 14469 if (WXS_IS_RESTRICTION(type)) { 14470 int usesCount; 14471 xmlSchemaAttributeUsePtr tmp; 14472 14473 if (uses != NULL) 14474 usesCount = uses->nbItems; 14475 else 14476 usesCount = 0; 14477 14478 /* Restriction. */ 14479 for (i = 0; i < baseUses->nbItems; i++) { 14480 use = baseUses->items[i]; 14481 if (prohibs) { 14482 /* 14483 * Filter out prohibited uses. 14484 */ 14485 for (j = 0; j < prohibs->nbItems; j++) { 14486 pro = prohibs->items[j]; 14487 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14488 (WXS_ATTRUSE_DECL_TNS(use) == 14489 pro->targetNamespace)) 14490 { 14491 goto inherit_next; 14492 } 14493 } 14494 } 14495 if (usesCount) { 14496 /* 14497 * Filter out existing uses. 14498 */ 14499 for (j = 0; j < usesCount; j++) { 14500 tmp = uses->items[j]; 14501 if ((WXS_ATTRUSE_DECL_NAME(use) == 14502 WXS_ATTRUSE_DECL_NAME(tmp)) && 14503 (WXS_ATTRUSE_DECL_TNS(use) == 14504 WXS_ATTRUSE_DECL_TNS(tmp))) 14505 { 14506 goto inherit_next; 14507 } 14508 } 14509 } 14510 if (uses == NULL) { 14511 type->attrUses = xmlSchemaItemListCreate(); 14512 if (type->attrUses == NULL) 14513 goto exit_failure; 14514 uses = type->attrUses; 14515 } 14516 xmlSchemaItemListAddSize(uses, 2, use); 14517inherit_next: {} 14518 } 14519 } else { 14520 /* Extension. */ 14521 for (i = 0; i < baseUses->nbItems; i++) { 14522 use = baseUses->items[i]; 14523 if (uses == NULL) { 14524 type->attrUses = xmlSchemaItemListCreate(); 14525 if (type->attrUses == NULL) 14526 goto exit_failure; 14527 uses = type->attrUses; 14528 } 14529 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14530 } 14531 } 14532 } 14533 /* 14534 * Shrink attr. uses. 14535 */ 14536 if (uses) { 14537 if (uses->nbItems == 0) { 14538 xmlSchemaItemListFree(uses); 14539 type->attrUses = NULL; 14540 } 14541 /* 14542 * TODO: We could shrink the size of the array 14543 * to fit the actual number of items. 14544 */ 14545 } 14546 /* 14547 * Compute the complete wildcard. 14548 */ 14549 if (WXS_IS_EXTENSION(type)) { 14550 if (baseType->attributeWildcard != NULL) { 14551 /* 14552 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14553 * the appropriate case among the following:" 14554 */ 14555 if (type->attributeWildcard != NULL) { 14556 /* 14557 * Union the complete wildcard with the base wildcard. 14558 * SPEC {attribute wildcard} 14559 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14560 * and {annotation} are those of the `complete wildcard`, 14561 * and whose {namespace constraint} is the intensional union 14562 * of the {namespace constraint} of the `complete wildcard` 14563 * and of the `base wildcard`, as defined in Attribute 14564 * Wildcard Union ($3.10.6)." 14565 */ 14566 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14567 baseType->attributeWildcard) == -1) 14568 goto exit_failure; 14569 } else { 14570 /* 14571 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14572 * then the `base wildcard`." 14573 */ 14574 type->attributeWildcard = baseType->attributeWildcard; 14575 } 14576 } else { 14577 /* 14578 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14579 * `complete wildcard`" 14580 * NOOP 14581 */ 14582 } 14583 } else { 14584 /* 14585 * SPEC {attribute wildcard} 14586 * (3.1) "If the <restriction> alternative is chosen, then the 14587 * `complete wildcard`;" 14588 * NOOP 14589 */ 14590 } 14591 14592 return (0); 14593 14594exit_failure: 14595 return(-1); 14596} 14597 14598/** 14599 * xmlSchemaTypeFinalContains: 14600 * @schema: the schema 14601 * @type: the type definition 14602 * @final: the final 14603 * 14604 * Evaluates if a type definition contains the given "final". 14605 * This does take "finalDefault" into account as well. 14606 * 14607 * Returns 1 if the type does containt the given "final", 14608 * 0 otherwise. 14609 */ 14610static int 14611xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14612{ 14613 if (type == NULL) 14614 return (0); 14615 if (type->flags & final) 14616 return (1); 14617 else 14618 return (0); 14619} 14620 14621/** 14622 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14623 * @type: the Union Simple Type 14624 * 14625 * Returns a list of member types of @type if existing, 14626 * returns NULL otherwise. 14627 */ 14628static xmlSchemaTypeLinkPtr 14629xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14630{ 14631 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14632 if (type->memberTypes != NULL) 14633 return (type->memberTypes); 14634 else 14635 type = type->baseType; 14636 } 14637 return (NULL); 14638} 14639 14640/** 14641 * xmlSchemaGetParticleTotalRangeMin: 14642 * @particle: the particle 14643 * 14644 * Schema Component Constraint: Effective Total Range 14645 * (all and sequence) + (choice) 14646 * 14647 * Returns the minimun Effective Total Range. 14648 */ 14649static int 14650xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14651{ 14652 if ((particle->children == NULL) || 14653 (particle->minOccurs == 0)) 14654 return (0); 14655 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14656 int min = -1, cur; 14657 xmlSchemaParticlePtr part = 14658 (xmlSchemaParticlePtr) particle->children->children; 14659 14660 if (part == NULL) 14661 return (0); 14662 while (part != NULL) { 14663 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14664 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14665 cur = part->minOccurs; 14666 else 14667 cur = xmlSchemaGetParticleTotalRangeMin(part); 14668 if (cur == 0) 14669 return (0); 14670 if ((min > cur) || (min == -1)) 14671 min = cur; 14672 part = (xmlSchemaParticlePtr) part->next; 14673 } 14674 return (particle->minOccurs * min); 14675 } else { 14676 /* <all> and <sequence> */ 14677 int sum = 0; 14678 xmlSchemaParticlePtr part = 14679 (xmlSchemaParticlePtr) particle->children->children; 14680 14681 if (part == NULL) 14682 return (0); 14683 do { 14684 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14685 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14686 sum += part->minOccurs; 14687 else 14688 sum += xmlSchemaGetParticleTotalRangeMin(part); 14689 part = (xmlSchemaParticlePtr) part->next; 14690 } while (part != NULL); 14691 return (particle->minOccurs * sum); 14692 } 14693} 14694 14695#if 0 14696/** 14697 * xmlSchemaGetParticleTotalRangeMax: 14698 * @particle: the particle 14699 * 14700 * Schema Component Constraint: Effective Total Range 14701 * (all and sequence) + (choice) 14702 * 14703 * Returns the maximum Effective Total Range. 14704 */ 14705static int 14706xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14707{ 14708 if ((particle->children == NULL) || 14709 (particle->children->children == NULL)) 14710 return (0); 14711 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14712 int max = -1, cur; 14713 xmlSchemaParticlePtr part = 14714 (xmlSchemaParticlePtr) particle->children->children; 14715 14716 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14717 if (part->children == NULL) 14718 continue; 14719 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14720 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14721 cur = part->maxOccurs; 14722 else 14723 cur = xmlSchemaGetParticleTotalRangeMax(part); 14724 if (cur == UNBOUNDED) 14725 return (UNBOUNDED); 14726 if ((max < cur) || (max == -1)) 14727 max = cur; 14728 } 14729 /* TODO: Handle overflows? */ 14730 return (particle->maxOccurs * max); 14731 } else { 14732 /* <all> and <sequence> */ 14733 int sum = 0, cur; 14734 xmlSchemaParticlePtr part = 14735 (xmlSchemaParticlePtr) particle->children->children; 14736 14737 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14738 if (part->children == NULL) 14739 continue; 14740 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14741 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14742 cur = part->maxOccurs; 14743 else 14744 cur = xmlSchemaGetParticleTotalRangeMax(part); 14745 if (cur == UNBOUNDED) 14746 return (UNBOUNDED); 14747 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14748 return (UNBOUNDED); 14749 sum += cur; 14750 } 14751 /* TODO: Handle overflows? */ 14752 return (particle->maxOccurs * sum); 14753 } 14754} 14755#endif 14756 14757/** 14758 * xmlSchemaIsParticleEmptiable: 14759 * @particle: the particle 14760 * 14761 * Schema Component Constraint: Particle Emptiable 14762 * Checks whether the given particle is emptiable. 14763 * 14764 * Returns 1 if emptiable, 0 otherwise. 14765 */ 14766static int 14767xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14768{ 14769 /* 14770 * SPEC (1) "Its {min occurs} is 0." 14771 */ 14772 if ((particle == NULL) || (particle->minOccurs == 0) || 14773 (particle->children == NULL)) 14774 return (1); 14775 /* 14776 * SPEC (2) "Its {term} is a group and the minimum part of the 14777 * effective total range of that group, [...] is 0." 14778 */ 14779 if (WXS_IS_MODEL_GROUP(particle->children)) { 14780 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14781 return (1); 14782 } 14783 return (0); 14784} 14785 14786/** 14787 * xmlSchemaCheckCOSSTDerivedOK: 14788 * @actxt: a context 14789 * @type: the derived simple type definition 14790 * @baseType: the base type definition 14791 * @subset: the subset of ('restriction', ect.) 14792 * 14793 * Schema Component Constraint: 14794 * Type Derivation OK (Simple) (cos-st-derived-OK) 14795 * 14796 * Checks wheter @type can be validly 14797 * derived from @baseType. 14798 * 14799 * Returns 0 on success, an positive error code otherwise. 14800 */ 14801static int 14802xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14803 xmlSchemaTypePtr type, 14804 xmlSchemaTypePtr baseType, 14805 int subset) 14806{ 14807 /* 14808 * 1 They are the same type definition. 14809 * TODO: The identy check might have to be more complex than this. 14810 */ 14811 if (type == baseType) 14812 return (0); 14813 /* 14814 * 2.1 restriction is not in the subset, or in the {final} 14815 * of its own {base type definition}; 14816 * 14817 * NOTE that this will be used also via "xsi:type". 14818 * 14819 * TODO: Revise this, it looks strange. How can the "type" 14820 * not be fixed or *in* fixing? 14821 */ 14822 if (WXS_IS_TYPE_NOT_FIXED(type)) 14823 if (xmlSchemaTypeFixup(type, actxt) == -1) 14824 return(-1); 14825 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14826 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14827 return(-1); 14828 if ((subset & SUBSET_RESTRICTION) || 14829 (xmlSchemaTypeFinalContains(type->baseType, 14830 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14831 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14832 } 14833 /* 2.2 */ 14834 if (type->baseType == baseType) { 14835 /* 14836 * 2.2.1 D's `base type definition` is B. 14837 */ 14838 return (0); 14839 } 14840 /* 14841 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14842 * and is validly derived from B given the subset, as defined by this 14843 * constraint. 14844 */ 14845 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14846 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14847 baseType, subset) == 0)) { 14848 return (0); 14849 } 14850 /* 14851 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14852 * definition`. 14853 */ 14854 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14855 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14856 return (0); 14857 } 14858 /* 14859 * 2.2.4 B's {variety} is union and D is validly derived from a type 14860 * definition in B's {member type definitions} given the subset, as 14861 * defined by this constraint. 14862 * 14863 * NOTE: This seems not to involve built-in types, since there is no 14864 * built-in Union Simple Type. 14865 */ 14866 if (WXS_IS_UNION(baseType)) { 14867 xmlSchemaTypeLinkPtr cur; 14868 14869 cur = baseType->memberTypes; 14870 while (cur != NULL) { 14871 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14872 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14873 return(-1); 14874 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14875 type, cur->type, subset) == 0) 14876 { 14877 /* 14878 * It just has to be validly derived from at least one 14879 * member-type. 14880 */ 14881 return (0); 14882 } 14883 cur = cur->next; 14884 } 14885 } 14886 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14887} 14888 14889/** 14890 * xmlSchemaCheckTypeDefCircularInternal: 14891 * @pctxt: the schema parser context 14892 * @ctxtType: the type definition 14893 * @ancestor: an ancestor of @ctxtType 14894 * 14895 * Checks st-props-correct (2) + ct-props-correct (3). 14896 * Circular type definitions are not allowed. 14897 * 14898 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14899 * circular, 0 otherwise. 14900 */ 14901static int 14902xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14903 xmlSchemaTypePtr ctxtType, 14904 xmlSchemaTypePtr ancestor) 14905{ 14906 int ret; 14907 14908 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14909 return (0); 14910 14911 if (ctxtType == ancestor) { 14912 xmlSchemaPCustomErr(pctxt, 14913 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14914 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14915 "The definition is circular", NULL); 14916 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14917 } 14918 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14919 /* 14920 * Avoid inifinite recursion on circular types not yet checked. 14921 */ 14922 return (0); 14923 } 14924 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14925 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14926 ancestor->baseType); 14927 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14928 return (ret); 14929} 14930 14931/** 14932 * xmlSchemaCheckTypeDefCircular: 14933 * @item: the complex/simple type definition 14934 * @ctxt: the parser context 14935 * @name: the name 14936 * 14937 * Checks for circular type definitions. 14938 */ 14939static void 14940xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14941 xmlSchemaParserCtxtPtr ctxt) 14942{ 14943 if ((item == NULL) || 14944 (item->type == XML_SCHEMA_TYPE_BASIC) || 14945 (item->baseType == NULL)) 14946 return; 14947 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14948 item->baseType); 14949} 14950 14951/* 14952* Simple Type Definition Representation OK (src-simple-type) 4 14953* 14954* "4 Circular union type definition is disallowed. That is, if the 14955* <union> alternative is chosen, there must not be any entries in the 14956* memberTypes [attribute] at any depth which resolve to the component 14957* corresponding to the <simpleType>." 14958* 14959* Note that this should work on the *representation* of a component, 14960* thus assumes any union types in the member types not being yet 14961* substituted. At this stage we need the variety of the types 14962* to be already computed. 14963*/ 14964static int 14965xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14966 xmlSchemaTypePtr ctxType, 14967 xmlSchemaTypeLinkPtr members) 14968{ 14969 xmlSchemaTypeLinkPtr member; 14970 xmlSchemaTypePtr memberType; 14971 14972 member = members; 14973 while (member != NULL) { 14974 memberType = member->type; 14975 while ((memberType != NULL) && 14976 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14977 if (memberType == ctxType) { 14978 xmlSchemaPCustomErr(pctxt, 14979 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14980 WXS_BASIC_CAST ctxType, NULL, 14981 "The union type definition is circular", NULL); 14982 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14983 } 14984 if ((WXS_IS_UNION(memberType)) && 14985 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14986 { 14987 int res; 14988 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 14989 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 14990 ctxType, 14991 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 14992 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 14993 if (res != 0) 14994 return(res); 14995 } 14996 memberType = memberType->baseType; 14997 } 14998 member = member->next; 14999 } 15000 return(0); 15001} 15002 15003static int 15004xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15005 xmlSchemaTypePtr type) 15006{ 15007 if (! WXS_IS_UNION(type)) 15008 return(0); 15009 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15010 type->memberTypes)); 15011} 15012 15013/** 15014 * xmlSchemaResolveTypeReferences: 15015 * @item: the complex/simple type definition 15016 * @ctxt: the parser context 15017 * @name: the name 15018 * 15019 * Resolvese type definition references 15020 */ 15021static void 15022xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15023 xmlSchemaParserCtxtPtr ctxt) 15024{ 15025 if (typeDef == NULL) 15026 return; 15027 15028 /* 15029 * Resolve the base type. 15030 */ 15031 if (typeDef->baseType == NULL) { 15032 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15033 typeDef->base, typeDef->baseNs); 15034 if (typeDef->baseType == NULL) { 15035 xmlSchemaPResCompAttrErr(ctxt, 15036 XML_SCHEMAP_SRC_RESOLVE, 15037 WXS_BASIC_CAST typeDef, typeDef->node, 15038 "base", typeDef->base, typeDef->baseNs, 15039 XML_SCHEMA_TYPE_SIMPLE, NULL); 15040 return; 15041 } 15042 } 15043 if (WXS_IS_SIMPLE(typeDef)) { 15044 if (WXS_IS_UNION(typeDef)) { 15045 /* 15046 * Resolve the memberTypes. 15047 */ 15048 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15049 return; 15050 } else if (WXS_IS_LIST(typeDef)) { 15051 /* 15052 * Resolve the itemType. 15053 */ 15054 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15055 15056 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15057 typeDef->base, typeDef->baseNs); 15058 15059 if ((typeDef->subtypes == NULL) || 15060 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15061 { 15062 typeDef->subtypes = NULL; 15063 xmlSchemaPResCompAttrErr(ctxt, 15064 XML_SCHEMAP_SRC_RESOLVE, 15065 WXS_BASIC_CAST typeDef, typeDef->node, 15066 "itemType", typeDef->base, typeDef->baseNs, 15067 XML_SCHEMA_TYPE_SIMPLE, NULL); 15068 } 15069 } 15070 return; 15071 } 15072 } 15073 /* 15074 * The ball of letters below means, that if we have a particle 15075 * which has a QName-helper component as its {term}, we want 15076 * to resolve it... 15077 */ 15078 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15079 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15080 XML_SCHEMA_TYPE_PARTICLE) && 15081 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15082 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15083 XML_SCHEMA_EXTRA_QNAMEREF)) 15084 { 15085 xmlSchemaQNameRefPtr ref = 15086 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15087 xmlSchemaModelGroupDefPtr groupDef; 15088 15089 /* 15090 * URGENT TODO: Test this. 15091 */ 15092 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15093 /* 15094 * Resolve the MG definition reference. 15095 */ 15096 groupDef = 15097 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15098 ref->itemType, ref->name, ref->targetNamespace); 15099 if (groupDef == NULL) { 15100 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15101 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15102 "ref", ref->name, ref->targetNamespace, ref->itemType, 15103 NULL); 15104 /* Remove the particle. */ 15105 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15106 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15107 /* Remove the particle. */ 15108 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15109 else { 15110 /* 15111 * Assign the MG definition's {model group} to the 15112 * particle's {term}. 15113 */ 15114 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15115 15116 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15117 /* 15118 * SPEC cos-all-limited (1.2) 15119 * "1.2 the {term} property of a particle with 15120 * {max occurs}=1 which is part of a pair which constitutes 15121 * the {content type} of a complex type definition." 15122 */ 15123 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15124 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15125 /* TODO: error code */ 15126 XML_SCHEMAP_COS_ALL_LIMITED, 15127 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15128 "The particle's {max occurs} must be 1, since the " 15129 "reference resolves to an 'all' model group", 15130 NULL, NULL); 15131 } 15132 } 15133 } 15134 } 15135} 15136 15137 15138 15139/** 15140 * xmlSchemaCheckSTPropsCorrect: 15141 * @ctxt: the schema parser context 15142 * @type: the simple type definition 15143 * 15144 * Checks st-props-correct. 15145 * 15146 * Returns 0 if the properties are correct, 15147 * if not, a positive error code and -1 on internal 15148 * errors. 15149 */ 15150static int 15151xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15152 xmlSchemaTypePtr type) 15153{ 15154 xmlSchemaTypePtr baseType = type->baseType; 15155 xmlChar *str = NULL; 15156 15157 /* STATE: error funcs converted. */ 15158 /* 15159 * Schema Component Constraint: Simple Type Definition Properties Correct 15160 * 15161 * NOTE: This is somehow redundant, since we actually built a simple type 15162 * to have all the needed information; this acts as an self test. 15163 */ 15164 /* Base type: If the datatype has been `derived` by `restriction` 15165 * then the Simple Type Definition component from which it is `derived`, 15166 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15167 */ 15168 if (baseType == NULL) { 15169 /* 15170 * TODO: Think about: "modulo the impact of Missing 15171 * Sub-components ($5.3)." 15172 */ 15173 xmlSchemaPCustomErr(ctxt, 15174 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15175 WXS_BASIC_CAST type, NULL, 15176 "No base type existent", NULL); 15177 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15178 15179 } 15180 if (! WXS_IS_SIMPLE(baseType)) { 15181 xmlSchemaPCustomErr(ctxt, 15182 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15183 WXS_BASIC_CAST type, NULL, 15184 "The base type '%s' is not a simple type", 15185 xmlSchemaGetComponentQName(&str, baseType)); 15186 FREE_AND_NULL(str) 15187 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15188 } 15189 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15190 (WXS_IS_RESTRICTION(type) == 0) && 15191 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15192 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15193 xmlSchemaPCustomErr(ctxt, 15194 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15195 WXS_BASIC_CAST type, NULL, 15196 "A type, derived by list or union, must have " 15197 "the simple ur-type definition as base type, not '%s'", 15198 xmlSchemaGetComponentQName(&str, baseType)); 15199 FREE_AND_NULL(str) 15200 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15201 } 15202 /* 15203 * Variety: One of {atomic, list, union}. 15204 */ 15205 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15206 (! WXS_IS_LIST(type))) { 15207 xmlSchemaPCustomErr(ctxt, 15208 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15209 WXS_BASIC_CAST type, NULL, 15210 "The variety is absent", NULL); 15211 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15212 } 15213 /* TODO: Finish this. Hmm, is this finished? */ 15214 15215 /* 15216 * 3 The {final} of the {base type definition} must not contain restriction. 15217 */ 15218 if (xmlSchemaTypeFinalContains(baseType, 15219 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15220 xmlSchemaPCustomErr(ctxt, 15221 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15222 WXS_BASIC_CAST type, NULL, 15223 "The 'final' of its base type '%s' must not contain " 15224 "'restriction'", 15225 xmlSchemaGetComponentQName(&str, baseType)); 15226 FREE_AND_NULL(str) 15227 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15228 } 15229 15230 /* 15231 * 2 All simple type definitions must be derived ultimately from the `simple 15232 * ur-type definition` (so circular definitions are disallowed). That is, it 15233 * must be possible to reach a built-in primitive datatype or the `simple 15234 * ur-type definition` by repeatedly following the {base type definition}. 15235 * 15236 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15237 */ 15238 return (0); 15239} 15240 15241/** 15242 * xmlSchemaCheckCOSSTRestricts: 15243 * @ctxt: the schema parser context 15244 * @type: the simple type definition 15245 * 15246 * Schema Component Constraint: 15247 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15248 15249 * Checks if the given @type (simpleType) is derived validly by restriction. 15250 * STATUS: 15251 * 15252 * Returns -1 on internal errors, 0 if the type is validly derived, 15253 * a positive error code otherwise. 15254 */ 15255static int 15256xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15257 xmlSchemaTypePtr type) 15258{ 15259 xmlChar *str = NULL; 15260 15261 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15262 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15263 "given type is not a user-derived simpleType"); 15264 return (-1); 15265 } 15266 15267 if (WXS_IS_ATOMIC(type)) { 15268 xmlSchemaTypePtr primitive; 15269 /* 15270 * 1.1 The {base type definition} must be an atomic simple 15271 * type definition or a built-in primitive datatype. 15272 */ 15273 if (! WXS_IS_ATOMIC(type->baseType)) { 15274 xmlSchemaPCustomErr(pctxt, 15275 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15276 WXS_BASIC_CAST type, NULL, 15277 "The base type '%s' is not an atomic simple type", 15278 xmlSchemaGetComponentQName(&str, type->baseType)); 15279 FREE_AND_NULL(str) 15280 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15281 } 15282 /* 1.2 The {final} of the {base type definition} must not contain 15283 * restriction. 15284 */ 15285 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15286 if (xmlSchemaTypeFinalContains(type->baseType, 15287 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15288 xmlSchemaPCustomErr(pctxt, 15289 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15290 WXS_BASIC_CAST type, NULL, 15291 "The final of its base type '%s' must not contain 'restriction'", 15292 xmlSchemaGetComponentQName(&str, type->baseType)); 15293 FREE_AND_NULL(str) 15294 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15295 } 15296 15297 /* 15298 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15299 * type definition}, as specified in the appropriate subsection of 3.2 15300 * Primitive datatypes. 15301 */ 15302 if (type->facets != NULL) { 15303 xmlSchemaFacetPtr facet; 15304 int ok = 1; 15305 15306 primitive = xmlSchemaGetPrimitiveType(type); 15307 if (primitive == NULL) { 15308 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15309 "failed to get primitive type"); 15310 return (-1); 15311 } 15312 facet = type->facets; 15313 do { 15314 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15315 ok = 0; 15316 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15317 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15318 type, primitive, facet); 15319 } 15320 facet = facet->next; 15321 } while (facet != NULL); 15322 if (ok == 0) 15323 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15324 } 15325 /* 15326 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15327 * of the {base type definition} (call this BF),then the DF's {value} 15328 * must be a valid restriction of BF's {value} as defined in 15329 * [XML Schemas: Datatypes]." 15330 * 15331 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15332 * xmlSchemaDeriveAndValidateFacets() 15333 */ 15334 } else if (WXS_IS_LIST(type)) { 15335 xmlSchemaTypePtr itemType = NULL; 15336 15337 itemType = type->subtypes; 15338 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15339 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15340 "failed to evaluate the item type"); 15341 return (-1); 15342 } 15343 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15344 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15345 /* 15346 * 2.1 The {item type definition} must have a {variety} of atomic or 15347 * union (in which case all the {member type definitions} 15348 * must be atomic). 15349 */ 15350 if ((! WXS_IS_ATOMIC(itemType)) && 15351 (! WXS_IS_UNION(itemType))) { 15352 xmlSchemaPCustomErr(pctxt, 15353 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15354 WXS_BASIC_CAST type, NULL, 15355 "The item type '%s' does not have a variety of atomic or union", 15356 xmlSchemaGetComponentQName(&str, itemType)); 15357 FREE_AND_NULL(str) 15358 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15359 } else if (WXS_IS_UNION(itemType)) { 15360 xmlSchemaTypeLinkPtr member; 15361 15362 member = itemType->memberTypes; 15363 while (member != NULL) { 15364 if (! WXS_IS_ATOMIC(member->type)) { 15365 xmlSchemaPCustomErr(pctxt, 15366 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15367 WXS_BASIC_CAST type, NULL, 15368 "The item type is a union type, but the " 15369 "member type '%s' of this item type is not atomic", 15370 xmlSchemaGetComponentQName(&str, member->type)); 15371 FREE_AND_NULL(str) 15372 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15373 } 15374 member = member->next; 15375 } 15376 } 15377 15378 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15379 xmlSchemaFacetPtr facet; 15380 /* 15381 * This is the case if we have: <simpleType><list .. 15382 */ 15383 /* 15384 * 2.3.1 15385 * 2.3.1.1 The {final} of the {item type definition} must not 15386 * contain list. 15387 */ 15388 if (xmlSchemaTypeFinalContains(itemType, 15389 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15390 xmlSchemaPCustomErr(pctxt, 15391 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15392 WXS_BASIC_CAST type, NULL, 15393 "The final of its item type '%s' must not contain 'list'", 15394 xmlSchemaGetComponentQName(&str, itemType)); 15395 FREE_AND_NULL(str) 15396 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15397 } 15398 /* 15399 * 2.3.1.2 The {facets} must only contain the whiteSpace 15400 * facet component. 15401 * OPTIMIZE TODO: the S4S already disallows any facet 15402 * to be specified. 15403 */ 15404 if (type->facets != NULL) { 15405 facet = type->facets; 15406 do { 15407 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15408 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15409 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15410 type, facet); 15411 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15412 } 15413 facet = facet->next; 15414 } while (facet != NULL); 15415 } 15416 /* 15417 * MAYBE TODO: (Hmm, not really) Datatypes states: 15418 * A `list` datatype can be `derived` from an `atomic` datatype 15419 * whose `lexical space` allows space (such as string or anyURI)or 15420 * a `union` datatype any of whose {member type definitions}'s 15421 * `lexical space` allows space. 15422 */ 15423 } else { 15424 /* 15425 * This is the case if we have: <simpleType><restriction ... 15426 * I.e. the variety of "list" is inherited. 15427 */ 15428 /* 15429 * 2.3.2 15430 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15431 */ 15432 if (! WXS_IS_LIST(type->baseType)) { 15433 xmlSchemaPCustomErr(pctxt, 15434 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15435 WXS_BASIC_CAST type, NULL, 15436 "The base type '%s' must be a list type", 15437 xmlSchemaGetComponentQName(&str, type->baseType)); 15438 FREE_AND_NULL(str) 15439 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15440 } 15441 /* 15442 * 2.3.2.2 The {final} of the {base type definition} must not 15443 * contain restriction. 15444 */ 15445 if (xmlSchemaTypeFinalContains(type->baseType, 15446 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15447 xmlSchemaPCustomErr(pctxt, 15448 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15449 WXS_BASIC_CAST type, NULL, 15450 "The 'final' of the base type '%s' must not contain 'restriction'", 15451 xmlSchemaGetComponentQName(&str, type->baseType)); 15452 FREE_AND_NULL(str) 15453 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15454 } 15455 /* 15456 * 2.3.2.3 The {item type definition} must be validly derived 15457 * from the {base type definition}'s {item type definition} given 15458 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15459 */ 15460 { 15461 xmlSchemaTypePtr baseItemType; 15462 15463 baseItemType = type->baseType->subtypes; 15464 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15465 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15466 "failed to eval the item type of a base type"); 15467 return (-1); 15468 } 15469 if ((itemType != baseItemType) && 15470 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15471 baseItemType, 0) != 0)) { 15472 xmlChar *strBIT = NULL, *strBT = NULL; 15473 xmlSchemaPCustomErrExt(pctxt, 15474 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15475 WXS_BASIC_CAST type, NULL, 15476 "The item type '%s' is not validly derived from " 15477 "the item type '%s' of the base type '%s'", 15478 xmlSchemaGetComponentQName(&str, itemType), 15479 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15480 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15481 15482 FREE_AND_NULL(str) 15483 FREE_AND_NULL(strBIT) 15484 FREE_AND_NULL(strBT) 15485 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15486 } 15487 } 15488 15489 if (type->facets != NULL) { 15490 xmlSchemaFacetPtr facet; 15491 int ok = 1; 15492 /* 15493 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15494 * and enumeration facet components are allowed among the {facets}. 15495 */ 15496 facet = type->facets; 15497 do { 15498 switch (facet->type) { 15499 case XML_SCHEMA_FACET_LENGTH: 15500 case XML_SCHEMA_FACET_MINLENGTH: 15501 case XML_SCHEMA_FACET_MAXLENGTH: 15502 case XML_SCHEMA_FACET_WHITESPACE: 15503 /* 15504 * TODO: 2.5.1.2 List datatypes 15505 * The value of `whiteSpace` is fixed to the value collapse. 15506 */ 15507 case XML_SCHEMA_FACET_PATTERN: 15508 case XML_SCHEMA_FACET_ENUMERATION: 15509 break; 15510 default: { 15511 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15512 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15513 type, facet); 15514 /* 15515 * We could return, but it's nicer to report all 15516 * invalid facets. 15517 */ 15518 ok = 0; 15519 } 15520 } 15521 facet = facet->next; 15522 } while (facet != NULL); 15523 if (ok == 0) 15524 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15525 /* 15526 * SPEC (2.3.2.5) (same as 1.3.2) 15527 * 15528 * NOTE (2.3.2.5) This is currently done in 15529 * xmlSchemaDeriveAndValidateFacets() 15530 */ 15531 } 15532 } 15533 } else if (WXS_IS_UNION(type)) { 15534 /* 15535 * 3.1 The {member type definitions} must all have {variety} of 15536 * atomic or list. 15537 */ 15538 xmlSchemaTypeLinkPtr member; 15539 15540 member = type->memberTypes; 15541 while (member != NULL) { 15542 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15543 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15544 15545 if ((! WXS_IS_ATOMIC(member->type)) && 15546 (! WXS_IS_LIST(member->type))) { 15547 xmlSchemaPCustomErr(pctxt, 15548 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15549 WXS_BASIC_CAST type, NULL, 15550 "The member type '%s' is neither an atomic, nor a list type", 15551 xmlSchemaGetComponentQName(&str, member->type)); 15552 FREE_AND_NULL(str) 15553 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15554 } 15555 member = member->next; 15556 } 15557 /* 15558 * 3.3.1 If the {base type definition} is the `simple ur-type 15559 * definition` 15560 */ 15561 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15562 /* 15563 * 3.3.1.1 All of the {member type definitions} must have a 15564 * {final} which does not contain union. 15565 */ 15566 member = type->memberTypes; 15567 while (member != NULL) { 15568 if (xmlSchemaTypeFinalContains(member->type, 15569 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15570 xmlSchemaPCustomErr(pctxt, 15571 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15572 WXS_BASIC_CAST type, NULL, 15573 "The 'final' of member type '%s' contains 'union'", 15574 xmlSchemaGetComponentQName(&str, member->type)); 15575 FREE_AND_NULL(str) 15576 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15577 } 15578 member = member->next; 15579 } 15580 /* 15581 * 3.3.1.2 The {facets} must be empty. 15582 */ 15583 if (type->facetSet != NULL) { 15584 xmlSchemaPCustomErr(pctxt, 15585 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15586 WXS_BASIC_CAST type, NULL, 15587 "No facets allowed", NULL); 15588 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15589 } 15590 } else { 15591 /* 15592 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15593 * I.e. the variety of "list" is inherited. 15594 */ 15595 if (! WXS_IS_UNION(type->baseType)) { 15596 xmlSchemaPCustomErr(pctxt, 15597 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15598 WXS_BASIC_CAST type, NULL, 15599 "The base type '%s' is not a union type", 15600 xmlSchemaGetComponentQName(&str, type->baseType)); 15601 FREE_AND_NULL(str) 15602 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15603 } 15604 /* 15605 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15606 */ 15607 if (xmlSchemaTypeFinalContains(type->baseType, 15608 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15609 xmlSchemaPCustomErr(pctxt, 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15611 WXS_BASIC_CAST type, NULL, 15612 "The 'final' of its base type '%s' must not contain 'restriction'", 15613 xmlSchemaGetComponentQName(&str, type->baseType)); 15614 FREE_AND_NULL(str) 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15616 } 15617 /* 15618 * 3.3.2.3 The {member type definitions}, in order, must be validly 15619 * derived from the corresponding type definitions in the {base 15620 * type definition}'s {member type definitions} given the empty set, 15621 * as defined in Type Derivation OK (Simple) ($3.14.6). 15622 */ 15623 { 15624 xmlSchemaTypeLinkPtr baseMember; 15625 15626 /* 15627 * OPTIMIZE: if the type is restricting, it has no local defined 15628 * member types and inherits the member types of the base type; 15629 * thus a check for equality can be skipped. 15630 */ 15631 /* 15632 * Even worse: I cannot see a scenario where a restricting 15633 * union simple type can have other member types as the member 15634 * types of it's base type. This check seems not necessary with 15635 * respect to the derivation process in libxml2. 15636 * But necessary if constructing types with an API. 15637 */ 15638 if (type->memberTypes != NULL) { 15639 member = type->memberTypes; 15640 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15641 if ((member == NULL) && (baseMember != NULL)) { 15642 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15643 "different number of member types in base"); 15644 } 15645 while (member != NULL) { 15646 if (baseMember == NULL) { 15647 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15648 "different number of member types in base"); 15649 } else if ((member->type != baseMember->type) && 15650 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15651 member->type, baseMember->type, 0) != 0)) { 15652 xmlChar *strBMT = NULL, *strBT = NULL; 15653 15654 xmlSchemaPCustomErrExt(pctxt, 15655 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15656 WXS_BASIC_CAST type, NULL, 15657 "The member type %s is not validly " 15658 "derived from its corresponding member " 15659 "type %s of the base type %s", 15660 xmlSchemaGetComponentQName(&str, member->type), 15661 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15662 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15663 FREE_AND_NULL(str) 15664 FREE_AND_NULL(strBMT) 15665 FREE_AND_NULL(strBT) 15666 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15667 } 15668 member = member->next; 15669 if (baseMember != NULL) 15670 baseMember = baseMember->next; 15671 } 15672 } 15673 } 15674 /* 15675 * 3.3.2.4 Only pattern and enumeration facet components are 15676 * allowed among the {facets}. 15677 */ 15678 if (type->facets != NULL) { 15679 xmlSchemaFacetPtr facet; 15680 int ok = 1; 15681 15682 facet = type->facets; 15683 do { 15684 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15685 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15686 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15687 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15688 type, facet); 15689 ok = 0; 15690 } 15691 facet = facet->next; 15692 } while (facet != NULL); 15693 if (ok == 0) 15694 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15695 15696 } 15697 /* 15698 * SPEC (3.3.2.5) (same as 1.3.2) 15699 * 15700 * NOTE (3.3.2.5) This is currently done in 15701 * xmlSchemaDeriveAndValidateFacets() 15702 */ 15703 } 15704 } 15705 15706 return (0); 15707} 15708 15709/** 15710 * xmlSchemaCheckSRCSimpleType: 15711 * @ctxt: the schema parser context 15712 * @type: the simple type definition 15713 * 15714 * Checks crc-simple-type constraints. 15715 * 15716 * Returns 0 if the constraints are satisfied, 15717 * if not a positive error code and -1 on internal 15718 * errors. 15719 */ 15720#if 0 15721static int 15722xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15723 xmlSchemaTypePtr type) 15724{ 15725 /* 15726 * src-simple-type.1 The corresponding simple type definition, if any, 15727 * must satisfy the conditions set out in Constraints on Simple Type 15728 * Definition Schema Components ($3.14.6). 15729 */ 15730 if (WXS_IS_RESTRICTION(type)) { 15731 /* 15732 * src-simple-type.2 "If the <restriction> alternative is chosen, 15733 * either it must have a base [attribute] or a <simpleType> among its 15734 * [children], but not both." 15735 * NOTE: This is checked in the parse function of <restriction>. 15736 */ 15737 /* 15738 * 15739 */ 15740 } else if (WXS_IS_LIST(type)) { 15741 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15742 * an itemType [attribute] or a <simpleType> among its [children], 15743 * but not both." 15744 * 15745 * NOTE: This is checked in the parse function of <list>. 15746 */ 15747 } else if (WXS_IS_UNION(type)) { 15748 /* 15749 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15750 */ 15751 } 15752 return (0); 15753} 15754#endif 15755 15756static int 15757xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15758{ 15759 if (ctxt->vctxt == NULL) { 15760 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15761 if (ctxt->vctxt == NULL) { 15762 xmlSchemaPErr(ctxt, NULL, 15763 XML_SCHEMAP_INTERNAL, 15764 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15765 "failed to create a temp. validation context.\n", 15766 NULL, NULL); 15767 return (-1); 15768 } 15769 /* TODO: Pass user data. */ 15770 xmlSchemaSetValidErrors(ctxt->vctxt, 15771 ctxt->error, ctxt->warning, ctxt->errCtxt); 15772 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15773 ctxt->serror, ctxt->errCtxt); 15774 } 15775 return (0); 15776} 15777 15778static int 15779xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15780 xmlNodePtr node, 15781 xmlSchemaTypePtr type, 15782 const xmlChar *value, 15783 xmlSchemaValPtr *retVal, 15784 int fireErrors, 15785 int normalize, 15786 int isNormalized); 15787 15788/** 15789 * xmlSchemaParseCheckCOSValidDefault: 15790 * @pctxt: the schema parser context 15791 * @type: the simple type definition 15792 * @value: the default value 15793 * @node: an optional node (the holder of the value) 15794 * 15795 * Schema Component Constraint: Element Default Valid (Immediate) 15796 * (cos-valid-default) 15797 * This will be used by the parser only. For the validator there's 15798 * an other version. 15799 * 15800 * Returns 0 if the constraints are satisfied, 15801 * if not, a positive error code and -1 on internal 15802 * errors. 15803 */ 15804static int 15805xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15806 xmlNodePtr node, 15807 xmlSchemaTypePtr type, 15808 const xmlChar *value, 15809 xmlSchemaValPtr *val) 15810{ 15811 int ret = 0; 15812 15813 /* 15814 * cos-valid-default: 15815 * Schema Component Constraint: Element Default Valid (Immediate) 15816 * For a string to be a valid default with respect to a type 15817 * definition the appropriate case among the following must be true: 15818 */ 15819 if WXS_IS_COMPLEX(type) { 15820 /* 15821 * Complex type. 15822 * 15823 * SPEC (2.1) "its {content type} must be a simple type definition 15824 * or mixed." 15825 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15826 * type}'s particle must be `emptiable` as defined by 15827 * Particle Emptiable ($3.9.6)." 15828 */ 15829 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15830 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15831 /* NOTE that this covers (2.2.2) as well. */ 15832 xmlSchemaPCustomErr(pctxt, 15833 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15834 WXS_BASIC_CAST type, type->node, 15835 "For a string to be a valid default, the type definition " 15836 "must be a simple type or a complex type with mixed content " 15837 "and a particle emptiable", NULL); 15838 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15839 } 15840 } 15841 /* 15842 * 1 If the type definition is a simple type definition, then the string 15843 * must be `valid` with respect to that definition as defined by String 15844 * Valid ($3.14.4). 15845 * 15846 * AND 15847 * 15848 * 2.2.1 If the {content type} is a simple type definition, then the 15849 * string must be `valid` with respect to that simple type definition 15850 * as defined by String Valid ($3.14.4). 15851 */ 15852 if (WXS_IS_SIMPLE(type)) 15853 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15854 type, value, val, 1, 1, 0); 15855 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15856 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15857 type->contentTypeDef, value, val, 1, 1, 0); 15858 else 15859 return (ret); 15860 15861 if (ret < 0) { 15862 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15863 "calling xmlSchemaVCheckCVCSimpleType()"); 15864 } 15865 15866 return (ret); 15867} 15868 15869/** 15870 * xmlSchemaCheckCTPropsCorrect: 15871 * @ctxt: the schema parser context 15872 * @type: the complex type definition 15873 * 15874 *.(4.6) Constraints on Complex Type Definition Schema Components 15875 * Schema Component Constraint: 15876 * Complex Type Definition Properties Correct (ct-props-correct) 15877 * STATUS: (seems) complete 15878 * 15879 * Returns 0 if the constraints are satisfied, a positive 15880 * error code if not and -1 if an internal error occured. 15881 */ 15882static int 15883xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15884 xmlSchemaTypePtr type) 15885{ 15886 /* 15887 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15888 * 15889 * SPEC (1) "The values of the properties of a complex type definition must 15890 * be as described in the property tableau in The Complex Type Definition 15891 * Schema Component ($3.4.1), modulo the impact of Missing 15892 * Sub-components ($5.3)." 15893 */ 15894 if ((type->baseType != NULL) && 15895 (WXS_IS_SIMPLE(type->baseType)) && 15896 (WXS_IS_EXTENSION(type) == 0)) { 15897 /* 15898 * SPEC (2) "If the {base type definition} is a simple type definition, 15899 * the {derivation method} must be extension." 15900 */ 15901 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15902 XML_SCHEMAP_SRC_CT_1, 15903 NULL, WXS_BASIC_CAST type, 15904 "If the base type is a simple type, the derivation method must be " 15905 "'extension'", NULL, NULL); 15906 return (XML_SCHEMAP_SRC_CT_1); 15907 } 15908 /* 15909 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15910 * definition`. That is, it must be possible to reach the `ur-type 15911 * definition` by repeatedly following the {base type definition}." 15912 * 15913 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15914 */ 15915 /* 15916 * NOTE that (4) and (5) need the following: 15917 * - attribute uses need to be already inherited (apply attr. prohibitions) 15918 * - attribute group references need to be expanded already 15919 * - simple types need to be typefixed already 15920 */ 15921 if (type->attrUses && 15922 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15923 { 15924 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15925 xmlSchemaAttributeUsePtr use, tmp; 15926 int i, j, hasId = 0; 15927 15928 for (i = uses->nbItems -1; i >= 0; i--) { 15929 use = uses->items[i]; 15930 15931 /* 15932 * SPEC ct-props-correct 15933 * (4) "Two distinct attribute declarations in the 15934 * {attribute uses} must not have identical {name}s and 15935 * {target namespace}s." 15936 */ 15937 if (i > 0) { 15938 for (j = i -1; j >= 0; j--) { 15939 tmp = uses->items[j]; 15940 if ((WXS_ATTRUSE_DECL_NAME(use) == 15941 WXS_ATTRUSE_DECL_NAME(tmp)) && 15942 (WXS_ATTRUSE_DECL_TNS(use) == 15943 WXS_ATTRUSE_DECL_TNS(tmp))) 15944 { 15945 xmlChar *str = NULL; 15946 15947 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15948 XML_SCHEMAP_AG_PROPS_CORRECT, 15949 NULL, WXS_BASIC_CAST type, 15950 "Duplicate %s", 15951 xmlSchemaGetComponentDesignation(&str, use), 15952 NULL); 15953 FREE_AND_NULL(str); 15954 /* 15955 * Remove the duplicate. 15956 */ 15957 if (xmlSchemaItemListRemove(uses, i) == -1) 15958 goto exit_failure; 15959 goto next_use; 15960 } 15961 } 15962 } 15963 /* 15964 * SPEC ct-props-correct 15965 * (5) "Two distinct attribute declarations in the 15966 * {attribute uses} must not have {type definition}s which 15967 * are or are derived from ID." 15968 */ 15969 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15970 if (xmlSchemaIsDerivedFromBuiltInType( 15971 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15972 { 15973 if (hasId) { 15974 xmlChar *str = NULL; 15975 15976 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15977 XML_SCHEMAP_AG_PROPS_CORRECT, 15978 NULL, WXS_BASIC_CAST type, 15979 "There must not exist more than one attribute " 15980 "declaration of type 'xs:ID' " 15981 "(or derived from 'xs:ID'). The %s violates this " 15982 "constraint", 15983 xmlSchemaGetComponentDesignation(&str, use), 15984 NULL); 15985 FREE_AND_NULL(str); 15986 if (xmlSchemaItemListRemove(uses, i) == -1) 15987 goto exit_failure; 15988 } 15989 15990 hasId = 1; 15991 } 15992 } 15993next_use: {} 15994 } 15995 } 15996 return (0); 15997exit_failure: 15998 return(-1); 15999} 16000 16001static int 16002xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16003 xmlSchemaTypePtr typeB) 16004{ 16005 /* 16006 * TODO: This should implement component-identity 16007 * in the future. 16008 */ 16009 if ((typeA == NULL) || (typeB == NULL)) 16010 return (0); 16011 return (typeA == typeB); 16012} 16013 16014/** 16015 * xmlSchemaCheckCOSCTDerivedOK: 16016 * @ctxt: the schema parser context 16017 * @type: the to-be derived complex type definition 16018 * @baseType: the base complex type definition 16019 * @set: the given set 16020 * 16021 * Schema Component Constraint: 16022 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16023 * 16024 * STATUS: completed 16025 * 16026 * Returns 0 if the constraints are satisfied, or 1 16027 * if not. 16028 */ 16029static int 16030xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16031 xmlSchemaTypePtr type, 16032 xmlSchemaTypePtr baseType, 16033 int set) 16034{ 16035 int equal = xmlSchemaAreEqualTypes(type, baseType); 16036 /* TODO: Error codes. */ 16037 /* 16038 * SPEC "For a complex type definition (call it D, for derived) 16039 * to be validly derived from a type definition (call this 16040 * B, for base) given a subset of {extension, restriction} 16041 * all of the following must be true:" 16042 */ 16043 if (! equal) { 16044 /* 16045 * SPEC (1) "If B and D are not the same type definition, then the 16046 * {derivation method} of D must not be in the subset." 16047 */ 16048 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16049 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16050 return (1); 16051 } else { 16052 /* 16053 * SPEC (2.1) "B and D must be the same type definition." 16054 */ 16055 return (0); 16056 } 16057 /* 16058 * SPEC (2.2) "B must be D's {base type definition}." 16059 */ 16060 if (type->baseType == baseType) 16061 return (0); 16062 /* 16063 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16064 * definition`." 16065 */ 16066 if (WXS_IS_ANYTYPE(type->baseType)) 16067 return (1); 16068 16069 if (WXS_IS_COMPLEX(type->baseType)) { 16070 /* 16071 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16072 * must be validly derived from B given the subset as defined by this 16073 * constraint." 16074 */ 16075 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16076 baseType, set)); 16077 } else { 16078 /* 16079 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16080 * must be validly derived from B given the subset as defined in Type 16081 * Derivation OK (Simple) ($3.14.6). 16082 */ 16083 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16084 baseType, set)); 16085 } 16086} 16087 16088/** 16089 * xmlSchemaCheckCOSDerivedOK: 16090 * @type: the derived simple type definition 16091 * @baseType: the base type definition 16092 * 16093 * Calls: 16094 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16095 * 16096 * Checks wheter @type can be validly derived from @baseType. 16097 * 16098 * Returns 0 on success, an positive error code otherwise. 16099 */ 16100static int 16101xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16102 xmlSchemaTypePtr type, 16103 xmlSchemaTypePtr baseType, 16104 int set) 16105{ 16106 if (WXS_IS_SIMPLE(type)) 16107 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16108 else 16109 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16110} 16111 16112/** 16113 * xmlSchemaCheckCOSCTExtends: 16114 * @ctxt: the schema parser context 16115 * @type: the complex type definition 16116 * 16117 * (3.4.6) Constraints on Complex Type Definition Schema Components 16118 * Schema Component Constraint: 16119 * Derivation Valid (Extension) (cos-ct-extends) 16120 * 16121 * STATUS: 16122 * missing: 16123 * (1.5) 16124 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16125 * 16126 * Returns 0 if the constraints are satisfied, a positive 16127 * error code if not and -1 if an internal error occured. 16128 */ 16129static int 16130xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16131 xmlSchemaTypePtr type) 16132{ 16133 xmlSchemaTypePtr base = type->baseType; 16134 /* 16135 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16136 * temporarily only. 16137 */ 16138 /* 16139 * SPEC (1) "If the {base type definition} is a complex type definition, 16140 * then all of the following must be true:" 16141 */ 16142 if (WXS_IS_COMPLEX(base)) { 16143 /* 16144 * SPEC (1.1) "The {final} of the {base type definition} must not 16145 * contain extension." 16146 */ 16147 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16148 xmlSchemaPCustomErr(ctxt, 16149 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16150 WXS_BASIC_CAST type, NULL, 16151 "The 'final' of the base type definition " 16152 "contains 'extension'", NULL); 16153 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16154 } 16155 16156 /* 16157 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16158 * since they are automatically satisfied through the 16159 * inheriting mechanism. 16160 * Note that even if redefining components, the inheriting mechanism 16161 * is used. 16162 */ 16163#if 0 16164 /* 16165 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16166 * uses} 16167 * of the complex type definition itself, that is, for every attribute 16168 * use in the {attribute uses} of the {base type definition}, there 16169 * must be an attribute use in the {attribute uses} of the complex 16170 * type definition itself whose {attribute declaration} has the same 16171 * {name}, {target namespace} and {type definition} as its attribute 16172 * declaration" 16173 */ 16174 if (base->attrUses != NULL) { 16175 int i, j, found; 16176 xmlSchemaAttributeUsePtr use, buse; 16177 16178 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16179 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16180 found = 0; 16181 if (type->attrUses != NULL) { 16182 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16183 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16184 { 16185 if ((WXS_ATTRUSE_DECL_NAME(use) == 16186 WXS_ATTRUSE_DECL_NAME(buse)) && 16187 (WXS_ATTRUSE_DECL_TNS(use) == 16188 WXS_ATTRUSE_DECL_TNS(buse)) && 16189 (WXS_ATTRUSE_TYPEDEF(use) == 16190 WXS_ATTRUSE_TYPEDEF(buse)) 16191 { 16192 found = 1; 16193 break; 16194 } 16195 } 16196 } 16197 if (! found) { 16198 xmlChar *str = NULL; 16199 16200 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16201 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16202 NULL, WXS_BASIC_CAST type, 16203 /* 16204 * TODO: The report does not indicate that also the 16205 * type needs to be the same. 16206 */ 16207 "This type is missing a matching correspondent " 16208 "for its {base type}'s %s in its {attribute uses}", 16209 xmlSchemaGetComponentDesignation(&str, 16210 buse->children), 16211 NULL); 16212 FREE_AND_NULL(str) 16213 } 16214 } 16215 } 16216 /* 16217 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16218 * definition must also have one, and the base type definition's 16219 * {attribute wildcard}'s {namespace constraint} must be a subset 16220 * of the complex type definition's {attribute wildcard}'s {namespace 16221 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16222 */ 16223 16224 /* 16225 * MAYBE TODO: Enable if ever needed. But this will be needed only 16226 * if created the type via a schema construction API. 16227 */ 16228 if (base->attributeWildcard != NULL) { 16229 if (type->attributeWilcard == NULL) { 16230 xmlChar *str = NULL; 16231 16232 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16233 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16234 NULL, type, 16235 "The base %s has an attribute wildcard, " 16236 "but this type is missing an attribute wildcard", 16237 xmlSchemaGetComponentDesignation(&str, base)); 16238 FREE_AND_NULL(str) 16239 16240 } else if (xmlSchemaCheckCOSNSSubset( 16241 base->attributeWildcard, type->attributeWildcard)) 16242 { 16243 xmlChar *str = NULL; 16244 16245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16246 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16247 NULL, type, 16248 "The attribute wildcard is not a valid " 16249 "superset of the one in the base %s", 16250 xmlSchemaGetComponentDesignation(&str, base)); 16251 FREE_AND_NULL(str) 16252 } 16253 } 16254#endif 16255 /* 16256 * SPEC (1.4) "One of the following must be true:" 16257 */ 16258 if ((type->contentTypeDef != NULL) && 16259 (type->contentTypeDef == base->contentTypeDef)) { 16260 /* 16261 * SPEC (1.4.1) "The {content type} of the {base type definition} 16262 * and the {content type} of the complex type definition itself 16263 * must be the same simple type definition" 16264 * PASS 16265 */ 16266 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16267 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16268 /* 16269 * SPEC (1.4.2) "The {content type} of both the {base type 16270 * definition} and the complex type definition itself must 16271 * be empty." 16272 * PASS 16273 */ 16274 } else { 16275 /* 16276 * SPEC (1.4.3) "All of the following must be true:" 16277 */ 16278 if (type->subtypes == NULL) { 16279 /* 16280 * SPEC 1.4.3.1 The {content type} of the complex type 16281 * definition itself must specify a particle. 16282 */ 16283 xmlSchemaPCustomErr(ctxt, 16284 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16285 WXS_BASIC_CAST type, NULL, 16286 "The content type must specify a particle", NULL); 16287 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16288 } 16289 /* 16290 * SPEC (1.4.3.2) "One of the following must be true:" 16291 */ 16292 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16293 /* 16294 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16295 * definition} must be empty. 16296 * PASS 16297 */ 16298 } else { 16299 /* 16300 * SPEC (1.4.3.2.2) "All of the following must be true:" 16301 */ 16302 if ((type->contentType != base->contentType) || 16303 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16304 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16305 /* 16306 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16307 * or both must be element-only." 16308 */ 16309 xmlSchemaPCustomErr(ctxt, 16310 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16311 WXS_BASIC_CAST type, NULL, 16312 "The content type of both, the type and its base " 16313 "type, must either 'mixed' or 'element-only'", NULL); 16314 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16315 } 16316 /* 16317 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16318 * complex type definition must be a `valid extension` 16319 * of the {base type definition}'s particle, as defined 16320 * in Particle Valid (Extension) ($3.9.6)." 16321 * 16322 * NOTE that we won't check "Particle Valid (Extension)", 16323 * since it is ensured by the derivation process in 16324 * xmlSchemaTypeFixup(). We need to implement this when heading 16325 * for a construction API 16326 * TODO: !! This is needed to be checked if redefining a type !! 16327 */ 16328 } 16329 /* 16330 * URGENT TODO (1.5) 16331 */ 16332 } 16333 } else { 16334 /* 16335 * SPEC (2) "If the {base type definition} is a simple type definition, 16336 * then all of the following must be true:" 16337 */ 16338 if (type->contentTypeDef != base) { 16339 /* 16340 * SPEC (2.1) "The {content type} must be the same simple type 16341 * definition." 16342 */ 16343 xmlSchemaPCustomErr(ctxt, 16344 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16345 WXS_BASIC_CAST type, NULL, 16346 "The content type must be the simple base type", NULL); 16347 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16348 } 16349 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16350 /* 16351 * SPEC (2.2) "The {final} of the {base type definition} must not 16352 * contain extension" 16353 * NOTE that this is the same as (1.1). 16354 */ 16355 xmlSchemaPCustomErr(ctxt, 16356 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16357 WXS_BASIC_CAST type, NULL, 16358 "The 'final' of the base type definition " 16359 "contains 'extension'", NULL); 16360 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16361 } 16362 } 16363 return (0); 16364} 16365 16366/** 16367 * xmlSchemaCheckDerivationOKRestriction: 16368 * @ctxt: the schema parser context 16369 * @type: the complex type definition 16370 * 16371 * (3.4.6) Constraints on Complex Type Definition Schema Components 16372 * Schema Component Constraint: 16373 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16374 * 16375 * STATUS: 16376 * missing: 16377 * (5.4.2) ??? 16378 * 16379 * ATTENTION: 16380 * In XML Schema 1.1 this will be: 16381 * Validation Rule: Checking complex type subsumption 16382 * 16383 * Returns 0 if the constraints are satisfied, a positive 16384 * error code if not and -1 if an internal error occured. 16385 */ 16386static int 16387xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16388 xmlSchemaTypePtr type) 16389{ 16390 xmlSchemaTypePtr base; 16391 16392 /* 16393 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16394 * temporarily only. 16395 */ 16396 base = type->baseType; 16397 if (! WXS_IS_COMPLEX(base)) { 16398 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16399 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16400 type->node, WXS_BASIC_CAST type, 16401 "The base type must be a complex type", NULL, NULL); 16402 return(ctxt->err); 16403 } 16404 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16405 /* 16406 * SPEC (1) "The {base type definition} must be a complex type 16407 * definition whose {final} does not contain restriction." 16408 */ 16409 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16410 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16411 type->node, WXS_BASIC_CAST type, 16412 "The 'final' of the base type definition " 16413 "contains 'restriction'", NULL, NULL); 16414 return (ctxt->err); 16415 } 16416 /* 16417 * SPEC (2), (3) and (4) 16418 * Those are handled in a separate function, since the 16419 * same constraints are needed for redefinition of 16420 * attribute groups as well. 16421 */ 16422 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16423 XML_SCHEMA_ACTION_DERIVE, 16424 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16425 type->attrUses, base->attrUses, 16426 type->attributeWildcard, 16427 base->attributeWildcard) == -1) 16428 { 16429 return(-1); 16430 } 16431 /* 16432 * SPEC (5) "One of the following must be true:" 16433 */ 16434 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16435 /* 16436 * SPEC (5.1) "The {base type definition} must be the 16437 * `ur-type definition`." 16438 * PASS 16439 */ 16440 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16441 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16442 /* 16443 * SPEC (5.2.1) "The {content type} of the complex type definition 16444 * must be a simple type definition" 16445 * 16446 * SPEC (5.2.2) "One of the following must be true:" 16447 */ 16448 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16449 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16450 { 16451 int err; 16452 /* 16453 * SPEC (5.2.2.1) "The {content type} of the {base type 16454 * definition} must be a simple type definition from which 16455 * the {content type} is validly derived given the empty 16456 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16457 * 16458 * ATTENTION TODO: This seems not needed if the type implicitely 16459 * derived from the base type. 16460 * 16461 */ 16462 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16463 type->contentTypeDef, base->contentTypeDef, 0); 16464 if (err != 0) { 16465 xmlChar *strA = NULL, *strB = NULL; 16466 16467 if (err == -1) 16468 return(-1); 16469 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16470 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16471 NULL, WXS_BASIC_CAST type, 16472 "The {content type} %s is not validly derived from the " 16473 "base type's {content type} %s", 16474 xmlSchemaGetComponentDesignation(&strA, 16475 type->contentTypeDef), 16476 xmlSchemaGetComponentDesignation(&strB, 16477 base->contentTypeDef)); 16478 FREE_AND_NULL(strA); 16479 FREE_AND_NULL(strB); 16480 return(ctxt->err); 16481 } 16482 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16483 (xmlSchemaIsParticleEmptiable( 16484 (xmlSchemaParticlePtr) base->subtypes))) { 16485 /* 16486 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16487 * and have a particle which is `emptiable` as defined in 16488 * Particle Emptiable ($3.9.6)." 16489 * PASS 16490 */ 16491 } else { 16492 xmlSchemaPCustomErr(ctxt, 16493 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16494 WXS_BASIC_CAST type, NULL, 16495 "The content type of the base type must be either " 16496 "a simple type or 'mixed' and an emptiable particle", NULL); 16497 return (ctxt->err); 16498 } 16499 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16500 /* 16501 * SPEC (5.3.1) "The {content type} of the complex type itself must 16502 * be empty" 16503 */ 16504 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16505 /* 16506 * SPEC (5.3.2.1) "The {content type} of the {base type 16507 * definition} must also be empty." 16508 * PASS 16509 */ 16510 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16511 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16512 xmlSchemaIsParticleEmptiable( 16513 (xmlSchemaParticlePtr) base->subtypes)) { 16514 /* 16515 * SPEC (5.3.2.2) "The {content type} of the {base type 16516 * definition} must be elementOnly or mixed and have a particle 16517 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16518 * PASS 16519 */ 16520 } else { 16521 xmlSchemaPCustomErr(ctxt, 16522 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16523 WXS_BASIC_CAST type, NULL, 16524 "The content type of the base type must be either " 16525 "empty or 'mixed' (or 'elements-only') and an emptiable " 16526 "particle", NULL); 16527 return (ctxt->err); 16528 } 16529 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16530 WXS_HAS_MIXED_CONTENT(type)) { 16531 /* 16532 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16533 * itself must be element-only" 16534 */ 16535 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16536 /* 16537 * SPEC (5.4.1.2) "The {content type} of the complex type 16538 * definition itself and of the {base type definition} must be 16539 * mixed" 16540 */ 16541 xmlSchemaPCustomErr(ctxt, 16542 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16543 WXS_BASIC_CAST type, NULL, 16544 "If the content type is 'mixed', then the content type of the " 16545 "base type must also be 'mixed'", NULL); 16546 return (ctxt->err); 16547 } 16548 /* 16549 * SPEC (5.4.2) "The particle of the complex type definition itself 16550 * must be a `valid restriction` of the particle of the {content 16551 * type} of the {base type definition} as defined in Particle Valid 16552 * (Restriction) ($3.9.6). 16553 * 16554 * URGENT TODO: (5.4.2) 16555 */ 16556 } else { 16557 xmlSchemaPCustomErr(ctxt, 16558 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16559 WXS_BASIC_CAST type, NULL, 16560 "The type is not a valid restriction of its base type", NULL); 16561 return (ctxt->err); 16562 } 16563 return (0); 16564} 16565 16566/** 16567 * xmlSchemaCheckCTComponent: 16568 * @ctxt: the schema parser context 16569 * @type: the complex type definition 16570 * 16571 * (3.4.6) Constraints on Complex Type Definition Schema Components 16572 * 16573 * Returns 0 if the constraints are satisfied, a positive 16574 * error code if not and -1 if an internal error occured. 16575 */ 16576static int 16577xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16578 xmlSchemaTypePtr type) 16579{ 16580 int ret; 16581 /* 16582 * Complex Type Definition Properties Correct 16583 */ 16584 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16585 if (ret != 0) 16586 return (ret); 16587 if (WXS_IS_EXTENSION(type)) 16588 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16589 else 16590 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16591 return (ret); 16592} 16593 16594/** 16595 * xmlSchemaCheckSRCCT: 16596 * @ctxt: the schema parser context 16597 * @type: the complex type definition 16598 * 16599 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16600 * Schema Representation Constraint: 16601 * Complex Type Definition Representation OK (src-ct) 16602 * 16603 * Returns 0 if the constraints are satisfied, a positive 16604 * error code if not and -1 if an internal error occured. 16605 */ 16606static int 16607xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16608 xmlSchemaTypePtr type) 16609{ 16610 xmlSchemaTypePtr base; 16611 int ret = 0; 16612 16613 /* 16614 * TODO: Adjust the error codes here, as I used 16615 * XML_SCHEMAP_SRC_CT_1 only yet. 16616 */ 16617 base = type->baseType; 16618 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16619 /* 16620 * 1 If the <complexContent> alternative is chosen, the type definition 16621 * `resolved` to by the `actual value` of the base [attribute] 16622 * must be a complex type definition; 16623 */ 16624 if (! WXS_IS_COMPLEX(base)) { 16625 xmlChar *str = NULL; 16626 xmlSchemaPCustomErr(ctxt, 16627 XML_SCHEMAP_SRC_CT_1, 16628 WXS_BASIC_CAST type, type->node, 16629 "If using <complexContent>, the base type is expected to be " 16630 "a complex type. The base type '%s' is a simple type", 16631 xmlSchemaFormatQName(&str, base->targetNamespace, 16632 base->name)); 16633 FREE_AND_NULL(str) 16634 return (XML_SCHEMAP_SRC_CT_1); 16635 } 16636 } else { 16637 /* 16638 * SPEC 16639 * 2 If the <simpleContent> alternative is chosen, all of the 16640 * following must be true: 16641 * 2.1 The type definition `resolved` to by the `actual value` of the 16642 * base [attribute] must be one of the following: 16643 */ 16644 if (WXS_IS_SIMPLE(base)) { 16645 if (WXS_IS_EXTENSION(type) == 0) { 16646 xmlChar *str = NULL; 16647 /* 16648 * 2.1.3 only if the <extension> alternative is also 16649 * chosen, a simple type definition. 16650 */ 16651 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16652 xmlSchemaPCustomErr(ctxt, 16653 XML_SCHEMAP_SRC_CT_1, 16654 WXS_BASIC_CAST type, NULL, 16655 "If using <simpleContent> and <restriction>, the base " 16656 "type must be a complex type. The base type '%s' is " 16657 "a simple type", 16658 xmlSchemaFormatQName(&str, base->targetNamespace, 16659 base->name)); 16660 FREE_AND_NULL(str) 16661 return (XML_SCHEMAP_SRC_CT_1); 16662 } 16663 } else { 16664 /* Base type is a complex type. */ 16665 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16666 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16667 /* 16668 * 2.1.1 a complex type definition whose {content type} is a 16669 * simple type definition; 16670 * PASS 16671 */ 16672 if (base->contentTypeDef == NULL) { 16673 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16674 WXS_BASIC_CAST type, NULL, 16675 "Internal error: xmlSchemaCheckSRCCT, " 16676 "'%s', base type has no content type", 16677 type->name); 16678 return (-1); 16679 } 16680 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16681 (WXS_IS_RESTRICTION(type))) { 16682 16683 /* 16684 * 2.1.2 only if the <restriction> alternative is also 16685 * chosen, a complex type definition whose {content type} 16686 * is mixed and a particle emptiable. 16687 */ 16688 if (! xmlSchemaIsParticleEmptiable( 16689 (xmlSchemaParticlePtr) base->subtypes)) { 16690 ret = XML_SCHEMAP_SRC_CT_1; 16691 } else 16692 /* 16693 * Attention: at this point the <simpleType> child is in 16694 * ->contentTypeDef (put there during parsing). 16695 */ 16696 if (type->contentTypeDef == NULL) { 16697 xmlChar *str = NULL; 16698 /* 16699 * 2.2 If clause 2.1.2 above is satisfied, then there 16700 * must be a <simpleType> among the [children] of 16701 * <restriction>. 16702 */ 16703 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16704 xmlSchemaPCustomErr(ctxt, 16705 XML_SCHEMAP_SRC_CT_1, 16706 WXS_BASIC_CAST type, NULL, 16707 "A <simpleType> is expected among the children " 16708 "of <restriction>, if <simpleContent> is used and " 16709 "the base type '%s' is a complex type", 16710 xmlSchemaFormatQName(&str, base->targetNamespace, 16711 base->name)); 16712 FREE_AND_NULL(str) 16713 return (XML_SCHEMAP_SRC_CT_1); 16714 } 16715 } else { 16716 ret = XML_SCHEMAP_SRC_CT_1; 16717 } 16718 } 16719 if (ret > 0) { 16720 xmlChar *str = NULL; 16721 if (WXS_IS_RESTRICTION(type)) { 16722 xmlSchemaPCustomErr(ctxt, 16723 XML_SCHEMAP_SRC_CT_1, 16724 WXS_BASIC_CAST type, NULL, 16725 "If <simpleContent> and <restriction> is used, the " 16726 "base type must be a simple type or a complex type with " 16727 "mixed content and particle emptiable. The base type " 16728 "'%s' is none of those", 16729 xmlSchemaFormatQName(&str, base->targetNamespace, 16730 base->name)); 16731 } else { 16732 xmlSchemaPCustomErr(ctxt, 16733 XML_SCHEMAP_SRC_CT_1, 16734 WXS_BASIC_CAST type, NULL, 16735 "If <simpleContent> and <extension> is used, the " 16736 "base type must be a simple type. The base type '%s' " 16737 "is a complex type", 16738 xmlSchemaFormatQName(&str, base->targetNamespace, 16739 base->name)); 16740 } 16741 FREE_AND_NULL(str) 16742 } 16743 } 16744 /* 16745 * SPEC (3) "The corresponding complex type definition component must 16746 * satisfy the conditions set out in Constraints on Complex Type 16747 * Definition Schema Components ($3.4.6);" 16748 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16749 */ 16750 /* 16751 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16752 * above for {attribute wildcard} is satisfied, the intensional 16753 * intersection must be expressible, as defined in Attribute Wildcard 16754 * Intersection ($3.10.6). 16755 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16756 */ 16757 return (ret); 16758} 16759 16760#ifdef ENABLE_PARTICLE_RESTRICTION 16761/** 16762 * xmlSchemaCheckParticleRangeOK: 16763 * @ctxt: the schema parser context 16764 * @type: the complex type definition 16765 * 16766 * (3.9.6) Constraints on Particle Schema Components 16767 * Schema Component Constraint: 16768 * Occurrence Range OK (range-ok) 16769 * 16770 * STATUS: complete 16771 * 16772 * Returns 0 if the constraints are satisfied, a positive 16773 * error code if not and -1 if an internal error occured. 16774 */ 16775static int 16776xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16777 int bmin, int bmax) 16778{ 16779 if (rmin < bmin) 16780 return (1); 16781 if ((bmax != UNBOUNDED) && 16782 (rmax > bmax)) 16783 return (1); 16784 return (0); 16785} 16786 16787/** 16788 * xmlSchemaCheckRCaseNameAndTypeOK: 16789 * @ctxt: the schema parser context 16790 * @r: the restricting element declaration particle 16791 * @b: the base element declaration particle 16792 * 16793 * (3.9.6) Constraints on Particle Schema Components 16794 * Schema Component Constraint: 16795 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16796 * (rcase-NameAndTypeOK) 16797 * 16798 * STATUS: 16799 * MISSING (3.2.3) 16800 * CLARIFY: (3.2.2) 16801 * 16802 * Returns 0 if the constraints are satisfied, a positive 16803 * error code if not and -1 if an internal error occured. 16804 */ 16805static int 16806xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16807 xmlSchemaParticlePtr r, 16808 xmlSchemaParticlePtr b) 16809{ 16810 xmlSchemaElementPtr elemR, elemB; 16811 16812 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16813 elemR = (xmlSchemaElementPtr) r->children; 16814 elemB = (xmlSchemaElementPtr) b->children; 16815 /* 16816 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16817 * the same." 16818 */ 16819 if ((elemR != elemB) && 16820 ((! xmlStrEqual(elemR->name, elemB->name)) || 16821 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16822 return (1); 16823 /* 16824 * SPEC (2) "R's occurrence range is a valid restriction of B's 16825 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16826 */ 16827 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16828 b->minOccurs, b->maxOccurs) != 0) 16829 return (1); 16830 /* 16831 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16832 * {scope} are global." 16833 */ 16834 if (elemR == elemB) 16835 return (0); 16836 /* 16837 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16838 */ 16839 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16840 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16841 return (1); 16842 /* 16843 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16844 * or is not fixed, or R's declaration's {value constraint} is fixed 16845 * with the same value." 16846 */ 16847 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16848 ((elemR->value == NULL) || 16849 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16850 /* TODO: Equality of the initial value or normalized or canonical? */ 16851 (! xmlStrEqual(elemR->value, elemB->value)))) 16852 return (1); 16853 /* 16854 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16855 * definitions} is a subset of B's declaration's {identity-constraint 16856 * definitions}, if any." 16857 */ 16858 if (elemB->idcs != NULL) { 16859 /* TODO */ 16860 } 16861 /* 16862 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16863 * superset of B's declaration's {disallowed substitutions}." 16864 */ 16865 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16866 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16867 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16868 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16869 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16870 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16871 return (1); 16872 /* 16873 * SPEC (3.2.5) "R's {type definition} is validly derived given 16874 * {extension, list, union} from B's {type definition}" 16875 * 16876 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16877 * set, if the corresponding constraints handle "restriction" and 16878 * "extension" only? 16879 * 16880 */ 16881 { 16882 int set = 0; 16883 16884 set |= SUBSET_EXTENSION; 16885 set |= SUBSET_LIST; 16886 set |= SUBSET_UNION; 16887 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16888 elemB->subtypes, set) != 0) 16889 return (1); 16890 } 16891 return (0); 16892} 16893 16894/** 16895 * xmlSchemaCheckRCaseNSCompat: 16896 * @ctxt: the schema parser context 16897 * @r: the restricting element declaration particle 16898 * @b: the base wildcard particle 16899 * 16900 * (3.9.6) Constraints on Particle Schema Components 16901 * Schema Component Constraint: 16902 * Particle Derivation OK (Elt:Any -- NSCompat) 16903 * (rcase-NSCompat) 16904 * 16905 * STATUS: complete 16906 * 16907 * Returns 0 if the constraints are satisfied, a positive 16908 * error code if not and -1 if an internal error occured. 16909 */ 16910static int 16911xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16912 xmlSchemaParticlePtr r, 16913 xmlSchemaParticlePtr b) 16914{ 16915 /* TODO:Error codes (rcase-NSCompat). */ 16916 /* 16917 * SPEC "For an element declaration particle to be a `valid restriction` 16918 * of a wildcard particle all of the following must be true:" 16919 * 16920 * SPEC (1) "The element declaration's {target namespace} is `valid` 16921 * with respect to the wildcard's {namespace constraint} as defined by 16922 * Wildcard allows Namespace Name ($3.10.4)." 16923 */ 16924 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16925 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16926 return (1); 16927 /* 16928 * SPEC (2) "R's occurrence range is a valid restriction of B's 16929 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16930 */ 16931 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16932 b->minOccurs, b->maxOccurs) != 0) 16933 return (1); 16934 16935 return (0); 16936} 16937 16938/** 16939 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16940 * @ctxt: the schema parser context 16941 * @r: the restricting element declaration particle 16942 * @b: the base model group particle 16943 * 16944 * (3.9.6) Constraints on Particle Schema Components 16945 * Schema Component Constraint: 16946 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16947 * (rcase-RecurseAsIfGroup) 16948 * 16949 * STATUS: TODO 16950 * 16951 * Returns 0 if the constraints are satisfied, a positive 16952 * error code if not and -1 if an internal error occured. 16953 */ 16954static int 16955xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16956 xmlSchemaParticlePtr r, 16957 xmlSchemaParticlePtr b) 16958{ 16959 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16960 TODO 16961 return (0); 16962} 16963 16964/** 16965 * xmlSchemaCheckRCaseNSSubset: 16966 * @ctxt: the schema parser context 16967 * @r: the restricting wildcard particle 16968 * @b: the base wildcard particle 16969 * 16970 * (3.9.6) Constraints on Particle Schema Components 16971 * Schema Component Constraint: 16972 * Particle Derivation OK (Any:Any -- NSSubset) 16973 * (rcase-NSSubset) 16974 * 16975 * STATUS: complete 16976 * 16977 * Returns 0 if the constraints are satisfied, a positive 16978 * error code if not and -1 if an internal error occured. 16979 */ 16980static int 16981xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16982 xmlSchemaParticlePtr r, 16983 xmlSchemaParticlePtr b, 16984 int isAnyTypeBase) 16985{ 16986 /* TODO: Error codes (rcase-NSSubset). */ 16987 /* 16988 * SPEC (1) "R's occurrence range is a valid restriction of B's 16989 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16990 */ 16991 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16992 b->minOccurs, b->maxOccurs)) 16993 return (1); 16994 /* 16995 * SPEC (2) "R's {namespace constraint} must be an intensional subset 16996 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 16997 */ 16998 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 16999 (xmlSchemaWildcardPtr) b->children)) 17000 return (1); 17001 /* 17002 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17003 * definition`, R's {process contents} must be identical to or stronger 17004 * than B's {process contents}, where strict is stronger than lax is 17005 * stronger than skip." 17006 */ 17007 if (! isAnyTypeBase) { 17008 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17009 ((xmlSchemaWildcardPtr) b->children)->processContents) 17010 return (1); 17011 } 17012 17013 return (0); 17014} 17015 17016/** 17017 * xmlSchemaCheckCOSParticleRestrict: 17018 * @ctxt: the schema parser context 17019 * @type: the complex type definition 17020 * 17021 * (3.9.6) Constraints on Particle Schema Components 17022 * Schema Component Constraint: 17023 * Particle Valid (Restriction) (cos-particle-restrict) 17024 * 17025 * STATUS: TODO 17026 * 17027 * Returns 0 if the constraints are satisfied, a positive 17028 * error code if not and -1 if an internal error occured. 17029 */ 17030static int 17031xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17032 xmlSchemaParticlePtr r, 17033 xmlSchemaParticlePtr b) 17034{ 17035 int ret = 0; 17036 17037 /*part = WXS_TYPE_PARTICLE(type); 17038 basePart = WXS_TYPE_PARTICLE(base); 17039 */ 17040 17041 TODO 17042 17043 /* 17044 * SPEC (1) "They are the same particle." 17045 */ 17046 if (r == b) 17047 return (0); 17048 17049 17050 return (0); 17051} 17052 17053#if 0 17054/** 17055 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17056 * @ctxt: the schema parser context 17057 * @r: the model group particle 17058 * @b: the base wildcard particle 17059 * 17060 * (3.9.6) Constraints on Particle Schema Components 17061 * Schema Component Constraint: 17062 * Particle Derivation OK (All/Choice/Sequence:Any -- 17063 * NSRecurseCheckCardinality) 17064 * (rcase-NSRecurseCheckCardinality) 17065 * 17066 * STATUS: TODO: subst-groups 17067 * 17068 * Returns 0 if the constraints are satisfied, a positive 17069 * error code if not and -1 if an internal error occured. 17070 */ 17071static int 17072xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17073 xmlSchemaParticlePtr r, 17074 xmlSchemaParticlePtr b) 17075{ 17076 xmlSchemaParticlePtr part; 17077 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17078 if ((r->children == NULL) || (r->children->children == NULL)) 17079 return (-1); 17080 /* 17081 * SPEC "For a group particle to be a `valid restriction` of a 17082 * wildcard particle..." 17083 * 17084 * SPEC (1) "Every member of the {particles} of the group is a `valid 17085 * restriction` of the wildcard as defined by 17086 * Particle Valid (Restriction) ($3.9.6)." 17087 */ 17088 part = (xmlSchemaParticlePtr) r->children->children; 17089 do { 17090 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17091 return (1); 17092 part = (xmlSchemaParticlePtr) part->next; 17093 } while (part != NULL); 17094 /* 17095 * SPEC (2) "The effective total range of the group [...] is a 17096 * valid restriction of B's occurrence range as defined by 17097 * Occurrence Range OK ($3.9.6)." 17098 */ 17099 if (xmlSchemaCheckParticleRangeOK( 17100 xmlSchemaGetParticleTotalRangeMin(r), 17101 xmlSchemaGetParticleTotalRangeMax(r), 17102 b->minOccurs, b->maxOccurs) != 0) 17103 return (1); 17104 return (0); 17105} 17106#endif 17107 17108/** 17109 * xmlSchemaCheckRCaseRecurse: 17110 * @ctxt: the schema parser context 17111 * @r: the <all> or <sequence> model group particle 17112 * @b: the base <all> or <sequence> model group particle 17113 * 17114 * (3.9.6) Constraints on Particle Schema Components 17115 * Schema Component Constraint: 17116 * Particle Derivation OK (All:All,Sequence:Sequence -- 17117 Recurse) 17118 * (rcase-Recurse) 17119 * 17120 * STATUS: ? 17121 * TODO: subst-groups 17122 * 17123 * Returns 0 if the constraints are satisfied, a positive 17124 * error code if not and -1 if an internal error occured. 17125 */ 17126static int 17127xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17128 xmlSchemaParticlePtr r, 17129 xmlSchemaParticlePtr b) 17130{ 17131 /* xmlSchemaParticlePtr part; */ 17132 /* TODO: Error codes (rcase-Recurse). */ 17133 if ((r->children == NULL) || (b->children == NULL) || 17134 (r->children->type != b->children->type)) 17135 return (-1); 17136 /* 17137 * SPEC "For an all or sequence group particle to be a `valid 17138 * restriction` of another group particle with the same {compositor}..." 17139 * 17140 * SPEC (1) "R's occurrence range is a valid restriction of B's 17141 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17142 */ 17143 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17144 b->minOccurs, b->maxOccurs)) 17145 return (1); 17146 17147 17148 return (0); 17149} 17150 17151#endif 17152 17153#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17154 xmlSchemaPCustomErrExt(pctxt, \ 17155 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17156 WXS_BASIC_CAST fac1, fac1->node, \ 17157 "It is an error for both '%s' and '%s' to be specified on the "\ 17158 "same type definition", \ 17159 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17160 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17161 17162#define FACET_RESTR_ERR(fac1, msg) \ 17163 xmlSchemaPCustomErr(pctxt, \ 17164 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17165 WXS_BASIC_CAST fac1, fac1->node, \ 17166 msg, NULL); 17167 17168#define FACET_RESTR_FIXED_ERR(fac) \ 17169 xmlSchemaPCustomErr(pctxt, \ 17170 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17171 WXS_BASIC_CAST fac, fac->node, \ 17172 "The base type's facet is 'fixed', thus the value must not " \ 17173 "differ", NULL); 17174 17175static void 17176xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17177 xmlSchemaFacetPtr facet1, 17178 xmlSchemaFacetPtr facet2, 17179 int lessGreater, 17180 int orEqual, 17181 int ofBase) 17182{ 17183 xmlChar *msg = NULL; 17184 17185 msg = xmlStrdup(BAD_CAST "'"); 17186 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17187 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17188 if (lessGreater == 0) 17189 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17190 if (lessGreater == 1) 17191 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17192 else 17193 msg = xmlStrcat(msg, BAD_CAST " less than"); 17194 17195 if (orEqual) 17196 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17197 msg = xmlStrcat(msg, BAD_CAST " '"); 17198 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17199 if (ofBase) 17200 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17201 else 17202 msg = xmlStrcat(msg, BAD_CAST "'"); 17203 17204 xmlSchemaPCustomErr(pctxt, 17205 XML_SCHEMAP_INVALID_FACET_VALUE, 17206 WXS_BASIC_CAST facet1, NULL, 17207 (const char *) msg, NULL); 17208 17209 if (msg != NULL) 17210 xmlFree(msg); 17211} 17212 17213/* 17214* xmlSchemaDeriveAndValidateFacets: 17215* 17216* Schema Component Constraint: Simple Type Restriction (Facets) 17217* (st-restrict-facets) 17218*/ 17219static int 17220xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17221 xmlSchemaTypePtr type) 17222{ 17223 xmlSchemaTypePtr base = type->baseType; 17224 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17225 xmlSchemaFacetPtr facet, bfacet, 17226 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17227 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17228 fmininc = NULL, fmaxinc = NULL, 17229 fminexc = NULL, fmaxexc = NULL, 17230 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17231 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17232 bfmininc = NULL, bfmaxinc = NULL, 17233 bfminexc = NULL, bfmaxexc = NULL; 17234 int res; /* err = 0, fixedErr; */ 17235 17236 /* 17237 * SPEC st-restrict-facets 1: 17238 * "The {variety} of R is the same as that of B." 17239 */ 17240 /* 17241 * SPEC st-restrict-facets 2: 17242 * "If {variety} is atomic, the {primitive type definition} 17243 * of R is the same as that of B." 17244 * 17245 * NOTE: we leave 1 & 2 out for now, since this will be 17246 * satisfied by the derivation process. 17247 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17248 */ 17249 /* 17250 * SPEC st-restrict-facets 3: 17251 * "The {facets} of R are the union of S and the {facets} 17252 * of B, eliminating duplicates. To eliminate duplicates, 17253 * when a facet of the same kind occurs in both S and the 17254 * {facets} of B, the one in the {facets} of B is not 17255 * included, with the exception of enumeration and pattern 17256 * facets, for which multiple occurrences with distinct values 17257 * are allowed." 17258 */ 17259 17260 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17261 return (0); 17262 17263 last = type->facetSet; 17264 if (last != NULL) 17265 while (last->next != NULL) 17266 last = last->next; 17267 17268 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17269 facet = cur->facet; 17270 switch (facet->type) { 17271 case XML_SCHEMA_FACET_LENGTH: 17272 flength = facet; break; 17273 case XML_SCHEMA_FACET_MINLENGTH: 17274 fminlen = facet; break; 17275 case XML_SCHEMA_FACET_MININCLUSIVE: 17276 fmininc = facet; break; 17277 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17278 fminexc = facet; break; 17279 case XML_SCHEMA_FACET_MAXLENGTH: 17280 fmaxlen = facet; break; 17281 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17282 fmaxinc = facet; break; 17283 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17284 fmaxexc = facet; break; 17285 case XML_SCHEMA_FACET_TOTALDIGITS: 17286 ftotdig = facet; break; 17287 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17288 ffracdig = facet; break; 17289 default: 17290 break; 17291 } 17292 } 17293 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17294 facet = cur->facet; 17295 switch (facet->type) { 17296 case XML_SCHEMA_FACET_LENGTH: 17297 bflength = facet; break; 17298 case XML_SCHEMA_FACET_MINLENGTH: 17299 bfminlen = facet; break; 17300 case XML_SCHEMA_FACET_MININCLUSIVE: 17301 bfmininc = facet; break; 17302 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17303 bfminexc = facet; break; 17304 case XML_SCHEMA_FACET_MAXLENGTH: 17305 bfmaxlen = facet; break; 17306 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17307 bfmaxinc = facet; break; 17308 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17309 bfmaxexc = facet; break; 17310 case XML_SCHEMA_FACET_TOTALDIGITS: 17311 bftotdig = facet; break; 17312 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17313 bffracdig = facet; break; 17314 default: 17315 break; 17316 } 17317 } 17318 /* 17319 * length and minLength or maxLength (2.2) + (3.2) 17320 */ 17321 if (flength && (fminlen || fmaxlen)) { 17322 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17323 "either of 'minLength' or 'maxLength' to be specified on " 17324 "the same type definition") 17325 } 17326 /* 17327 * Mutual exclusions in the same derivation step. 17328 */ 17329 if ((fmaxinc) && (fmaxexc)) { 17330 /* 17331 * SCC "maxInclusive and maxExclusive" 17332 */ 17333 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17334 } 17335 if ((fmininc) && (fminexc)) { 17336 /* 17337 * SCC "minInclusive and minExclusive" 17338 */ 17339 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17340 } 17341 17342 if (flength && bflength) { 17343 /* 17344 * SCC "length valid restriction" 17345 * The values have to be equal. 17346 */ 17347 res = xmlSchemaCompareValues(flength->val, bflength->val); 17348 if (res == -2) 17349 goto internal_error; 17350 if (res != 0) 17351 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17352 if ((res != 0) && (bflength->fixed)) { 17353 FACET_RESTR_FIXED_ERR(flength) 17354 } 17355 17356 } 17357 if (fminlen && bfminlen) { 17358 /* 17359 * SCC "minLength valid restriction" 17360 * minLength >= BASE minLength 17361 */ 17362 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17363 if (res == -2) 17364 goto internal_error; 17365 if (res == -1) 17366 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17367 if ((res != 0) && (bfminlen->fixed)) { 17368 FACET_RESTR_FIXED_ERR(fminlen) 17369 } 17370 } 17371 if (fmaxlen && bfmaxlen) { 17372 /* 17373 * SCC "maxLength valid restriction" 17374 * maxLength <= BASE minLength 17375 */ 17376 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17377 if (res == -2) 17378 goto internal_error; 17379 if (res == 1) 17380 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17381 if ((res != 0) && (bfmaxlen->fixed)) { 17382 FACET_RESTR_FIXED_ERR(fmaxlen) 17383 } 17384 } 17385 /* 17386 * SCC "length and minLength or maxLength" 17387 */ 17388 if (! flength) 17389 flength = bflength; 17390 if (flength) { 17391 if (! fminlen) 17392 fminlen = bfminlen; 17393 if (fminlen) { 17394 /* (1.1) length >= minLength */ 17395 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17396 if (res == -2) 17397 goto internal_error; 17398 if (res == -1) 17399 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17400 } 17401 if (! fmaxlen) 17402 fmaxlen = bfmaxlen; 17403 if (fmaxlen) { 17404 /* (2.1) length <= maxLength */ 17405 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17406 if (res == -2) 17407 goto internal_error; 17408 if (res == 1) 17409 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17410 } 17411 } 17412 if (fmaxinc) { 17413 /* 17414 * "maxInclusive" 17415 */ 17416 if (fmininc) { 17417 /* SCC "maxInclusive >= minInclusive" */ 17418 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17419 if (res == -2) 17420 goto internal_error; 17421 if (res == -1) { 17422 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17423 } 17424 } 17425 /* 17426 * SCC "maxInclusive valid restriction" 17427 */ 17428 if (bfmaxinc) { 17429 /* maxInclusive <= BASE maxInclusive */ 17430 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17431 if (res == -2) 17432 goto internal_error; 17433 if (res == 1) 17434 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17435 if ((res != 0) && (bfmaxinc->fixed)) { 17436 FACET_RESTR_FIXED_ERR(fmaxinc) 17437 } 17438 } 17439 if (bfmaxexc) { 17440 /* maxInclusive < BASE maxExclusive */ 17441 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17442 if (res == -2) 17443 goto internal_error; 17444 if (res != -1) { 17445 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17446 } 17447 } 17448 if (bfmininc) { 17449 /* maxInclusive >= BASE minInclusive */ 17450 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17451 if (res == -2) 17452 goto internal_error; 17453 if (res == -1) { 17454 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17455 } 17456 } 17457 if (bfminexc) { 17458 /* maxInclusive > BASE minExclusive */ 17459 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17460 if (res == -2) 17461 goto internal_error; 17462 if (res != 1) { 17463 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17464 } 17465 } 17466 } 17467 if (fmaxexc) { 17468 /* 17469 * "maxExclusive >= minExclusive" 17470 */ 17471 if (fminexc) { 17472 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17473 if (res == -2) 17474 goto internal_error; 17475 if (res == -1) { 17476 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17477 } 17478 } 17479 /* 17480 * "maxExclusive valid restriction" 17481 */ 17482 if (bfmaxexc) { 17483 /* maxExclusive <= BASE maxExclusive */ 17484 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17485 if (res == -2) 17486 goto internal_error; 17487 if (res == 1) { 17488 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17489 } 17490 if ((res != 0) && (bfmaxexc->fixed)) { 17491 FACET_RESTR_FIXED_ERR(fmaxexc) 17492 } 17493 } 17494 if (bfmaxinc) { 17495 /* maxExclusive <= BASE maxInclusive */ 17496 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17497 if (res == -2) 17498 goto internal_error; 17499 if (res == 1) { 17500 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17501 } 17502 } 17503 if (bfmininc) { 17504 /* maxExclusive > BASE minInclusive */ 17505 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17506 if (res == -2) 17507 goto internal_error; 17508 if (res != 1) { 17509 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17510 } 17511 } 17512 if (bfminexc) { 17513 /* maxExclusive > BASE minExclusive */ 17514 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17515 if (res == -2) 17516 goto internal_error; 17517 if (res != 1) { 17518 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17519 } 17520 } 17521 } 17522 if (fminexc) { 17523 /* 17524 * "minExclusive < maxInclusive" 17525 */ 17526 if (fmaxinc) { 17527 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17528 if (res == -2) 17529 goto internal_error; 17530 if (res != -1) { 17531 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17532 } 17533 } 17534 /* 17535 * "minExclusive valid restriction" 17536 */ 17537 if (bfminexc) { 17538 /* minExclusive >= BASE minExclusive */ 17539 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17540 if (res == -2) 17541 goto internal_error; 17542 if (res == -1) { 17543 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17544 } 17545 if ((res != 0) && (bfminexc->fixed)) { 17546 FACET_RESTR_FIXED_ERR(fminexc) 17547 } 17548 } 17549 if (bfmaxinc) { 17550 /* minExclusive <= BASE maxInclusive */ 17551 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17552 if (res == -2) 17553 goto internal_error; 17554 if (res == 1) { 17555 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17556 } 17557 } 17558 if (bfmininc) { 17559 /* minExclusive >= BASE minInclusive */ 17560 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17561 if (res == -2) 17562 goto internal_error; 17563 if (res == -1) { 17564 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17565 } 17566 } 17567 if (bfmaxexc) { 17568 /* minExclusive < BASE maxExclusive */ 17569 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17570 if (res == -2) 17571 goto internal_error; 17572 if (res != -1) { 17573 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17574 } 17575 } 17576 } 17577 if (fmininc) { 17578 /* 17579 * "minInclusive < maxExclusive" 17580 */ 17581 if (fmaxexc) { 17582 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17583 if (res == -2) 17584 goto internal_error; 17585 if (res != -1) { 17586 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17587 } 17588 } 17589 /* 17590 * "minExclusive valid restriction" 17591 */ 17592 if (bfmininc) { 17593 /* minInclusive >= BASE minInclusive */ 17594 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17595 if (res == -2) 17596 goto internal_error; 17597 if (res == -1) { 17598 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17599 } 17600 if ((res != 0) && (bfmininc->fixed)) { 17601 FACET_RESTR_FIXED_ERR(fmininc) 17602 } 17603 } 17604 if (bfmaxinc) { 17605 /* minInclusive <= BASE maxInclusive */ 17606 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17607 if (res == -2) 17608 goto internal_error; 17609 if (res == 1) { 17610 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17611 } 17612 } 17613 if (bfminexc) { 17614 /* minInclusive > BASE minExclusive */ 17615 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17616 if (res == -2) 17617 goto internal_error; 17618 if (res != 1) 17619 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17620 } 17621 if (bfmaxexc) { 17622 /* minInclusive < BASE maxExclusive */ 17623 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17624 if (res == -2) 17625 goto internal_error; 17626 if (res != -1) 17627 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17628 } 17629 } 17630 if (ftotdig && bftotdig) { 17631 /* 17632 * SCC " totalDigits valid restriction" 17633 * totalDigits <= BASE totalDigits 17634 */ 17635 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17636 if (res == -2) 17637 goto internal_error; 17638 if (res == 1) 17639 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17640 -1, 1, 1); 17641 if ((res != 0) && (bftotdig->fixed)) { 17642 FACET_RESTR_FIXED_ERR(ftotdig) 17643 } 17644 } 17645 if (ffracdig && bffracdig) { 17646 /* 17647 * SCC "fractionDigits valid restriction" 17648 * fractionDigits <= BASE fractionDigits 17649 */ 17650 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17651 if (res == -2) 17652 goto internal_error; 17653 if (res == 1) 17654 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17655 -1, 1, 1); 17656 if ((res != 0) && (bffracdig->fixed)) { 17657 FACET_RESTR_FIXED_ERR(ffracdig) 17658 } 17659 } 17660 /* 17661 * SCC "fractionDigits less than or equal to totalDigits" 17662 */ 17663 if (! ftotdig) 17664 ftotdig = bftotdig; 17665 if (! ffracdig) 17666 ffracdig = bffracdig; 17667 if (ftotdig && ffracdig) { 17668 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17669 if (res == -2) 17670 goto internal_error; 17671 if (res == 1) 17672 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17673 -1, 1, 0); 17674 } 17675 /* 17676 * *Enumerations* won' be added here, since only the first set 17677 * of enumerations in the ancestor-or-self axis is used 17678 * for validation, plus we need to use the base type of those 17679 * enumerations for whitespace. 17680 * 17681 * *Patterns*: won't be add here, since they are ORed at 17682 * type level and ANDed at ancestor level. This will 17683 * happed during validation by walking the base axis 17684 * of the type. 17685 */ 17686 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17687 bfacet = cur->facet; 17688 /* 17689 * Special handling of enumerations and patterns. 17690 * TODO: hmm, they should not appear in the set, so remove this. 17691 */ 17692 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17693 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17694 continue; 17695 /* 17696 * Search for a duplicate facet in the current type. 17697 */ 17698 link = type->facetSet; 17699 /* err = 0; */ 17700 /* fixedErr = 0; */ 17701 while (link != NULL) { 17702 facet = link->facet; 17703 if (facet->type == bfacet->type) { 17704 switch (facet->type) { 17705 case XML_SCHEMA_FACET_WHITESPACE: 17706 /* 17707 * The whitespace must be stronger. 17708 */ 17709 if (facet->whitespace < bfacet->whitespace) { 17710 FACET_RESTR_ERR(facet, 17711 "The 'whitespace' value has to be equal to " 17712 "or stronger than the 'whitespace' value of " 17713 "the base type") 17714 } 17715 if ((bfacet->fixed) && 17716 (facet->whitespace != bfacet->whitespace)) { 17717 FACET_RESTR_FIXED_ERR(facet) 17718 } 17719 break; 17720 default: 17721 break; 17722 } 17723 /* Duplicate found. */ 17724 break; 17725 } 17726 link = link->next; 17727 } 17728 /* 17729 * If no duplicate was found: add the base types's facet 17730 * to the set. 17731 */ 17732 if (link == NULL) { 17733 link = (xmlSchemaFacetLinkPtr) 17734 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17735 if (link == NULL) { 17736 xmlSchemaPErrMemory(pctxt, 17737 "deriving facets, creating a facet link", NULL); 17738 return (-1); 17739 } 17740 link->facet = cur->facet; 17741 link->next = NULL; 17742 if (last == NULL) 17743 type->facetSet = link; 17744 else 17745 last->next = link; 17746 last = link; 17747 } 17748 17749 } 17750 17751 return (0); 17752internal_error: 17753 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17754 "an error occured"); 17755 return (-1); 17756} 17757 17758static int 17759xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17760 xmlSchemaTypePtr type) 17761{ 17762 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17763 /* 17764 * The actual value is then formed by replacing any union type 17765 * definition in the `explicit members` with the members of their 17766 * {member type definitions}, in order. 17767 * 17768 * TODO: There's a bug entry at 17769 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17770 * which indicates that we'll keep the union types the future. 17771 */ 17772 link = type->memberTypes; 17773 while (link != NULL) { 17774 17775 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17776 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17777 17778 if (WXS_IS_UNION(link->type)) { 17779 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17780 if (subLink != NULL) { 17781 link->type = subLink->type; 17782 if (subLink->next != NULL) { 17783 lastLink = link->next; 17784 subLink = subLink->next; 17785 prevLink = link; 17786 while (subLink != NULL) { 17787 newLink = (xmlSchemaTypeLinkPtr) 17788 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17789 if (newLink == NULL) { 17790 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17791 NULL); 17792 return (-1); 17793 } 17794 newLink->type = subLink->type; 17795 prevLink->next = newLink; 17796 prevLink = newLink; 17797 newLink->next = lastLink; 17798 17799 subLink = subLink->next; 17800 } 17801 } 17802 } 17803 } 17804 link = link->next; 17805 } 17806 return (0); 17807} 17808 17809static void 17810xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17811{ 17812 int has = 0, needVal = 0, normVal = 0; 17813 17814 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17815 if (has) { 17816 needVal = (type->baseType->flags & 17817 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17818 normVal = (type->baseType->flags & 17819 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17820 } 17821 if (type->facets != NULL) { 17822 xmlSchemaFacetPtr fac; 17823 17824 for (fac = type->facets; fac != NULL; fac = fac->next) { 17825 switch (fac->type) { 17826 case XML_SCHEMA_FACET_WHITESPACE: 17827 break; 17828 case XML_SCHEMA_FACET_PATTERN: 17829 normVal = 1; 17830 has = 1; 17831 break; 17832 case XML_SCHEMA_FACET_ENUMERATION: 17833 needVal = 1; 17834 normVal = 1; 17835 has = 1; 17836 break; 17837 default: 17838 has = 1; 17839 break; 17840 } 17841 } 17842 } 17843 if (normVal) 17844 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17845 if (needVal) 17846 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17847 if (has) 17848 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17849 17850 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17851 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17852 /* 17853 * OPTIMIZE VAL TODO: Some facets need a computed value. 17854 */ 17855 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17856 (prim->builtInType != XML_SCHEMAS_STRING)) { 17857 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17858 } 17859 } 17860} 17861 17862static int 17863xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17864{ 17865 17866 17867 /* 17868 * Evaluate the whitespace-facet value. 17869 */ 17870 if (WXS_IS_LIST(type)) { 17871 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17872 return (0); 17873 } else if (WXS_IS_UNION(type)) 17874 return (0); 17875 17876 if (type->facetSet != NULL) { 17877 xmlSchemaFacetLinkPtr lin; 17878 17879 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17880 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17881 switch (lin->facet->whitespace) { 17882 case XML_SCHEMAS_FACET_PRESERVE: 17883 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17884 break; 17885 case XML_SCHEMAS_FACET_REPLACE: 17886 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17887 break; 17888 case XML_SCHEMAS_FACET_COLLAPSE: 17889 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17890 break; 17891 default: 17892 return (-1); 17893 } 17894 return (0); 17895 } 17896 } 17897 } 17898 /* 17899 * For all `atomic` datatypes other than string (and types `derived` 17900 * by `restriction` from it) the value of whiteSpace is fixed to 17901 * collapse 17902 */ 17903 { 17904 xmlSchemaTypePtr anc; 17905 17906 for (anc = type->baseType; anc != NULL && 17907 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17908 anc = anc->baseType) { 17909 17910 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17911 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17912 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17913 17914 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17915 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17916 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17917 17918 } else 17919 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17920 break; 17921 } 17922 } 17923 } 17924 return (0); 17925} 17926 17927static int 17928xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17929 xmlSchemaTypePtr type) 17930{ 17931 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17932 return(0); 17933 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17934 return(0); 17935 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17936 17937 if (WXS_IS_LIST(type)) { 17938 /* 17939 * Corresponds to <simpleType><list>... 17940 */ 17941 if (type->subtypes == NULL) { 17942 /* 17943 * This one is really needed, so get out. 17944 */ 17945 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17946 "list type has no item-type assigned"); 17947 return(-1); 17948 } 17949 } else if (WXS_IS_UNION(type)) { 17950 /* 17951 * Corresponds to <simpleType><union>... 17952 */ 17953 if (type->memberTypes == NULL) { 17954 /* 17955 * This one is really needed, so get out. 17956 */ 17957 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17958 "union type has no member-types assigned"); 17959 return(-1); 17960 } 17961 } else { 17962 /* 17963 * Corresponds to <simpleType><restriction>... 17964 */ 17965 if (type->baseType == NULL) { 17966 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17967 "type has no base-type assigned"); 17968 return(-1); 17969 } 17970 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17971 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17972 return(-1); 17973 /* 17974 * Variety 17975 * If the <restriction> alternative is chosen, then the 17976 * {variety} of the {base type definition}. 17977 */ 17978 if (WXS_IS_ATOMIC(type->baseType)) 17979 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17980 else if (WXS_IS_LIST(type->baseType)) { 17981 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17982 /* 17983 * Inherit the itemType. 17984 */ 17985 type->subtypes = type->baseType->subtypes; 17986 } else if (WXS_IS_UNION(type->baseType)) { 17987 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 17988 /* 17989 * NOTE that we won't assign the memberTypes of the base, 17990 * since this will make trouble when freeing them; we will 17991 * use a lookup function to access them instead. 17992 */ 17993 } 17994 } 17995 return(0); 17996} 17997 17998#ifdef DEBUG_TYPE 17999static void 18000xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18001 xmlSchemaTypePtr type) 18002{ 18003 if (type->node != NULL) { 18004 xmlGenericError(xmlGenericErrorContext, 18005 "Type of %s : %s:%d :", name, 18006 type->node->doc->URL, 18007 xmlGetLineNo(type->node)); 18008 } else { 18009 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18010 } 18011 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18012 switch (type->contentType) { 18013 case XML_SCHEMA_CONTENT_SIMPLE: 18014 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18015 break; 18016 case XML_SCHEMA_CONTENT_ELEMENTS: 18017 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18018 break; 18019 case XML_SCHEMA_CONTENT_UNKNOWN: 18020 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18021 break; 18022 case XML_SCHEMA_CONTENT_EMPTY: 18023 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18024 break; 18025 case XML_SCHEMA_CONTENT_MIXED: 18026 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18027 type->subtypes)) 18028 xmlGenericError(xmlGenericErrorContext, 18029 "mixed as emptiable particle\n"); 18030 else 18031 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18032 break; 18033 /* Removed, since not used. */ 18034 /* 18035 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18036 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18037 break; 18038 */ 18039 case XML_SCHEMA_CONTENT_BASIC: 18040 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18041 break; 18042 default: 18043 xmlGenericError(xmlGenericErrorContext, 18044 "not registered !!!\n"); 18045 break; 18046 } 18047 } 18048} 18049#endif 18050 18051/* 18052* 3.14.6 Constraints on Simple Type Definition Schema Components 18053*/ 18054static int 18055xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18056 xmlSchemaTypePtr type) 18057{ 18058 int res, olderrs = pctxt->nberrors; 18059 18060 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18061 return(-1); 18062 18063 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18064 return(0); 18065 18066 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18067 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18068 18069 if (type->baseType == NULL) { 18070 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18071 "missing baseType"); 18072 goto exit_failure; 18073 } 18074 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18075 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18076 /* 18077 * If a member type of a union is a union itself, we need to substitute 18078 * that member type for its member types. 18079 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18080 * types in WXS 1.1. 18081 */ 18082 if ((type->memberTypes != NULL) && 18083 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18084 return(-1); 18085 /* 18086 * SPEC src-simple-type 1 18087 * "The corresponding simple type definition, if any, must satisfy 18088 * the conditions set out in Constraints on Simple Type Definition 18089 * Schema Components ($3.14.6)." 18090 */ 18091 /* 18092 * Schema Component Constraint: Simple Type Definition Properties Correct 18093 * (st-props-correct) 18094 */ 18095 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18096 HFAILURE HERROR 18097 /* 18098 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18099 * (cos-st-restricts) 18100 */ 18101 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18102 HFAILURE HERROR 18103 /* 18104 * TODO: Removed the error report, since it got annoying to get an 18105 * extra error report, if anything failed until now. 18106 * Enable this if needed. 18107 * 18108 * xmlSchemaPErr(ctxt, type->node, 18109 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18110 * "Simple type '%s' does not satisfy the constraints " 18111 * "on simple type definitions.\n", 18112 * type->name, NULL); 18113 */ 18114 /* 18115 * Schema Component Constraint: Simple Type Restriction (Facets) 18116 * (st-restrict-facets) 18117 */ 18118 res = xmlSchemaCheckFacetValues(type, pctxt); 18119 HFAILURE HERROR 18120 if ((type->facetSet != NULL) || 18121 (type->baseType->facetSet != NULL)) { 18122 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18123 HFAILURE HERROR 18124 } 18125 /* 18126 * Whitespace value. 18127 */ 18128 res = xmlSchemaTypeFixupWhitespace(type); 18129 HFAILURE HERROR 18130 xmlSchemaTypeFixupOptimFacets(type); 18131 18132exit_error: 18133#ifdef DEBUG_TYPE 18134 xmlSchemaDebugFixedType(pctxt, type); 18135#endif 18136 if (olderrs != pctxt->nberrors) 18137 return(pctxt->err); 18138 return(0); 18139 18140exit_failure: 18141#ifdef DEBUG_TYPE 18142 xmlSchemaDebugFixedType(pctxt, type); 18143#endif 18144 return(-1); 18145} 18146 18147static int 18148xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18149 xmlSchemaTypePtr type) 18150{ 18151 int res = 0, olderrs = pctxt->nberrors; 18152 xmlSchemaTypePtr baseType = type->baseType; 18153 18154 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18155 return(0); 18156 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18157 if (baseType == NULL) { 18158 PERROR_INT("xmlSchemaFixupComplexType", 18159 "missing baseType"); 18160 goto exit_failure; 18161 } 18162 /* 18163 * Fixup the base type. 18164 */ 18165 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18166 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18167 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18168 /* 18169 * Skip fixup if the base type is invalid. 18170 * TODO: Generate a warning! 18171 */ 18172 return(0); 18173 } 18174 /* 18175 * This basically checks if the base type can be derived. 18176 */ 18177 res = xmlSchemaCheckSRCCT(pctxt, type); 18178 HFAILURE HERROR 18179 /* 18180 * Fixup the content type. 18181 */ 18182 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18183 /* 18184 * Corresponds to <complexType><simpleContent>... 18185 */ 18186 if ((WXS_IS_COMPLEX(baseType)) && 18187 (baseType->contentTypeDef != NULL) && 18188 (WXS_IS_RESTRICTION(type))) { 18189 xmlSchemaTypePtr contentBase, content; 18190#ifdef ENABLE_NAMED_LOCALS 18191 char buf[30]; 18192 const xmlChar *tmpname; 18193#endif 18194 /* 18195 * SPEC (1) If <restriction> + base type is <complexType>, 18196 * "whose own {content type} is a simple type..." 18197 */ 18198 if (type->contentTypeDef != NULL) { 18199 /* 18200 * SPEC (1.1) "the simple type definition corresponding to the 18201 * <simpleType> among the [children] of <restriction> if there 18202 * is one;" 18203 * Note that this "<simpleType> among the [children]" was put 18204 * into ->contentTypeDef during parsing. 18205 */ 18206 contentBase = type->contentTypeDef; 18207 type->contentTypeDef = NULL; 18208 } else { 18209 /* 18210 * (1.2) "...otherwise (<restriction> has no <simpleType> 18211 * among its [children]), the simple type definition which 18212 * is the {content type} of the ... base type." 18213 */ 18214 contentBase = baseType->contentTypeDef; 18215 } 18216 /* 18217 * SPEC 18218 * "... a simple type definition which restricts the simple 18219 * type definition identified in clause 1.1 or clause 1.2 18220 * with a set of facet components" 18221 * 18222 * Create the anonymous simple type, which will be the content 18223 * type of the complex type. 18224 */ 18225#ifdef ENABLE_NAMED_LOCALS 18226 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18227 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18228 content = xmlSchemaAddType(pctxt, pctxt->schema, 18229 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18230 type->node, 0); 18231#else 18232 content = xmlSchemaAddType(pctxt, pctxt->schema, 18233 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18234 type->node, 0); 18235#endif 18236 if (content == NULL) 18237 goto exit_failure; 18238 /* 18239 * We will use the same node as for the <complexType> 18240 * to have it somehow anchored in the schema doc. 18241 */ 18242 content->type = XML_SCHEMA_TYPE_SIMPLE; 18243 content->baseType = contentBase; 18244 /* 18245 * Move the facets, previously anchored on the 18246 * complexType during parsing. 18247 */ 18248 content->facets = type->facets; 18249 type->facets = NULL; 18250 content->facetSet = type->facetSet; 18251 type->facetSet = NULL; 18252 18253 type->contentTypeDef = content; 18254 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18255 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18256 /* 18257 * Fixup the newly created type. We don't need to check 18258 * for circularity here. 18259 */ 18260 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18261 HFAILURE HERROR 18262 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18263 HFAILURE HERROR 18264 18265 } else if ((WXS_IS_COMPLEX(baseType)) && 18266 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18267 (WXS_IS_RESTRICTION(type))) { 18268 /* 18269 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18270 * an emptiable particle, then a simple type definition which 18271 * restricts the <restriction>'s <simpleType> child. 18272 */ 18273 if ((type->contentTypeDef == NULL) || 18274 (type->contentTypeDef->baseType == NULL)) { 18275 /* 18276 * TODO: Check if this ever happens. 18277 */ 18278 xmlSchemaPCustomErr(pctxt, 18279 XML_SCHEMAP_INTERNAL, 18280 WXS_BASIC_CAST type, NULL, 18281 "Internal error: xmlSchemaTypeFixup, " 18282 "complex type '%s': the <simpleContent><restriction> " 18283 "is missing a <simpleType> child, but was not catched " 18284 "by xmlSchemaCheckSRCCT()", type->name); 18285 goto exit_failure; 18286 } 18287 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18288 /* 18289 * SPEC (3) If <extension> + base is <complexType> with 18290 * <simpleType> content, "...then the {content type} of that 18291 * complex type definition" 18292 */ 18293 if (baseType->contentTypeDef == NULL) { 18294 /* 18295 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18296 * should have catched this already. 18297 */ 18298 xmlSchemaPCustomErr(pctxt, 18299 XML_SCHEMAP_INTERNAL, 18300 WXS_BASIC_CAST type, NULL, 18301 "Internal error: xmlSchemaTypeFixup, " 18302 "complex type '%s': the <extension>ed base type is " 18303 "a complex type with no simple content type", 18304 type->name); 18305 goto exit_failure; 18306 } 18307 type->contentTypeDef = baseType->contentTypeDef; 18308 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18309 /* 18310 * SPEC (4) <extension> + base is <simpleType> 18311 * "... then that simple type definition" 18312 */ 18313 type->contentTypeDef = baseType; 18314 } else { 18315 /* 18316 * TODO: Check if this ever happens. 18317 */ 18318 xmlSchemaPCustomErr(pctxt, 18319 XML_SCHEMAP_INTERNAL, 18320 WXS_BASIC_CAST type, NULL, 18321 "Internal error: xmlSchemaTypeFixup, " 18322 "complex type '%s' with <simpleContent>: unhandled " 18323 "derivation case", type->name); 18324 goto exit_failure; 18325 } 18326 } else { 18327 int dummySequence = 0; 18328 xmlSchemaParticlePtr particle = 18329 (xmlSchemaParticlePtr) type->subtypes; 18330 /* 18331 * Corresponds to <complexType><complexContent>... 18332 * 18333 * NOTE that the effective mixed was already set during parsing of 18334 * <complexType> and <complexContent>; its flag value is 18335 * XML_SCHEMAS_TYPE_MIXED. 18336 * 18337 * Compute the "effective content": 18338 * (2.1.1) + (2.1.2) + (2.1.3) 18339 */ 18340 if ((particle == NULL) || 18341 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18342 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18343 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18344 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18345 (particle->minOccurs == 0))) && 18346 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18347 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18348 /* 18349 * SPEC (2.1.4) "If the `effective mixed` is true, then 18350 * a particle whose properties are as follows:..." 18351 * 18352 * Empty sequence model group with 18353 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18354 * NOTE that we sill assign it the <complexType> node to 18355 * somehow anchor it in the doc. 18356 */ 18357 if ((particle == NULL) || 18358 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18359 /* 18360 * Create the particle. 18361 */ 18362 particle = xmlSchemaAddParticle(pctxt, 18363 type->node, 1, 1); 18364 if (particle == NULL) 18365 goto exit_failure; 18366 /* 18367 * Create the model group. 18368 */ /* URGENT TODO: avoid adding to pending items. */ 18369 particle->children = (xmlSchemaTreeItemPtr) 18370 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18371 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18372 if (particle->children == NULL) 18373 goto exit_failure; 18374 18375 type->subtypes = (xmlSchemaTypePtr) particle; 18376 } 18377 dummySequence = 1; 18378 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18379 } else { 18380 /* 18381 * SPEC (2.1.5) "otherwise empty" 18382 */ 18383 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18384 } 18385 } else { 18386 /* 18387 * SPEC (2.2) "otherwise the particle corresponding to the 18388 * <all>, <choice>, <group> or <sequence> among the 18389 * [children]." 18390 */ 18391 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18392 } 18393 /* 18394 * Compute the "content type". 18395 */ 18396 if (WXS_IS_RESTRICTION(type)) { 18397 /* 18398 * SPEC (3.1) "If <restriction>..." 18399 * (3.1.1) + (3.1.2) */ 18400 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18401 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18402 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18403 } 18404 } else { 18405 /* 18406 * SPEC (3.2) "If <extension>..." 18407 */ 18408 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18409 /* 18410 * SPEC (3.2.1) 18411 * "If the `effective content` is empty, then the 18412 * {content type} of the [...] base ..." 18413 */ 18414 type->contentType = baseType->contentType; 18415 type->subtypes = baseType->subtypes; 18416 /* 18417 * Fixes bug #347316: 18418 * This is the case when the base type has a simple 18419 * type definition as content. 18420 */ 18421 type->contentTypeDef = baseType->contentTypeDef; 18422 /* 18423 * NOTE that the effective mixed is ignored here. 18424 */ 18425 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18426 /* 18427 * SPEC (3.2.2) 18428 */ 18429 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18430 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18431 } else { 18432 /* 18433 * SPEC (3.2.3) 18434 */ 18435 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18436 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18437 /* 18438 * "A model group whose {compositor} is sequence and whose 18439 * {particles} are..." 18440 */ 18441 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18442 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18443 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18444 XML_SCHEMA_TYPE_ALL)) 18445 { 18446 /* 18447 * SPEC cos-all-limited (1) 18448 */ 18449 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18450 /* TODO: error code */ 18451 XML_SCHEMAP_COS_ALL_LIMITED, 18452 WXS_ITEM_NODE(type), NULL, 18453 "The type has an 'all' model group in its " 18454 "{content type} and thus cannot be derived from " 18455 "a non-empty type, since this would produce a " 18456 "'sequence' model group containing the 'all' " 18457 "model group; 'all' model groups are not " 18458 "allowed to appear inside other model groups", 18459 NULL, NULL); 18460 18461 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18462 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18463 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18464 XML_SCHEMA_TYPE_ALL)) 18465 { 18466 /* 18467 * SPEC cos-all-limited (1) 18468 */ 18469 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18470 /* TODO: error code */ 18471 XML_SCHEMAP_COS_ALL_LIMITED, 18472 WXS_ITEM_NODE(type), NULL, 18473 "A type cannot be derived by extension from a type " 18474 "which has an 'all' model group in its " 18475 "{content type}, since this would produce a " 18476 "'sequence' model group containing the 'all' " 18477 "model group; 'all' model groups are not " 18478 "allowed to appear inside other model groups", 18479 NULL, NULL); 18480 18481 } else if (! dummySequence) { 18482 xmlSchemaTreeItemPtr effectiveContent = 18483 (xmlSchemaTreeItemPtr) type->subtypes; 18484 /* 18485 * Create the particle. 18486 */ 18487 particle = xmlSchemaAddParticle(pctxt, 18488 type->node, 1, 1); 18489 if (particle == NULL) 18490 goto exit_failure; 18491 /* 18492 * Create the "sequence" model group. 18493 */ 18494 particle->children = (xmlSchemaTreeItemPtr) 18495 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18496 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18497 if (particle->children == NULL) 18498 goto exit_failure; 18499 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18500 /* 18501 * SPEC "the particle of the {content type} of 18502 * the ... base ..." 18503 * Create a duplicate of the base type's particle 18504 * and assign its "term" to it. 18505 */ 18506 particle->children->children = 18507 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18508 type->node, 18509 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18510 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18511 if (particle->children->children == NULL) 18512 goto exit_failure; 18513 particle = (xmlSchemaParticlePtr) 18514 particle->children->children; 18515 particle->children = 18516 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18517 /* 18518 * SPEC "followed by the `effective content`." 18519 */ 18520 particle->next = effectiveContent; 18521 /* 18522 * This all will result in: 18523 * new-particle 18524 * --> new-sequence( 18525 * new-particle 18526 * --> base-model, 18527 * this-particle 18528 * --> this-model 18529 * ) 18530 */ 18531 } else { 18532 /* 18533 * This is the case when there is already an empty 18534 * <sequence> with minOccurs==maxOccurs==1. 18535 * Just add the base types's content type. 18536 * NOTE that, although we miss to add an intermediate 18537 * <sequence>, this should produce no difference to 18538 * neither the regex compilation of the content model, 18539 * nor to the complex type contraints. 18540 */ 18541 particle->children->children = 18542 (xmlSchemaTreeItemPtr) baseType->subtypes; 18543 } 18544 } 18545 } 18546 } 18547 /* 18548 * Now fixup attribute uses: 18549 * - expand attr. group references 18550 * - intersect attribute wildcards 18551 * - inherit attribute uses of the base type 18552 * - inherit or union attr. wildcards if extending 18553 * - apply attr. use prohibitions if restricting 18554 */ 18555 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18556 HFAILURE HERROR 18557 /* 18558 * Apply the complex type component constraints; this will not 18559 * check attributes, since this is done in 18560 * xmlSchemaFixupTypeAttributeUses(). 18561 */ 18562 res = xmlSchemaCheckCTComponent(pctxt, type); 18563 HFAILURE HERROR 18564 18565#ifdef DEBUG_TYPE 18566 xmlSchemaDebugFixedType(pctxt, type); 18567#endif 18568 if (olderrs != pctxt->nberrors) 18569 return(pctxt->err); 18570 else 18571 return(0); 18572 18573exit_error: 18574 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18575#ifdef DEBUG_TYPE 18576 xmlSchemaDebugFixedType(pctxt, type); 18577#endif 18578 return(pctxt->err); 18579 18580exit_failure: 18581 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18582#ifdef DEBUG_TYPE 18583 xmlSchemaDebugFixedType(pctxt, type); 18584#endif 18585 return(-1); 18586} 18587 18588 18589/** 18590 * xmlSchemaTypeFixup: 18591 * @typeDecl: the schema type definition 18592 * @ctxt: the schema parser context 18593 * 18594 * Fixes the content model of the type. 18595 * URGENT TODO: We need an int result! 18596 */ 18597static int 18598xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18599 xmlSchemaAbstractCtxtPtr actxt) 18600{ 18601 if (type == NULL) 18602 return(0); 18603 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18604 AERROR_INT("xmlSchemaTypeFixup", 18605 "this function needs a parser context"); 18606 return(-1); 18607 } 18608 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18609 return(0); 18610 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18611 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18612 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18613 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18614 return(0); 18615} 18616 18617/** 18618 * xmlSchemaCheckFacet: 18619 * @facet: the facet 18620 * @typeDecl: the schema type definition 18621 * @pctxt: the schema parser context or NULL 18622 * @name: the optional name of the type 18623 * 18624 * Checks and computes the values of facets. 18625 * 18626 * Returns 0 if valid, a positive error code if not valid and 18627 * -1 in case of an internal or API error. 18628 */ 18629int 18630xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18631 xmlSchemaTypePtr typeDecl, 18632 xmlSchemaParserCtxtPtr pctxt, 18633 const xmlChar * name ATTRIBUTE_UNUSED) 18634{ 18635 int ret = 0, ctxtGiven; 18636 18637 if ((facet == NULL) || (typeDecl == NULL)) 18638 return(-1); 18639 /* 18640 * TODO: will the parser context be given if used from 18641 * the relaxNG module? 18642 */ 18643 if (pctxt == NULL) 18644 ctxtGiven = 0; 18645 else 18646 ctxtGiven = 1; 18647 18648 switch (facet->type) { 18649 case XML_SCHEMA_FACET_MININCLUSIVE: 18650 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18651 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18652 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18653 case XML_SCHEMA_FACET_ENUMERATION: { 18654 /* 18655 * Okay we need to validate the value 18656 * at that point. 18657 */ 18658 xmlSchemaTypePtr base; 18659 18660 /* 4.3.5.5 Constraints on enumeration Schema Components 18661 * Schema Component Constraint: enumeration valid restriction 18662 * It is an `error` if any member of {value} is not in the 18663 * `value space` of {base type definition}. 18664 * 18665 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18666 * The value `must` be in the 18667 * `value space` of the `base type`. 18668 */ 18669 /* 18670 * This function is intended to deliver a compiled value 18671 * on the facet. In this implementation of XML Schemata the 18672 * type holding a facet, won't be a built-in type. 18673 * Thus to ensure that other API 18674 * calls (relaxng) do work, if the given type is a built-in 18675 * type, we will assume that the given built-in type *is 18676 * already* the base type. 18677 */ 18678 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18679 base = typeDecl->baseType; 18680 if (base == NULL) { 18681 PERROR_INT("xmlSchemaCheckFacet", 18682 "a type user derived type has no base type"); 18683 return (-1); 18684 } 18685 } else 18686 base = typeDecl; 18687 18688 if (! ctxtGiven) { 18689 /* 18690 * A context is needed if called from RelaxNG. 18691 */ 18692 pctxt = xmlSchemaNewParserCtxt("*"); 18693 if (pctxt == NULL) 18694 return (-1); 18695 } 18696 /* 18697 * NOTE: This call does not check the content nodes, 18698 * since they are not available: 18699 * facet->node is just the node holding the facet 18700 * definition, *not* the attribute holding the *value* 18701 * of the facet. 18702 */ 18703 ret = xmlSchemaVCheckCVCSimpleType( 18704 ACTXT_CAST pctxt, facet->node, base, 18705 facet->value, &(facet->val), 1, 1, 0); 18706 if (ret != 0) { 18707 if (ret < 0) { 18708 /* No error message for RelaxNG. */ 18709 if (ctxtGiven) { 18710 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18711 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18712 "Internal error: xmlSchemaCheckFacet, " 18713 "failed to validate the value '%s' of the " 18714 "facet '%s' against the base type", 18715 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18716 } 18717 goto internal_error; 18718 } 18719 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18720 /* No error message for RelaxNG. */ 18721 if (ctxtGiven) { 18722 xmlChar *str = NULL; 18723 18724 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18725 ret, facet->node, WXS_BASIC_CAST facet, 18726 "The value '%s' of the facet does not validate " 18727 "against the base type '%s'", 18728 facet->value, 18729 xmlSchemaFormatQName(&str, 18730 base->targetNamespace, base->name)); 18731 FREE_AND_NULL(str); 18732 } 18733 goto exit; 18734 } else if (facet->val == NULL) { 18735 if (ctxtGiven) { 18736 PERROR_INT("xmlSchemaCheckFacet", 18737 "value was not computed"); 18738 } 18739 TODO 18740 } 18741 break; 18742 } 18743 case XML_SCHEMA_FACET_PATTERN: 18744 facet->regexp = xmlRegexpCompile(facet->value); 18745 if (facet->regexp == NULL) { 18746 ret = XML_SCHEMAP_REGEXP_INVALID; 18747 /* No error message for RelaxNG. */ 18748 if (ctxtGiven) { 18749 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18750 ret, facet->node, WXS_BASIC_CAST typeDecl, 18751 "The value '%s' of the facet 'pattern' is not a " 18752 "valid regular expression", 18753 facet->value, NULL); 18754 } 18755 } 18756 break; 18757 case XML_SCHEMA_FACET_TOTALDIGITS: 18758 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18759 case XML_SCHEMA_FACET_LENGTH: 18760 case XML_SCHEMA_FACET_MAXLENGTH: 18761 case XML_SCHEMA_FACET_MINLENGTH: 18762 18763 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18764 ret = xmlSchemaValidatePredefinedType( 18765 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18766 facet->value, &(facet->val)); 18767 } else { 18768 ret = xmlSchemaValidatePredefinedType( 18769 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18770 facet->value, &(facet->val)); 18771 } 18772 if (ret != 0) { 18773 if (ret < 0) { 18774 /* No error message for RelaxNG. */ 18775 if (ctxtGiven) { 18776 PERROR_INT("xmlSchemaCheckFacet", 18777 "validating facet value"); 18778 } 18779 goto internal_error; 18780 } 18781 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18782 /* No error message for RelaxNG. */ 18783 if (ctxtGiven) { 18784 /* error code */ 18785 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18786 ret, facet->node, WXS_BASIC_CAST typeDecl, 18787 "The value '%s' of the facet '%s' is not a valid '%s'", 18788 facet->value, 18789 xmlSchemaFacetTypeToString(facet->type), 18790 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18791 BAD_CAST "nonNegativeInteger" : 18792 BAD_CAST "positiveInteger", 18793 NULL); 18794 } 18795 } 18796 break; 18797 18798 case XML_SCHEMA_FACET_WHITESPACE:{ 18799 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18800 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18801 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18802 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18803 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18804 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18805 } else { 18806 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18807 /* No error message for RelaxNG. */ 18808 if (ctxtGiven) { 18809 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18810 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18811 ret, facet->node, WXS_BASIC_CAST typeDecl, 18812 "The value '%s' of the facet 'whitespace' is not " 18813 "valid", facet->value, NULL); 18814 } 18815 } 18816 } 18817 default: 18818 break; 18819 } 18820exit: 18821 if ((! ctxtGiven) && (pctxt != NULL)) 18822 xmlSchemaFreeParserCtxt(pctxt); 18823 return (ret); 18824internal_error: 18825 if ((! ctxtGiven) && (pctxt != NULL)) 18826 xmlSchemaFreeParserCtxt(pctxt); 18827 return (-1); 18828} 18829 18830/** 18831 * xmlSchemaCheckFacetValues: 18832 * @typeDecl: the schema type definition 18833 * @ctxt: the schema parser context 18834 * 18835 * Checks the default values types, especially for facets 18836 */ 18837static int 18838xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18839 xmlSchemaParserCtxtPtr pctxt) 18840{ 18841 int res, olderrs = pctxt->nberrors; 18842 const xmlChar *name = typeDecl->name; 18843 /* 18844 * NOTE: It is intended to use the facets list, instead 18845 * of facetSet. 18846 */ 18847 if (typeDecl->facets != NULL) { 18848 xmlSchemaFacetPtr facet = typeDecl->facets; 18849 18850 /* 18851 * Temporarily assign the "schema" to the validation context 18852 * of the parser context. This is needed for NOTATION validation. 18853 */ 18854 if (pctxt->vctxt == NULL) { 18855 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18856 return(-1); 18857 } 18858 pctxt->vctxt->schema = pctxt->schema; 18859 while (facet != NULL) { 18860 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18861 HFAILURE 18862 facet = facet->next; 18863 } 18864 pctxt->vctxt->schema = NULL; 18865 } 18866 if (olderrs != pctxt->nberrors) 18867 return(pctxt->err); 18868 return(0); 18869exit_failure: 18870 return(-1); 18871} 18872 18873/** 18874 * xmlSchemaGetCircModelGrDefRef: 18875 * @ctxtMGroup: the searched model group 18876 * @selfMGroup: the second searched model group 18877 * @particle: the first particle 18878 * 18879 * This one is intended to be used by 18880 * xmlSchemaCheckGroupDefCircular only. 18881 * 18882 * Returns the particle with the circular model group definition reference, 18883 * otherwise NULL. 18884 */ 18885static xmlSchemaTreeItemPtr 18886xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18887 xmlSchemaTreeItemPtr particle) 18888{ 18889 xmlSchemaTreeItemPtr circ = NULL; 18890 xmlSchemaTreeItemPtr term; 18891 xmlSchemaModelGroupDefPtr gdef; 18892 18893 for (; particle != NULL; particle = particle->next) { 18894 term = particle->children; 18895 if (term == NULL) 18896 continue; 18897 switch (term->type) { 18898 case XML_SCHEMA_TYPE_GROUP: 18899 gdef = (xmlSchemaModelGroupDefPtr) term; 18900 if (gdef == groupDef) 18901 return (particle); 18902 /* 18903 * Mark this model group definition to avoid infinite 18904 * recursion on circular references not yet examined. 18905 */ 18906 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18907 continue; 18908 if (gdef->children != NULL) { 18909 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18910 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18911 gdef->children->children); 18912 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18913 if (circ != NULL) 18914 return (circ); 18915 } 18916 break; 18917 case XML_SCHEMA_TYPE_SEQUENCE: 18918 case XML_SCHEMA_TYPE_CHOICE: 18919 case XML_SCHEMA_TYPE_ALL: 18920 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18921 if (circ != NULL) 18922 return (circ); 18923 break; 18924 default: 18925 break; 18926 } 18927 } 18928 return (NULL); 18929} 18930 18931/** 18932 * xmlSchemaCheckGroupDefCircular: 18933 * @item: the model group definition 18934 * @ctxt: the parser context 18935 * @name: the name 18936 * 18937 * Checks for circular references to model group definitions. 18938 */ 18939static void 18940xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18941 xmlSchemaParserCtxtPtr ctxt) 18942{ 18943 /* 18944 * Schema Component Constraint: Model Group Correct 18945 * 2 Circular groups are disallowed. That is, within the {particles} 18946 * of a group there must not be at any depth a particle whose {term} 18947 * is the group itself. 18948 */ 18949 if ((item == NULL) || 18950 (item->type != XML_SCHEMA_TYPE_GROUP) || 18951 (item->children == NULL)) 18952 return; 18953 { 18954 xmlSchemaTreeItemPtr circ; 18955 18956 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18957 if (circ != NULL) { 18958 xmlChar *str = NULL; 18959 /* 18960 * TODO: The error report is not adequate: this constraint 18961 * is defined for model groups but not definitions, but since 18962 * there cannot be any circular model groups without a model group 18963 * definition (if not using a construction API), we check those 18964 * defintions only. 18965 */ 18966 xmlSchemaPCustomErr(ctxt, 18967 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18968 NULL, WXS_ITEM_NODE(circ), 18969 "Circular reference to the model group definition '%s' " 18970 "defined", xmlSchemaFormatQName(&str, 18971 item->targetNamespace, item->name)); 18972 FREE_AND_NULL(str) 18973 /* 18974 * NOTE: We will cut the reference to avoid further 18975 * confusion of the processor. This is a fatal error. 18976 */ 18977 circ->children = NULL; 18978 } 18979 } 18980} 18981 18982/** 18983 * xmlSchemaModelGroupToModelGroupDefFixup: 18984 * @ctxt: the parser context 18985 * @mg: the model group 18986 * 18987 * Assigns the model group of model group definitions to the "term" 18988 * of the referencing particle. 18989 * In xmlSchemaResolveModelGroupParticleReferences the model group 18990 * definitions were assigned to the "term", since needed for the 18991 * circularity check. 18992 * 18993 * Schema Component Constraint: 18994 * All Group Limited (cos-all-limited) (1.2) 18995 */ 18996static void 18997xmlSchemaModelGroupToModelGroupDefFixup( 18998 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 18999 xmlSchemaModelGroupPtr mg) 19000{ 19001 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19002 19003 while (particle != NULL) { 19004 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19005 ((WXS_PARTICLE_TERM(particle))->type != 19006 XML_SCHEMA_TYPE_GROUP)) 19007 { 19008 particle = WXS_PTC_CAST particle->next; 19009 continue; 19010 } 19011 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19012 /* 19013 * TODO: Remove the particle. 19014 */ 19015 WXS_PARTICLE_TERM(particle) = NULL; 19016 particle = WXS_PTC_CAST particle->next; 19017 continue; 19018 } 19019 /* 19020 * Assign the model group to the {term} of the particle. 19021 */ 19022 WXS_PARTICLE_TERM(particle) = 19023 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19024 19025 particle = WXS_PTC_CAST particle->next; 19026 } 19027} 19028 19029/** 19030 * xmlSchemaCheckAttrGroupCircularRecur: 19031 * @ctxtGr: the searched attribute group 19032 * @attr: the current attribute list to be processed 19033 * 19034 * This one is intended to be used by 19035 * xmlSchemaCheckAttrGroupCircular only. 19036 * 19037 * Returns the circular attribute grou reference, otherwise NULL. 19038 */ 19039static xmlSchemaQNameRefPtr 19040xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19041 xmlSchemaItemListPtr list) 19042{ 19043 xmlSchemaAttributeGroupPtr gr; 19044 xmlSchemaQNameRefPtr ref, circ; 19045 int i; 19046 /* 19047 * We will search for an attribute group reference which 19048 * references the context attribute group. 19049 */ 19050 for (i = 0; i < list->nbItems; i++) { 19051 ref = list->items[i]; 19052 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19053 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19054 (ref->item != NULL)) 19055 { 19056 gr = WXS_ATTR_GROUP_CAST ref->item; 19057 if (gr == ctxtGr) 19058 return(ref); 19059 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19060 continue; 19061 /* 19062 * Mark as visited to avoid infinite recursion on 19063 * circular references not yet examined. 19064 */ 19065 if ((gr->attrUses) && 19066 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19067 { 19068 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19069 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19070 (xmlSchemaItemListPtr) gr->attrUses); 19071 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19072 if (circ != NULL) 19073 return (circ); 19074 } 19075 19076 } 19077 } 19078 return (NULL); 19079} 19080 19081/** 19082 * xmlSchemaCheckAttrGroupCircular: 19083 * attrGr: the attribute group definition 19084 * @ctxt: the parser context 19085 * @name: the name 19086 * 19087 * Checks for circular references of attribute groups. 19088 */ 19089static int 19090xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19091 xmlSchemaParserCtxtPtr ctxt) 19092{ 19093 /* 19094 * Schema Representation Constraint: 19095 * Attribute Group Definition Representation OK 19096 * 3 Circular group reference is disallowed outside <redefine>. 19097 * That is, unless this element information item's parent is 19098 * <redefine>, then among the [children], if any, there must 19099 * not be an <attributeGroup> with ref [attribute] which resolves 19100 * to the component corresponding to this <attributeGroup>. Indirect 19101 * circularity is also ruled out. That is, when QName resolution 19102 * (Schema Document) ($3.15.3) is applied to a `QName` arising from 19103 * any <attributeGroup>s with a ref [attribute] among the [children], 19104 * it must not be the case that a `QName` is encountered at any depth 19105 * which resolves to the component corresponding to this <attributeGroup>. 19106 */ 19107 if (attrGr->attrUses == NULL) 19108 return(0); 19109 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19110 return(0); 19111 else { 19112 xmlSchemaQNameRefPtr circ; 19113 19114 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19115 (xmlSchemaItemListPtr) attrGr->attrUses); 19116 if (circ != NULL) { 19117 xmlChar *str = NULL; 19118 /* 19119 * TODO: Report the referenced attr group as QName. 19120 */ 19121 xmlSchemaPCustomErr(ctxt, 19122 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19123 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19124 "Circular reference to the attribute group '%s' " 19125 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19126 FREE_AND_NULL(str); 19127 /* 19128 * NOTE: We will cut the reference to avoid further 19129 * confusion of the processor. 19130 * BADSPEC TODO: The spec should define how to process in this case. 19131 */ 19132 circ->item = NULL; 19133 return(ctxt->err); 19134 } 19135 } 19136 return(0); 19137} 19138 19139static int 19140xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19141 xmlSchemaAttributeGroupPtr attrGr); 19142 19143/** 19144 * xmlSchemaExpandAttributeGroupRefs: 19145 * @pctxt: the parser context 19146 * @node: the node of the component holding the attribute uses 19147 * @completeWild: the intersected wildcard to be returned 19148 * @list: the attribute uses 19149 * 19150 * Substitutes contained attribute group references 19151 * for their attribute uses. Wilcards are intersected. 19152 * Attribute use prohibitions are removed from the list 19153 * and returned via the @prohibs list. 19154 * Pointlessness of attr. prohibs, if a matching attr. decl 19155 * is existent a well, are checked. 19156 */ 19157static int 19158xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19159 xmlSchemaBasicItemPtr item, 19160 xmlSchemaWildcardPtr *completeWild, 19161 xmlSchemaItemListPtr list, 19162 xmlSchemaItemListPtr prohibs) 19163{ 19164 xmlSchemaAttributeGroupPtr gr; 19165 xmlSchemaAttributeUsePtr use; 19166 xmlSchemaItemListPtr sublist; 19167 int i, j; 19168 int created = (*completeWild == NULL) ? 0 : 1; 19169 19170 if (prohibs) 19171 prohibs->nbItems = 0; 19172 19173 for (i = 0; i < list->nbItems; i++) { 19174 use = list->items[i]; 19175 19176 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19177 if (prohibs == NULL) { 19178 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19179 "unexpected attr prohibition found"); 19180 return(-1); 19181 } 19182 /* 19183 * Remove from attribute uses. 19184 */ 19185 if (xmlSchemaItemListRemove(list, i) == -1) 19186 return(-1); 19187 i--; 19188 /* 19189 * Note that duplicate prohibitions were already 19190 * handled at parsing time. 19191 */ 19192 /* 19193 * Add to list of prohibitions. 19194 */ 19195 xmlSchemaItemListAddSize(prohibs, 2, use); 19196 continue; 19197 } 19198 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19199 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19200 { 19201 if ((WXS_QNAME_CAST use)->item == NULL) 19202 return(-1); 19203 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19204 /* 19205 * Expand the referenced attr. group. 19206 * TODO: remove this, this is done in a previous step, so 19207 * already done here. 19208 */ 19209 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19210 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19211 return(-1); 19212 } 19213 /* 19214 * Build the 'complete' wildcard; i.e. intersect multiple 19215 * wildcards. 19216 */ 19217 if (gr->attributeWildcard != NULL) { 19218 if (*completeWild == NULL) { 19219 *completeWild = gr->attributeWildcard; 19220 } else { 19221 if (! created) { 19222 xmlSchemaWildcardPtr tmpWild; 19223 19224 /* 19225 * Copy the first encountered wildcard as context, 19226 * except for the annotation. 19227 * 19228 * Although the complete wildcard might not correspond 19229 * to any node in the schema, we will anchor it on 19230 * the node of the owner component. 19231 */ 19232 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19233 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19234 WXS_ITEM_NODE(item)); 19235 if (tmpWild == NULL) 19236 return(-1); 19237 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19238 tmpWild, *completeWild) == -1) 19239 return (-1); 19240 tmpWild->processContents = (*completeWild)->processContents; 19241 *completeWild = tmpWild; 19242 created = 1; 19243 } 19244 19245 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19246 gr->attributeWildcard) == -1) 19247 return(-1); 19248 } 19249 } 19250 /* 19251 * Just remove the reference if the referenced group does not 19252 * contain any attribute uses. 19253 */ 19254 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19255 if ((sublist == NULL) || sublist->nbItems == 0) { 19256 if (xmlSchemaItemListRemove(list, i) == -1) 19257 return(-1); 19258 i--; 19259 continue; 19260 } 19261 /* 19262 * Add the attribute uses. 19263 */ 19264 list->items[i] = sublist->items[0]; 19265 if (sublist->nbItems != 1) { 19266 for (j = 1; j < sublist->nbItems; j++) { 19267 i++; 19268 if (xmlSchemaItemListInsert(list, 19269 sublist->items[j], i) == -1) 19270 return(-1); 19271 } 19272 } 19273 } 19274 19275 } 19276 /* 19277 * Handle pointless prohibitions of declared attributes. 19278 */ 19279 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19280 xmlSchemaAttributeUseProhibPtr prohib; 19281 19282 for (i = prohibs->nbItems -1; i >= 0; i--) { 19283 prohib = prohibs->items[i]; 19284 for (j = 0; j < list->nbItems; j++) { 19285 use = list->items[j]; 19286 19287 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19288 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19289 { 19290 xmlChar *str = NULL; 19291 19292 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19293 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19294 prohib->node, NULL, 19295 "Skipping pointless attribute use prohibition " 19296 "'%s', since a corresponding attribute use " 19297 "exists already in the type definition", 19298 xmlSchemaFormatQName(&str, 19299 prohib->targetNamespace, prohib->name), 19300 NULL, NULL); 19301 FREE_AND_NULL(str); 19302 /* 19303 * Remove the prohibition. 19304 */ 19305 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19306 return(-1); 19307 break; 19308 } 19309 } 19310 } 19311 } 19312 return(0); 19313} 19314 19315/** 19316 * xmlSchemaAttributeGroupExpandRefs: 19317 * @pctxt: the parser context 19318 * @attrGr: the attribute group definition 19319 * 19320 * Computation of: 19321 * {attribute uses} property 19322 * {attribute wildcard} property 19323 * 19324 * Substitutes contained attribute group references 19325 * for their attribute uses. Wilcards are intersected. 19326 */ 19327static int 19328xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19329 xmlSchemaAttributeGroupPtr attrGr) 19330{ 19331 if ((attrGr->attrUses == NULL) || 19332 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19333 return(0); 19334 19335 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19336 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19337 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19338 return(-1); 19339 return(0); 19340} 19341 19342/** 19343 * xmlSchemaAttributeGroupExpandRefs: 19344 * @pctxt: the parser context 19345 * @attrGr: the attribute group definition 19346 * 19347 * Substitutes contained attribute group references 19348 * for their attribute uses. Wilcards are intersected. 19349 * 19350 * Schema Component Constraint: 19351 * Attribute Group Definition Properties Correct (ag-props-correct) 19352 */ 19353static int 19354xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19355 xmlSchemaAttributeGroupPtr attrGr) 19356{ 19357 /* 19358 * SPEC ag-props-correct 19359 * (1) "The values of the properties of an attribute group definition 19360 * must be as described in the property tableau in The Attribute 19361 * Group Definition Schema Component ($3.6.1), modulo the impact of 19362 * Missing Sub-components ($5.3);" 19363 */ 19364 19365 if ((attrGr->attrUses != NULL) && 19366 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19367 { 19368 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19369 xmlSchemaAttributeUsePtr use, tmp; 19370 int i, j, hasId = 0; 19371 19372 for (i = uses->nbItems -1; i >= 0; i--) { 19373 use = uses->items[i]; 19374 /* 19375 * SPEC ag-props-correct 19376 * (2) "Two distinct members of the {attribute uses} must not have 19377 * {attribute declaration}s both of whose {name}s match and whose 19378 * {target namespace}s are identical." 19379 */ 19380 if (i > 0) { 19381 for (j = i -1; j >= 0; j--) { 19382 tmp = uses->items[j]; 19383 if ((WXS_ATTRUSE_DECL_NAME(use) == 19384 WXS_ATTRUSE_DECL_NAME(tmp)) && 19385 (WXS_ATTRUSE_DECL_TNS(use) == 19386 WXS_ATTRUSE_DECL_TNS(tmp))) 19387 { 19388 xmlChar *str = NULL; 19389 19390 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19391 XML_SCHEMAP_AG_PROPS_CORRECT, 19392 attrGr->node, WXS_BASIC_CAST attrGr, 19393 "Duplicate %s", 19394 xmlSchemaGetComponentDesignation(&str, use), 19395 NULL); 19396 FREE_AND_NULL(str); 19397 /* 19398 * Remove the duplicate. 19399 */ 19400 if (xmlSchemaItemListRemove(uses, i) == -1) 19401 return(-1); 19402 goto next_use; 19403 } 19404 } 19405 } 19406 /* 19407 * SPEC ag-props-correct 19408 * (3) "Two distinct members of the {attribute uses} must not have 19409 * {attribute declaration}s both of whose {type definition}s are or 19410 * are derived from ID." 19411 * TODO: Does 'derived' include member-types of unions? 19412 */ 19413 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19414 if (xmlSchemaIsDerivedFromBuiltInType( 19415 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19416 { 19417 if (hasId) { 19418 xmlChar *str = NULL; 19419 19420 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19421 XML_SCHEMAP_AG_PROPS_CORRECT, 19422 attrGr->node, WXS_BASIC_CAST attrGr, 19423 "There must not exist more than one attribute " 19424 "declaration of type 'xs:ID' " 19425 "(or derived from 'xs:ID'). The %s violates this " 19426 "constraint", 19427 xmlSchemaGetComponentDesignation(&str, use), 19428 NULL); 19429 FREE_AND_NULL(str); 19430 if (xmlSchemaItemListRemove(uses, i) == -1) 19431 return(-1); 19432 } 19433 hasId = 1; 19434 } 19435 } 19436next_use: {} 19437 } 19438 } 19439 return(0); 19440} 19441 19442/** 19443 * xmlSchemaResolveAttrGroupReferences: 19444 * @attrgrpDecl: the schema attribute definition 19445 * @ctxt: the schema parser context 19446 * @name: the attribute name 19447 * 19448 * Resolves references to attribute group definitions. 19449 */ 19450static int 19451xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19452 xmlSchemaParserCtxtPtr ctxt) 19453{ 19454 xmlSchemaAttributeGroupPtr group; 19455 19456 if (ref->item != NULL) 19457 return(0); 19458 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19459 ref->name, 19460 ref->targetNamespace); 19461 if (group == NULL) { 19462 xmlSchemaPResCompAttrErr(ctxt, 19463 XML_SCHEMAP_SRC_RESOLVE, 19464 NULL, ref->node, 19465 "ref", ref->name, ref->targetNamespace, 19466 ref->itemType, NULL); 19467 return(ctxt->err); 19468 } 19469 ref->item = WXS_BASIC_CAST group; 19470 return(0); 19471} 19472 19473/** 19474 * xmlSchemaCheckAttrPropsCorrect: 19475 * @item: an schema attribute declaration/use 19476 * @ctxt: a schema parser context 19477 * @name: the name of the attribute 19478 * 19479 * 19480 * Schema Component Constraint: 19481 * Attribute Declaration Properties Correct (a-props-correct) 19482 * 19483 * Validates the value constraints of an attribute declaration/use. 19484 * NOTE that this needs the simle type definitions to be already 19485 * builded and checked. 19486 */ 19487static int 19488xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19489 xmlSchemaAttributePtr attr) 19490{ 19491 19492 /* 19493 * SPEC a-props-correct (1) 19494 * "The values of the properties of an attribute declaration must 19495 * be as described in the property tableau in The Attribute 19496 * Declaration Schema Component ($3.2.1), modulo the impact of 19497 * Missing Sub-components ($5.3)." 19498 */ 19499 19500 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19501 return(0); 19502 19503 if (attr->defValue != NULL) { 19504 int ret; 19505 19506 /* 19507 * SPEC a-props-correct (3) 19508 * "If the {type definition} is or is derived from ID then there 19509 * must not be a {value constraint}." 19510 */ 19511 if (xmlSchemaIsDerivedFromBuiltInType( 19512 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19513 { 19514 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19515 XML_SCHEMAP_A_PROPS_CORRECT_3, 19516 NULL, WXS_BASIC_CAST attr, 19517 "Value constraints are not allowed if the type definition " 19518 "is or is derived from xs:ID", 19519 NULL, NULL); 19520 return(pctxt->err); 19521 } 19522 /* 19523 * SPEC a-props-correct (2) 19524 * "if there is a {value constraint}, the canonical lexical 19525 * representation of its value must be `valid` with respect 19526 * to the {type definition} as defined in String Valid ($3.14.4)." 19527 * TODO: Don't care about the *canonical* stuff here, this requirement 19528 * will be removed in WXS 1.1 anyway. 19529 */ 19530 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19531 attr->node, WXS_ATTR_TYPEDEF(attr), 19532 attr->defValue, &(attr->defVal), 19533 1, 1, 0); 19534 if (ret != 0) { 19535 if (ret < 0) { 19536 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19537 "calling xmlSchemaVCheckCVCSimpleType()"); 19538 return(-1); 19539 } 19540 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19541 XML_SCHEMAP_A_PROPS_CORRECT_2, 19542 NULL, WXS_BASIC_CAST attr, 19543 "The value of the value constraint is not valid", 19544 NULL, NULL); 19545 return(pctxt->err); 19546 } 19547 } 19548 19549 return(0); 19550} 19551 19552static xmlSchemaElementPtr 19553xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19554 xmlSchemaElementPtr ancestor) 19555{ 19556 xmlSchemaElementPtr ret; 19557 19558 if (WXS_SUBST_HEAD(ancestor) == NULL) 19559 return (NULL); 19560 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19561 return (ancestor); 19562 19563 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19564 return (NULL); 19565 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19566 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19567 WXS_SUBST_HEAD(ancestor)); 19568 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19569 19570 return (ret); 19571} 19572 19573/** 19574 * xmlSchemaCheckElemPropsCorrect: 19575 * @ctxt: a schema parser context 19576 * @decl: the element declaration 19577 * @name: the name of the attribute 19578 * 19579 * Schema Component Constraint: 19580 * Element Declaration Properties Correct (e-props-correct) 19581 * 19582 * STATUS: 19583 * missing: (6) 19584 */ 19585static int 19586xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19587 xmlSchemaElementPtr elemDecl) 19588{ 19589 int ret = 0; 19590 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19591 /* 19592 * SPEC (1) "The values of the properties of an element declaration 19593 * must be as described in the property tableau in The Element 19594 * Declaration Schema Component ($3.3.1), modulo the impact of Missing 19595 * Sub-components ($5.3)." 19596 */ 19597 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19598 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19599 19600 xmlSchemaCheckElementDeclComponent(head, pctxt); 19601 /* 19602 * SPEC (3) "If there is a non-`absent` {substitution group 19603 * affiliation}, then {scope} must be global." 19604 */ 19605 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19606 xmlSchemaPCustomErr(pctxt, 19607 XML_SCHEMAP_E_PROPS_CORRECT_3, 19608 WXS_BASIC_CAST elemDecl, NULL, 19609 "Only global element declarations can have a " 19610 "substitution group affiliation", NULL); 19611 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19612 } 19613 /* 19614 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19615 * That is, it must not be possible to return to an element declaration 19616 * by repeatedly following the {substitution group affiliation} 19617 * property." 19618 */ 19619 if (head == elemDecl) 19620 circ = head; 19621 else if (WXS_SUBST_HEAD(head) != NULL) 19622 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19623 else 19624 circ = NULL; 19625 if (circ != NULL) { 19626 xmlChar *strA = NULL, *strB = NULL; 19627 19628 xmlSchemaPCustomErrExt(pctxt, 19629 XML_SCHEMAP_E_PROPS_CORRECT_6, 19630 WXS_BASIC_CAST circ, NULL, 19631 "The element declaration '%s' defines a circular " 19632 "substitution group to element declaration '%s'", 19633 xmlSchemaGetComponentQName(&strA, circ), 19634 xmlSchemaGetComponentQName(&strB, head), 19635 NULL); 19636 FREE_AND_NULL(strA) 19637 FREE_AND_NULL(strB) 19638 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19639 } 19640 /* 19641 * SPEC (4) "If there is a {substitution group affiliation}, 19642 * the {type definition} 19643 * of the element declaration must be validly derived from the {type 19644 * definition} of the {substitution group affiliation}, given the value 19645 * of the {substitution group exclusions} of the {substitution group 19646 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6) 19647 * (if the {type definition} is complex) or as defined in 19648 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is 19649 * simple)." 19650 * 19651 * NOTE: {substitution group exclusions} means the values of the 19652 * attribute "final". 19653 */ 19654 19655 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19656 int set = 0; 19657 19658 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19659 set |= SUBSET_EXTENSION; 19660 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19661 set |= SUBSET_RESTRICTION; 19662 19663 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19664 WXS_ELEM_TYPEDEF(head), set) != 0) { 19665 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19666 19667 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19668 xmlSchemaPCustomErrExt(pctxt, 19669 XML_SCHEMAP_E_PROPS_CORRECT_4, 19670 WXS_BASIC_CAST elemDecl, NULL, 19671 "The type definition '%s' was " 19672 "either rejected by the substitution group " 19673 "affiliation '%s', or not validly derived from its type " 19674 "definition '%s'", 19675 xmlSchemaGetComponentQName(&strA, typeDef), 19676 xmlSchemaGetComponentQName(&strB, head), 19677 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19678 FREE_AND_NULL(strA) 19679 FREE_AND_NULL(strB) 19680 FREE_AND_NULL(strC) 19681 } 19682 } 19683 } 19684 /* 19685 * SPEC (5) "If the {type definition} or {type definition}'s 19686 * {content type} 19687 * is or is derived from ID then there must not be a {value constraint}. 19688 * Note: The use of ID as a type definition for elements goes beyond 19689 * XML 1.0, and should be avoided if backwards compatibility is desired" 19690 */ 19691 if ((elemDecl->value != NULL) && 19692 ((WXS_IS_SIMPLE(typeDef) && 19693 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19694 (WXS_IS_COMPLEX(typeDef) && 19695 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19696 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19697 XML_SCHEMAS_ID)))) { 19698 19699 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19700 xmlSchemaPCustomErr(pctxt, 19701 XML_SCHEMAP_E_PROPS_CORRECT_5, 19702 WXS_BASIC_CAST elemDecl, NULL, 19703 "The type definition (or type definition's content type) is or " 19704 "is derived from ID; value constraints are not allowed in " 19705 "conjunction with such a type definition", NULL); 19706 } else if (elemDecl->value != NULL) { 19707 int vcret; 19708 xmlNodePtr node = NULL; 19709 19710 /* 19711 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19712 * representation of its value must be `valid` with respect to the 19713 * {type definition} as defined in Element Default Valid (Immediate) 19714 * ($3.3.6)." 19715 */ 19716 if (typeDef == NULL) { 19717 xmlSchemaPErr(pctxt, elemDecl->node, 19718 XML_SCHEMAP_INTERNAL, 19719 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19720 "type is missing... skipping validation of " 19721 "the value constraint", NULL, NULL); 19722 return (-1); 19723 } 19724 if (elemDecl->node != NULL) { 19725 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19726 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19727 BAD_CAST "fixed"); 19728 else 19729 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19730 BAD_CAST "default"); 19731 } 19732 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19733 typeDef, elemDecl->value, &(elemDecl->defVal)); 19734 if (vcret != 0) { 19735 if (vcret < 0) { 19736 PERROR_INT("xmlSchemaElemCheckValConstr", 19737 "failed to validate the value constraint of an " 19738 "element declaration"); 19739 return (-1); 19740 } 19741 return (vcret); 19742 } 19743 } 19744 19745 return (ret); 19746} 19747 19748/** 19749 * xmlSchemaCheckElemSubstGroup: 19750 * @ctxt: a schema parser context 19751 * @decl: the element declaration 19752 * @name: the name of the attribute 19753 * 19754 * Schema Component Constraint: 19755 * Substitution Group (cos-equiv-class) 19756 * 19757 * In Libxml2 the subst. groups will be precomputed, in terms of that 19758 * a list will be built for each subst. group head, holding all direct 19759 * referents to this head. 19760 * NOTE that this function needs: 19761 * 1. circular subst. groups to be checked beforehand 19762 * 2. the declaration's type to be derived from the head's type 19763 * 19764 * STATUS: 19765 * 19766 */ 19767static void 19768xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19769 xmlSchemaElementPtr elemDecl) 19770{ 19771 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19772 /* SPEC (1) "Its {abstract} is false." */ 19773 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19774 return; 19775 { 19776 xmlSchemaElementPtr head; 19777 xmlSchemaTypePtr headType, type; 19778 int set, methSet; 19779 /* 19780 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19781 * {disallowed substitutions} as the blocking constraint, as defined in 19782 * Substitution Group OK (Transitive) ($3.3.6)." 19783 */ 19784 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19785 head = WXS_SUBST_HEAD(head)) { 19786 set = 0; 19787 methSet = 0; 19788 /* 19789 * The blocking constraints. 19790 */ 19791 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19792 continue; 19793 headType = head->subtypes; 19794 type = elemDecl->subtypes; 19795 if (headType == type) 19796 goto add_member; 19797 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19798 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19799 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19800 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19801 /* 19802 * SPEC: Substitution Group OK (Transitive) (2.3) 19803 * "The set of all {derivation method}s involved in the 19804 * derivation of D's {type definition} from C's {type definition} 19805 * does not intersect with the union of the blocking constraint, 19806 * C's {prohibited substitutions} (if C is complex, otherwise the 19807 * empty set) and the {prohibited substitutions} (respectively the 19808 * empty set) of any intermediate {type definition}s in the 19809 * derivation of D's {type definition} from C's {type definition}." 19810 */ 19811 /* 19812 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19813 * subst.head axis, the methSet does not need to be computed for 19814 * the full depth over and over. 19815 */ 19816 /* 19817 * The set of all {derivation method}s involved in the derivation 19818 */ 19819 while ((type != NULL) && (type != headType)) { 19820 if ((WXS_IS_EXTENSION(type)) && 19821 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19822 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19823 19824 if (WXS_IS_RESTRICTION(type) && 19825 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19826 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19827 19828 type = type->baseType; 19829 } 19830 /* 19831 * The {prohibited substitutions} of all intermediate types + 19832 * the head's type. 19833 */ 19834 type = elemDecl->subtypes->baseType; 19835 while (type != NULL) { 19836 if (WXS_IS_COMPLEX(type)) { 19837 if ((type->flags & 19838 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19839 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19840 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19841 if ((type->flags & 19842 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19843 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19844 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19845 } else 19846 break; 19847 if (type == headType) 19848 break; 19849 type = type->baseType; 19850 } 19851 if ((set != 0) && 19852 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19853 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19854 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19855 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19856 continue; 19857 } 19858add_member: 19859 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19860 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19861 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19862 } 19863 } 19864} 19865 19866#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19867/** 19868 * xmlSchemaCheckElementDeclComponent 19869 * @pctxt: the schema parser context 19870 * @ctxtComponent: the context component (an element declaration) 19871 * @ctxtParticle: the first particle of the context component 19872 * @searchParticle: the element declaration particle to be analysed 19873 * 19874 * Schema Component Constraint: Element Declarations Consistent 19875 */ 19876static int 19877xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19878 xmlSchemaBasicItemPtr ctxtComponent, 19879 xmlSchemaParticlePtr ctxtParticle, 19880 xmlSchemaParticlePtr searchParticle, 19881 xmlSchemaParticlePtr curParticle, 19882 int search) 19883{ 19884 return(0); 19885 19886 int ret = 0; 19887 xmlSchemaParticlePtr cur = curParticle; 19888 if (curParticle == NULL) { 19889 return(0); 19890 } 19891 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19892 /* 19893 * Just return in this case. A missing "term" of the particle 19894 * might arise due to an invalid "term" component. 19895 */ 19896 return(0); 19897 } 19898 while (cur != NULL) { 19899 switch (WXS_PARTICLE_TERM(cur)->type) { 19900 case XML_SCHEMA_TYPE_ANY: 19901 break; 19902 case XML_SCHEMA_TYPE_ELEMENT: 19903 if (search == 0) { 19904 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19905 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19906 if (ret != 0) 19907 return(ret); 19908 } else { 19909 xmlSchemaElementPtr elem = 19910 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19911 /* 19912 * SPEC Element Declarations Consistent: 19913 * "If the {particles} contains, either directly, 19914 * indirectly (that is, within the {particles} of a 19915 * contained model group, recursively) or `implicitly` 19916 * two or more element declaration particles with 19917 * the same {name} and {target namespace}, then 19918 * all their type definitions must be the same 19919 * top-level definition [...]" 19920 */ 19921 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19922 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19923 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19924 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19925 { 19926 xmlChar *strA = NULL, *strB = NULL; 19927 19928 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19929 /* TODO: error code */ 19930 XML_SCHEMAP_COS_NONAMBIG, 19931 WXS_ITEM_NODE(cur), NULL, 19932 "In the content model of %s, there are multiple " 19933 "element declarations for '%s' with different " 19934 "type definitions", 19935 xmlSchemaGetComponentDesignation(&strA, 19936 ctxtComponent), 19937 xmlSchemaFormatQName(&strB, 19938 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19939 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19940 FREE_AND_NULL(strA); 19941 FREE_AND_NULL(strB); 19942 return(XML_SCHEMAP_COS_NONAMBIG); 19943 } 19944 } 19945 break; 19946 case XML_SCHEMA_TYPE_SEQUENCE: { 19947 break; 19948 } 19949 case XML_SCHEMA_TYPE_CHOICE:{ 19950 /* 19951 xmlSchemaTreeItemPtr sub; 19952 19953 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19954 while (sub != NULL) { 19955 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19956 ctxtParticle, ctxtElem); 19957 if (ret != 0) 19958 return(ret); 19959 sub = sub->next; 19960 } 19961 */ 19962 break; 19963 } 19964 case XML_SCHEMA_TYPE_ALL: 19965 break; 19966 case XML_SCHEMA_TYPE_GROUP: 19967 break; 19968 default: 19969 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19970 "xmlSchemaCheckElementDeclConsistent", 19971 "found unexpected term of type '%s' in content model", 19972 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19973 return(-1); 19974 } 19975 cur = (xmlSchemaParticlePtr) cur->next; 19976 } 19977 19978exit: 19979 return(ret); 19980} 19981#endif 19982 19983/** 19984 * xmlSchemaCheckElementDeclComponent 19985 * @item: an schema element declaration/particle 19986 * @ctxt: a schema parser context 19987 * @name: the name of the attribute 19988 * 19989 * Validates the value constraints of an element declaration. 19990 * Adds substitution group members. 19991 */ 19992static void 19993xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 19994 xmlSchemaParserCtxtPtr ctxt) 19995{ 19996 if (elemDecl == NULL) 19997 return; 19998 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 19999 return; 20000 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 20001 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 20002 /* 20003 * Adds substitution group members. 20004 */ 20005 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 20006 } 20007} 20008 20009/** 20010 * xmlSchemaResolveModelGroupParticleReferences: 20011 * @particle: a particle component 20012 * @ctxt: a parser context 20013 * 20014 * Resolves references of a model group's {particles} to 20015 * model group definitions and to element declarations. 20016 */ 20017static void 20018xmlSchemaResolveModelGroupParticleReferences( 20019 xmlSchemaParserCtxtPtr ctxt, 20020 xmlSchemaModelGroupPtr mg) 20021{ 20022 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 20023 xmlSchemaQNameRefPtr ref; 20024 xmlSchemaBasicItemPtr refItem; 20025 20026 /* 20027 * URGENT TODO: Test this. 20028 */ 20029 while (particle != NULL) { 20030 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20031 ((WXS_PARTICLE_TERM(particle))->type != 20032 XML_SCHEMA_EXTRA_QNAMEREF)) 20033 { 20034 goto next_particle; 20035 } 20036 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20037 /* 20038 * Resolve the reference. 20039 * NULL the {term} by default. 20040 */ 20041 particle->children = NULL; 20042 20043 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20044 ref->itemType, ref->name, ref->targetNamespace); 20045 if (refItem == NULL) { 20046 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20047 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20048 ref->targetNamespace, ref->itemType, NULL); 20049 /* TODO: remove the particle. */ 20050 goto next_particle; 20051 } 20052 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20053 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20054 /* TODO: remove the particle. */ 20055 goto next_particle; 20056 /* 20057 * NOTE that we will assign the model group definition 20058 * itself to the "term" of the particle. This will ease 20059 * the check for circular model group definitions. After 20060 * that the "term" will be assigned the model group of the 20061 * model group definition. 20062 */ 20063 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20064 XML_SCHEMA_TYPE_ALL) { 20065 /* 20066 * SPEC cos-all-limited (1) 20067 * SPEC cos-all-limited (1.2) 20068 * "It appears only as the value of one or both of the 20069 * following properties:" 20070 * (1.1) "the {model group} property of a model group 20071 * definition." 20072 * (1.2) "the {term} property of a particle [... of] the " 20073 * {content type} of a complex type definition." 20074 */ 20075 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20076 /* TODO: error code */ 20077 XML_SCHEMAP_COS_ALL_LIMITED, 20078 WXS_ITEM_NODE(particle), NULL, 20079 "A model group definition is referenced, but " 20080 "it contains an 'all' model group, which " 20081 "cannot be contained by model groups", 20082 NULL, NULL); 20083 /* TODO: remove the particle. */ 20084 goto next_particle; 20085 } 20086 particle->children = (xmlSchemaTreeItemPtr) refItem; 20087 } else { 20088 /* 20089 * TODO: Are referenced element declarations the only 20090 * other components we expect here? 20091 */ 20092 particle->children = (xmlSchemaTreeItemPtr) refItem; 20093 } 20094next_particle: 20095 particle = WXS_PTC_CAST particle->next; 20096 } 20097} 20098 20099static int 20100xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20101 xmlSchemaValPtr y) 20102{ 20103 xmlSchemaTypePtr tx, ty, ptx, pty; 20104 int ret; 20105 20106 while (x != NULL) { 20107 /* Same types. */ 20108 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20109 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20110 ptx = xmlSchemaGetPrimitiveType(tx); 20111 pty = xmlSchemaGetPrimitiveType(ty); 20112 /* 20113 * (1) if a datatype T' is `derived` by `restriction` from an 20114 * atomic datatype T then the `value space` of T' is a subset of 20115 * the `value space` of T. */ 20116 /* 20117 * (2) if datatypes T' and T'' are `derived` by `restriction` 20118 * from a common atomic ancestor T then the `value space`s of T' 20119 * and T'' may overlap. 20120 */ 20121 if (ptx != pty) 20122 return(0); 20123 /* 20124 * We assume computed values to be normalized, so do a fast 20125 * string comparison for string based types. 20126 */ 20127 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20128 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20129 if (! xmlStrEqual( 20130 xmlSchemaValueGetAsString(x), 20131 xmlSchemaValueGetAsString(y))) 20132 return (0); 20133 } else { 20134 ret = xmlSchemaCompareValuesWhtsp( 20135 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20136 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20137 if (ret == -2) 20138 return(-1); 20139 if (ret != 0) 20140 return(0); 20141 } 20142 /* 20143 * Lists. 20144 */ 20145 x = xmlSchemaValueGetNext(x); 20146 if (x != NULL) { 20147 y = xmlSchemaValueGetNext(y); 20148 if (y == NULL) 20149 return (0); 20150 } else if (xmlSchemaValueGetNext(y) != NULL) 20151 return (0); 20152 else 20153 return (1); 20154 } 20155 return (0); 20156} 20157 20158/** 20159 * xmlSchemaResolveAttrUseReferences: 20160 * @item: an attribute use 20161 * @ctxt: a parser context 20162 * 20163 * Resolves the referenced attribute declaration. 20164 */ 20165static int 20166xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20167 xmlSchemaParserCtxtPtr ctxt) 20168{ 20169 if ((ctxt == NULL) || (ause == NULL)) 20170 return(-1); 20171 if ((ause->attrDecl == NULL) || 20172 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20173 return(0); 20174 20175 { 20176 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20177 20178 /* 20179 * TODO: Evaluate, what errors could occur if the declaration is not 20180 * found. 20181 */ 20182 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20183 ref->name, ref->targetNamespace); 20184 if (ause->attrDecl == NULL) { 20185 xmlSchemaPResCompAttrErr(ctxt, 20186 XML_SCHEMAP_SRC_RESOLVE, 20187 WXS_BASIC_CAST ause, ause->node, 20188 "ref", ref->name, ref->targetNamespace, 20189 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20190 return(ctxt->err);; 20191 } 20192 } 20193 return(0); 20194} 20195 20196/** 20197 * xmlSchemaCheckAttrUsePropsCorrect: 20198 * @ctxt: a parser context 20199 * @use: an attribute use 20200 * 20201 * Schema Component Constraint: 20202 * Attribute Use Correct (au-props-correct) 20203 * 20204 */ 20205static int 20206xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20207 xmlSchemaAttributeUsePtr use) 20208{ 20209 if ((ctxt == NULL) || (use == NULL)) 20210 return(-1); 20211 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20212 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20213 return(0); 20214 20215 /* 20216 * SPEC au-props-correct (1) 20217 * "The values of the properties of an attribute use must be as 20218 * described in the property tableau in The Attribute Use Schema 20219 * Component ($3.5.1), modulo the impact of Missing 20220 * Sub-components ($5.3)." 20221 */ 20222 20223 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20224 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20225 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20226 { 20227 xmlSchemaPCustomErr(ctxt, 20228 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20229 WXS_BASIC_CAST use, NULL, 20230 "The attribute declaration has a 'fixed' value constraint " 20231 ", thus the attribute use must also have a 'fixed' value " 20232 "constraint", 20233 NULL); 20234 return(ctxt->err); 20235 } 20236 /* 20237 * Compute and check the value constraint's value. 20238 */ 20239 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20240 int ret; 20241 /* 20242 * TODO: The spec seems to be missing a check of the 20243 * value constraint of the attribute use. We will do it here. 20244 */ 20245 /* 20246 * SPEC a-props-correct (3) 20247 */ 20248 if (xmlSchemaIsDerivedFromBuiltInType( 20249 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20250 { 20251 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20252 XML_SCHEMAP_AU_PROPS_CORRECT, 20253 NULL, WXS_BASIC_CAST use, 20254 "Value constraints are not allowed if the type definition " 20255 "is or is derived from xs:ID", 20256 NULL, NULL); 20257 return(ctxt->err); 20258 } 20259 20260 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20261 use->node, WXS_ATTRUSE_TYPEDEF(use), 20262 use->defValue, &(use->defVal), 20263 1, 1, 0); 20264 if (ret != 0) { 20265 if (ret < 0) { 20266 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20267 "calling xmlSchemaVCheckCVCSimpleType()"); 20268 return(-1); 20269 } 20270 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20271 XML_SCHEMAP_AU_PROPS_CORRECT, 20272 NULL, WXS_BASIC_CAST use, 20273 "The value of the value constraint is not valid", 20274 NULL, NULL); 20275 return(ctxt->err); 20276 } 20277 } 20278 /* 20279 * SPEC au-props-correct (2) 20280 * "If the {attribute declaration} has a fixed 20281 * {value constraint}, then if the attribute use itself has a 20282 * {value constraint}, it must also be fixed and its value must match 20283 * that of the {attribute declaration}'s {value constraint}." 20284 */ 20285 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20286 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20287 { 20288 if (! xmlSchemaAreValuesEqual(use->defVal, 20289 (WXS_ATTRUSE_DECL(use))->defVal)) 20290 { 20291 xmlSchemaPCustomErr(ctxt, 20292 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20293 WXS_BASIC_CAST use, NULL, 20294 "The 'fixed' value constraint of the attribute use " 20295 "must match the attribute declaration's value " 20296 "constraint '%s'", 20297 (WXS_ATTRUSE_DECL(use))->defValue); 20298 } 20299 return(ctxt->err); 20300 } 20301 return(0); 20302} 20303 20304 20305 20306 20307/** 20308 * xmlSchemaResolveAttrTypeReferences: 20309 * @item: an attribute declaration 20310 * @ctxt: a parser context 20311 * 20312 * Resolves the referenced type definition component. 20313 */ 20314static int 20315xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20316 xmlSchemaParserCtxtPtr ctxt) 20317{ 20318 /* 20319 * The simple type definition corresponding to the <simpleType> element 20320 * information item in the [children], if present, otherwise the simple 20321 * type definition `resolved` to by the `actual value` of the type 20322 * [attribute], if present, otherwise the `simple ur-type definition`. 20323 */ 20324 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20325 return(0); 20326 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20327 if (item->subtypes != NULL) 20328 return(0); 20329 if (item->typeName != NULL) { 20330 xmlSchemaTypePtr type; 20331 20332 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20333 item->typeNs); 20334 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20335 xmlSchemaPResCompAttrErr(ctxt, 20336 XML_SCHEMAP_SRC_RESOLVE, 20337 WXS_BASIC_CAST item, item->node, 20338 "type", item->typeName, item->typeNs, 20339 XML_SCHEMA_TYPE_SIMPLE, NULL); 20340 return(ctxt->err); 20341 } else 20342 item->subtypes = type; 20343 20344 } else { 20345 /* 20346 * The type defaults to the xs:anySimpleType. 20347 */ 20348 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20349 } 20350 return(0); 20351} 20352 20353/** 20354 * xmlSchemaResolveIDCKeyReferences: 20355 * @idc: the identity-constraint definition 20356 * @ctxt: the schema parser context 20357 * @name: the attribute name 20358 * 20359 * Resolve keyRef references to key/unique IDCs. 20360 * Schema Component Constraint: 20361 * Identity-constraint Definition Properties Correct (c-props-correct) 20362 */ 20363static int 20364xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20365 xmlSchemaParserCtxtPtr pctxt) 20366{ 20367 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20368 return(0); 20369 if (idc->ref->name != NULL) { 20370 idc->ref->item = (xmlSchemaBasicItemPtr) 20371 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20372 idc->ref->targetNamespace); 20373 if (idc->ref->item == NULL) { 20374 /* 20375 * TODO: It is actually not an error to fail to resolve 20376 * at this stage. BUT we need to be that strict! 20377 */ 20378 xmlSchemaPResCompAttrErr(pctxt, 20379 XML_SCHEMAP_SRC_RESOLVE, 20380 WXS_BASIC_CAST idc, idc->node, 20381 "refer", idc->ref->name, 20382 idc->ref->targetNamespace, 20383 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20384 return(pctxt->err); 20385 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20386 /* 20387 * SPEC c-props-correct (1) 20388 */ 20389 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20390 XML_SCHEMAP_C_PROPS_CORRECT, 20391 NULL, WXS_BASIC_CAST idc, 20392 "The keyref references a keyref", 20393 NULL, NULL); 20394 idc->ref->item = NULL; 20395 return(pctxt->err); 20396 } else { 20397 if (idc->nbFields != 20398 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20399 xmlChar *str = NULL; 20400 xmlSchemaIDCPtr refer; 20401 20402 refer = (xmlSchemaIDCPtr) idc->ref->item; 20403 /* 20404 * SPEC c-props-correct(2) 20405 * "If the {identity-constraint category} is keyref, 20406 * the cardinality of the {fields} must equal that of 20407 * the {fields} of the {referenced key}. 20408 */ 20409 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20410 XML_SCHEMAP_C_PROPS_CORRECT, 20411 NULL, WXS_BASIC_CAST idc, 20412 "The cardinality of the keyref differs from the " 20413 "cardinality of the referenced key/unique '%s'", 20414 xmlSchemaFormatQName(&str, refer->targetNamespace, 20415 refer->name), 20416 NULL); 20417 FREE_AND_NULL(str) 20418 return(pctxt->err); 20419 } 20420 } 20421 } 20422 return(0); 20423} 20424 20425static int 20426xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20427 xmlSchemaParserCtxtPtr pctxt) 20428{ 20429 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20430 prohib->targetNamespace) == NULL) { 20431 20432 xmlSchemaPResCompAttrErr(pctxt, 20433 XML_SCHEMAP_SRC_RESOLVE, 20434 NULL, prohib->node, 20435 "ref", prohib->name, prohib->targetNamespace, 20436 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20437 return(XML_SCHEMAP_SRC_RESOLVE); 20438 } 20439 return(0); 20440} 20441 20442#define WXS_REDEFINED_TYPE(c) \ 20443(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20444 20445#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20446(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20447 20448#define WXS_REDEFINED_ATTR_GROUP(c) \ 20449(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20450 20451static int 20452xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20453{ 20454 int err = 0; 20455 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20456 xmlSchemaBasicItemPtr prev, item; 20457 int wasRedefined; 20458 20459 if (redef == NULL) 20460 return(0); 20461 20462 do { 20463 item = redef->item; 20464 /* 20465 * First try to locate the redefined component in the 20466 * schema graph starting with the redefined schema. 20467 * NOTE: According to this schema bug entry: 20468 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20469 * it's not clear if the referenced component needs to originate 20470 * from the <redefine>d schema _document_ or the schema; the latter 20471 * would include all imported and included sub-schemas of the 20472 * <redefine>d schema. Currenlty we latter approach is used. 20473 * SUPPLEMENT: It seems that the WG moves towards the latter 20474 * approach, so we are doing it right. 20475 * 20476 */ 20477 prev = xmlSchemaFindRedefCompInGraph( 20478 redef->targetBucket, item->type, 20479 redef->refName, redef->refTargetNs); 20480 if (prev == NULL) { 20481 xmlChar *str = NULL; 20482 xmlNodePtr node; 20483 20484 /* 20485 * SPEC src-redefine: 20486 * (6.2.1) "The `actual value` of its own name attribute plus 20487 * target namespace must successfully `resolve` to a model 20488 * group definition in I." 20489 * (7.2.1) "The `actual value` of its own name attribute plus 20490 * target namespace must successfully `resolve` to an attribute 20491 * group definition in I." 20492 20493 * 20494 * Note that, if we are redefining with the use of references 20495 * to components, the spec assumes the src-resolve to be used; 20496 * but this won't assure that we search only *inside* the 20497 * redefined schema. 20498 */ 20499 if (redef->reference) 20500 node = WXS_ITEM_NODE(redef->reference); 20501 else 20502 node = WXS_ITEM_NODE(item); 20503 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20504 /* 20505 * TODO: error code. 20506 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20507 * reference kind. 20508 */ 20509 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20510 "The %s '%s' to be redefined could not be found in " 20511 "the redefined schema", 20512 WXS_ITEM_TYPE_NAME(item), 20513 xmlSchemaFormatQName(&str, redef->refTargetNs, 20514 redef->refName)); 20515 FREE_AND_NULL(str); 20516 err = pctxt->err; 20517 redef = redef->next; 20518 continue; 20519 } 20520 /* 20521 * TODO: Obtaining and setting the redefinition state is really 20522 * clumsy. 20523 */ 20524 wasRedefined = 0; 20525 switch (item->type) { 20526 case XML_SCHEMA_TYPE_COMPLEX: 20527 case XML_SCHEMA_TYPE_SIMPLE: 20528 if ((WXS_TYPE_CAST prev)->flags & 20529 XML_SCHEMAS_TYPE_REDEFINED) 20530 { 20531 wasRedefined = 1; 20532 break; 20533 } 20534 /* Mark it as redefined. */ 20535 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20536 /* 20537 * Assign the redefined type to the 20538 * base type of the redefining type. 20539 * TODO: How 20540 */ 20541 ((xmlSchemaTypePtr) item)->baseType = 20542 (xmlSchemaTypePtr) prev; 20543 break; 20544 case XML_SCHEMA_TYPE_GROUP: 20545 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20546 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20547 { 20548 wasRedefined = 1; 20549 break; 20550 } 20551 /* Mark it as redefined. */ 20552 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20553 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20554 if (redef->reference != NULL) { 20555 /* 20556 * Overwrite the QName-reference with the 20557 * referenced model group def. 20558 */ 20559 (WXS_PTC_CAST redef->reference)->children = 20560 WXS_TREE_CAST prev; 20561 } 20562 redef->target = prev; 20563 break; 20564 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20565 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20566 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20567 { 20568 wasRedefined = 1; 20569 break; 20570 } 20571 (WXS_ATTR_GROUP_CAST prev)->flags |= 20572 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20573 if (redef->reference != NULL) { 20574 /* 20575 * Assign the redefined attribute group to the 20576 * QName-reference component. 20577 * This is the easy case, since we will just 20578 * expand the redefined group. 20579 */ 20580 (WXS_QNAME_CAST redef->reference)->item = prev; 20581 redef->target = NULL; 20582 } else { 20583 /* 20584 * This is the complicated case: we need 20585 * to apply src-redefine (7.2.2) at a later 20586 * stage, i.e. when attribute group references 20587 * have beed expanded and simple types have 20588 * beed fixed. 20589 */ 20590 redef->target = prev; 20591 } 20592 break; 20593 default: 20594 PERROR_INT("xmlSchemaResolveRedefReferences", 20595 "Unexpected redefined component type"); 20596 return(-1); 20597 } 20598 if (wasRedefined) { 20599 xmlChar *str = NULL; 20600 xmlNodePtr node; 20601 20602 if (redef->reference) 20603 node = WXS_ITEM_NODE(redef->reference); 20604 else 20605 node = WXS_ITEM_NODE(redef->item); 20606 20607 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20608 /* TODO: error code. */ 20609 XML_SCHEMAP_SRC_REDEFINE, 20610 node, NULL, 20611 "The referenced %s was already redefined. Multiple " 20612 "redefinition of the same component is not supported", 20613 xmlSchemaGetComponentDesignation(&str, prev), 20614 NULL); 20615 FREE_AND_NULL(str) 20616 err = pctxt->err; 20617 redef = redef->next; 20618 continue; 20619 } 20620 redef = redef->next; 20621 } while (redef != NULL); 20622 20623 return(err); 20624} 20625 20626static int 20627xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20628{ 20629 int err = 0; 20630 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20631 xmlSchemaBasicItemPtr item; 20632 20633 if (redef == NULL) 20634 return(0); 20635 20636 do { 20637 if (redef->target == NULL) { 20638 redef = redef->next; 20639 continue; 20640 } 20641 item = redef->item; 20642 20643 switch (item->type) { 20644 case XML_SCHEMA_TYPE_SIMPLE: 20645 case XML_SCHEMA_TYPE_COMPLEX: 20646 /* 20647 * Since the spec wants the {name} of the redefined 20648 * type to be 'absent', we'll NULL it. 20649 */ 20650 (WXS_TYPE_CAST redef->target)->name = NULL; 20651 20652 /* 20653 * TODO: Seems like there's nothing more to do. The normal 20654 * inheritance mechanism is used. But not 100% sure. 20655 */ 20656 break; 20657 case XML_SCHEMA_TYPE_GROUP: 20658 /* 20659 * URGENT TODO: 20660 * SPEC src-redefine: 20661 * (6.2.2) "The {model group} of the model group definition 20662 * which corresponds to it per XML Representation of Model 20663 * Group Definition Schema Components ($3.7.2) must be a 20664 * `valid restriction` of the {model group} of that model 20665 * group definition in I, as defined in Particle Valid 20666 * (Restriction) ($3.9.6)." 20667 */ 20668 break; 20669 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20670 /* 20671 * SPEC src-redefine: 20672 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20673 * the attribute group definition which corresponds to it 20674 * per XML Representation of Attribute Group Definition Schema 20675 * Components ($3.6.2) must be `valid restrictions` of the 20676 * {attribute uses} and {attribute wildcard} of that attribute 20677 * group definition in I, as defined in clause 2, clause 3 and 20678 * clause 4 of Derivation Valid (Restriction, Complex) 20679 * ($3.4.6) (where references to the base type definition are 20680 * understood as references to the attribute group definition 20681 * in I)." 20682 */ 20683 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20684 XML_SCHEMA_ACTION_REDEFINE, 20685 item, redef->target, 20686 (WXS_ATTR_GROUP_CAST item)->attrUses, 20687 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20688 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20689 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20690 if (err == -1) 20691 return(-1); 20692 break; 20693 default: 20694 break; 20695 } 20696 redef = redef->next; 20697 } while (redef != NULL); 20698 return(0); 20699} 20700 20701 20702static int 20703xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20704 xmlSchemaBucketPtr bucket) 20705{ 20706 xmlSchemaBasicItemPtr item; 20707 int err; 20708 xmlHashTablePtr *table; 20709 const xmlChar *name; 20710 int i; 20711 20712#define WXS_GET_GLOBAL_HASH(c, slot) { \ 20713 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20714 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20715 else \ 20716 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20717 20718 /* 20719 * Add global components to the schema's hash tables. 20720 * This is the place where duplicate components will be 20721 * detected. 20722 * TODO: I think normally we should support imports of the 20723 * same namespace from multiple locations. We don't do currently, 20724 * but if we do then according to: 20725 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20726 * we would need, if imported directly, to import redefined 20727 * components as well to be able to catch clashing components. 20728 * (I hope I'll still know what this means after some months :-() 20729 */ 20730 if (bucket == NULL) 20731 return(-1); 20732 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20733 return(0); 20734 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20735 20736 for (i = 0; i < bucket->globals->nbItems; i++) { 20737 item = bucket->globals->items[i]; 20738 table = NULL; 20739 switch (item->type) { 20740 case XML_SCHEMA_TYPE_COMPLEX: 20741 case XML_SCHEMA_TYPE_SIMPLE: 20742 if (WXS_REDEFINED_TYPE(item)) 20743 continue; 20744 name = (WXS_TYPE_CAST item)->name; 20745 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20746 break; 20747 case XML_SCHEMA_TYPE_ELEMENT: 20748 name = (WXS_ELEM_CAST item)->name; 20749 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20750 break; 20751 case XML_SCHEMA_TYPE_ATTRIBUTE: 20752 name = (WXS_ATTR_CAST item)->name; 20753 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20754 break; 20755 case XML_SCHEMA_TYPE_GROUP: 20756 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20757 continue; 20758 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20759 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20760 break; 20761 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20762 if (WXS_REDEFINED_ATTR_GROUP(item)) 20763 continue; 20764 name = (WXS_ATTR_GROUP_CAST item)->name; 20765 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20766 break; 20767 case XML_SCHEMA_TYPE_IDC_KEY: 20768 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20769 case XML_SCHEMA_TYPE_IDC_KEYREF: 20770 name = (WXS_IDC_CAST item)->name; 20771 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20772 break; 20773 case XML_SCHEMA_TYPE_NOTATION: 20774 name = ((xmlSchemaNotationPtr) item)->name; 20775 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20776 break; 20777 default: 20778 PERROR_INT("xmlSchemaAddComponents", 20779 "Unexpected global component type"); 20780 continue; 20781 } 20782 if (*table == NULL) { 20783 *table = xmlHashCreateDict(10, pctxt->dict); 20784 if (*table == NULL) { 20785 PERROR_INT("xmlSchemaAddComponents", 20786 "failed to create a component hash table"); 20787 return(-1); 20788 } 20789 } 20790 err = xmlHashAddEntry(*table, name, item); 20791 if (err != 0) { 20792 xmlChar *str = NULL; 20793 20794 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20795 XML_SCHEMAP_REDEFINED_TYPE, 20796 WXS_ITEM_NODE(item), 20797 WXS_BASIC_CAST item, 20798 "A global %s '%s' does already exist", 20799 WXS_ITEM_TYPE_NAME(item), 20800 xmlSchemaGetComponentQName(&str, item)); 20801 FREE_AND_NULL(str); 20802 } 20803 } 20804 /* 20805 * Process imported/included schemas. 20806 */ 20807 if (bucket->relations != NULL) { 20808 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20809 do { 20810 if ((rel->bucket != NULL) && 20811 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20812 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20813 return(-1); 20814 } 20815 rel = rel->next; 20816 } while (rel != NULL); 20817 } 20818 return(0); 20819} 20820 20821static int 20822xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20823 xmlSchemaBucketPtr rootBucket) 20824{ 20825 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20826 xmlSchemaTreeItemPtr item, *items; 20827 int nbItems, i, ret = 0; 20828 xmlSchemaBucketPtr oldbucket = con->bucket; 20829 xmlSchemaElementPtr elemDecl; 20830 20831#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20832 20833 if ((con->pending == NULL) || 20834 (con->pending->nbItems == 0)) 20835 return(0); 20836 20837 /* 20838 * Since xmlSchemaFixupComplexType() will create new particles 20839 * (local components), and those particle components need a bucket 20840 * on the constructor, we'll assure here that the constructor has 20841 * a bucket. 20842 * TODO: Think about storing locals _only_ on the main bucket. 20843 */ 20844 if (con->bucket == NULL) 20845 con->bucket = rootBucket; 20846 20847 /* TODO: 20848 * SPEC (src-redefine): 20849 * (6.2) "If it has no such self-reference, then all of the 20850 * following must be true:" 20851 20852 * (6.2.2) The {model group} of the model group definition which 20853 * corresponds to it per XML Representation of Model Group 20854 * Definition Schema Components ($3.7.2) must be a `valid 20855 * restriction` of the {model group} of that model group definition 20856 * in I, as defined in Particle Valid (Restriction) ($3.9.6)." 20857 */ 20858 xmlSchemaCheckSRCRedefineFirst(pctxt); 20859 20860 /* 20861 * Add global components to the schemata's hash tables. 20862 */ 20863 xmlSchemaAddComponents(pctxt, rootBucket); 20864 20865 pctxt->ctxtType = NULL; 20866 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20867 nbItems = con->pending->nbItems; 20868 /* 20869 * Now that we have parsed *all* the schema document(s) and converted 20870 * them to schema components, we can resolve references, apply component 20871 * constraints, create the FSA from the content model, etc. 20872 */ 20873 /* 20874 * Resolve references of.. 20875 * 20876 * 1. element declarations: 20877 * - the type definition 20878 * - the substitution group affiliation 20879 * 2. simple/complex types: 20880 * - the base type definition 20881 * - the memberTypes of union types 20882 * - the itemType of list types 20883 * 3. attributes declarations and attribute uses: 20884 * - the type definition 20885 * - if an attribute use, then the attribute declaration 20886 * 4. attribute group references: 20887 * - the attribute group definition 20888 * 5. particles: 20889 * - the term of the particle (e.g. a model group) 20890 * 6. IDC key-references: 20891 * - the referenced IDC 'key' or 'unique' definition 20892 * 7. Attribute prohibitions which had a "ref" attribute. 20893 */ 20894 for (i = 0; i < nbItems; i++) { 20895 item = items[i]; 20896 switch (item->type) { 20897 case XML_SCHEMA_TYPE_ELEMENT: 20898 xmlSchemaResolveElementReferences( 20899 (xmlSchemaElementPtr) item, pctxt); 20900 FIXHFAILURE; 20901 break; 20902 case XML_SCHEMA_TYPE_COMPLEX: 20903 case XML_SCHEMA_TYPE_SIMPLE: 20904 xmlSchemaResolveTypeReferences( 20905 (xmlSchemaTypePtr) item, pctxt); 20906 FIXHFAILURE; 20907 break; 20908 case XML_SCHEMA_TYPE_ATTRIBUTE: 20909 xmlSchemaResolveAttrTypeReferences( 20910 (xmlSchemaAttributePtr) item, pctxt); 20911 FIXHFAILURE; 20912 break; 20913 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20914 xmlSchemaResolveAttrUseReferences( 20915 (xmlSchemaAttributeUsePtr) item, pctxt); 20916 FIXHFAILURE; 20917 break; 20918 case XML_SCHEMA_EXTRA_QNAMEREF: 20919 if ((WXS_QNAME_CAST item)->itemType == 20920 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20921 { 20922 xmlSchemaResolveAttrGroupReferences( 20923 WXS_QNAME_CAST item, pctxt); 20924 } 20925 FIXHFAILURE; 20926 break; 20927 case XML_SCHEMA_TYPE_SEQUENCE: 20928 case XML_SCHEMA_TYPE_CHOICE: 20929 case XML_SCHEMA_TYPE_ALL: 20930 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20931 WXS_MODEL_GROUP_CAST item); 20932 FIXHFAILURE; 20933 break; 20934 case XML_SCHEMA_TYPE_IDC_KEY: 20935 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20936 case XML_SCHEMA_TYPE_IDC_KEYREF: 20937 xmlSchemaResolveIDCKeyReferences( 20938 (xmlSchemaIDCPtr) item, pctxt); 20939 FIXHFAILURE; 20940 break; 20941 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20942 /* 20943 * Handle attribue prohibition which had a 20944 * "ref" attribute. 20945 */ 20946 xmlSchemaResolveAttrUseProhibReferences( 20947 WXS_ATTR_PROHIB_CAST item, pctxt); 20948 FIXHFAILURE; 20949 break; 20950 default: 20951 break; 20952 } 20953 } 20954 if (pctxt->nberrors != 0) 20955 goto exit_error; 20956 20957 /* 20958 * Now that all references are resolved we 20959 * can check for circularity of... 20960 * 1. the base axis of type definitions 20961 * 2. nested model group definitions 20962 * 3. nested attribute group definitions 20963 * TODO: check for circual substitution groups. 20964 */ 20965 for (i = 0; i < nbItems; i++) { 20966 item = items[i]; 20967 /* 20968 * Let's better stop on the first error here. 20969 */ 20970 switch (item->type) { 20971 case XML_SCHEMA_TYPE_COMPLEX: 20972 case XML_SCHEMA_TYPE_SIMPLE: 20973 xmlSchemaCheckTypeDefCircular( 20974 (xmlSchemaTypePtr) item, pctxt); 20975 FIXHFAILURE; 20976 if (pctxt->nberrors != 0) 20977 goto exit_error; 20978 break; 20979 case XML_SCHEMA_TYPE_GROUP: 20980 xmlSchemaCheckGroupDefCircular( 20981 (xmlSchemaModelGroupDefPtr) item, pctxt); 20982 FIXHFAILURE; 20983 if (pctxt->nberrors != 0) 20984 goto exit_error; 20985 break; 20986 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20987 xmlSchemaCheckAttrGroupCircular( 20988 (xmlSchemaAttributeGroupPtr) item, pctxt); 20989 FIXHFAILURE; 20990 if (pctxt->nberrors != 0) 20991 goto exit_error; 20992 break; 20993 default: 20994 break; 20995 } 20996 } 20997 if (pctxt->nberrors != 0) 20998 goto exit_error; 20999 /* 21000 * Model group definition references: 21001 * Such a reference is reflected by a particle at the component 21002 * level. Until now the 'term' of such particles pointed 21003 * to the model group definition; this was done, in order to 21004 * ease circularity checks. Now we need to set the 'term' of 21005 * such particles to the model group of the model group definition. 21006 */ 21007 for (i = 0; i < nbItems; i++) { 21008 item = items[i]; 21009 switch (item->type) { 21010 case XML_SCHEMA_TYPE_SEQUENCE: 21011 case XML_SCHEMA_TYPE_CHOICE: 21012 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 21013 WXS_MODEL_GROUP_CAST item); 21014 break; 21015 default: 21016 break; 21017 } 21018 } 21019 if (pctxt->nberrors != 0) 21020 goto exit_error; 21021 /* 21022 * Expand attribute group references of attribute group definitions. 21023 */ 21024 for (i = 0; i < nbItems; i++) { 21025 item = items[i]; 21026 switch (item->type) { 21027 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21028 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 21029 WXS_ATTR_GROUP_HAS_REFS(item)) 21030 { 21031 xmlSchemaAttributeGroupExpandRefs(pctxt, 21032 WXS_ATTR_GROUP_CAST item); 21033 FIXHFAILURE; 21034 } 21035 break; 21036 default: 21037 break; 21038 } 21039 } 21040 if (pctxt->nberrors != 0) 21041 goto exit_error; 21042 /* 21043 * First compute the variety of simple types. This is needed as 21044 * a seperate step, since otherwise we won't be able to detect 21045 * circular union types in all cases. 21046 */ 21047 for (i = 0; i < nbItems; i++) { 21048 item = items[i]; 21049 switch (item->type) { 21050 case XML_SCHEMA_TYPE_SIMPLE: 21051 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21052 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21053 (xmlSchemaTypePtr) item); 21054 FIXHFAILURE; 21055 } 21056 break; 21057 default: 21058 break; 21059 } 21060 } 21061 if (pctxt->nberrors != 0) 21062 goto exit_error; 21063 /* 21064 * Detect circular union types. Note that this needs the variety to 21065 * be already computed. 21066 */ 21067 for (i = 0; i < nbItems; i++) { 21068 item = items[i]; 21069 switch (item->type) { 21070 case XML_SCHEMA_TYPE_SIMPLE: 21071 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21072 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21073 (xmlSchemaTypePtr) item); 21074 FIXHFAILURE; 21075 } 21076 break; 21077 default: 21078 break; 21079 } 21080 } 21081 if (pctxt->nberrors != 0) 21082 goto exit_error; 21083 21084 /* 21085 * Do the complete type fixup for simple types. 21086 */ 21087 for (i = 0; i < nbItems; i++) { 21088 item = items[i]; 21089 switch (item->type) { 21090 case XML_SCHEMA_TYPE_SIMPLE: 21091 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21092 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21093 FIXHFAILURE; 21094 } 21095 break; 21096 default: 21097 break; 21098 } 21099 } 21100 if (pctxt->nberrors != 0) 21101 goto exit_error; 21102 /* 21103 * At this point we need build and check all simple types. 21104 */ 21105 /* 21106 * Apply contraints for attribute declarations. 21107 */ 21108 for (i = 0; i < nbItems; i++) { 21109 item = items[i]; 21110 switch (item->type) { 21111 case XML_SCHEMA_TYPE_ATTRIBUTE: 21112 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21113 FIXHFAILURE; 21114 break; 21115 default: 21116 break; 21117 } 21118 } 21119 if (pctxt->nberrors != 0) 21120 goto exit_error; 21121 /* 21122 * Apply constraints for attribute uses. 21123 */ 21124 for (i = 0; i < nbItems; i++) { 21125 item = items[i]; 21126 switch (item->type) { 21127 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21128 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21129 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21130 WXS_ATTR_USE_CAST item); 21131 FIXHFAILURE; 21132 } 21133 break; 21134 default: 21135 break; 21136 } 21137 } 21138 if (pctxt->nberrors != 0) 21139 goto exit_error; 21140 21141 /* 21142 * Apply constraints for attribute group definitions. 21143 */ 21144 for (i = 0; i < nbItems; i++) { 21145 item = items[i]; 21146 switch (item->type) { 21147 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21148 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21149 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21150 { 21151 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21152 FIXHFAILURE; 21153 } 21154 break; 21155 default: 21156 break; 21157 } 21158 } 21159 if (pctxt->nberrors != 0) 21160 goto exit_error; 21161 21162 /* 21163 * Apply constraints for redefinitions. 21164 */ 21165 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21166 xmlSchemaCheckSRCRedefineSecond(pctxt); 21167 if (pctxt->nberrors != 0) 21168 goto exit_error; 21169 21170 /* 21171 * Complex types are builded and checked. 21172 */ 21173 for (i = 0; i < nbItems; i++) { 21174 item = con->pending->items[i]; 21175 switch (item->type) { 21176 case XML_SCHEMA_TYPE_COMPLEX: 21177 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21178 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21179 FIXHFAILURE; 21180 } 21181 break; 21182 default: 21183 break; 21184 } 21185 } 21186 if (pctxt->nberrors != 0) 21187 goto exit_error; 21188 21189 /* 21190 * The list could have changed, since xmlSchemaFixupComplexType() 21191 * will create particles and model groups in some cases. 21192 */ 21193 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21194 nbItems = con->pending->nbItems; 21195 21196 /* 21197 * Apply some constraints for element declarations. 21198 */ 21199 for (i = 0; i < nbItems; i++) { 21200 item = items[i]; 21201 switch (item->type) { 21202 case XML_SCHEMA_TYPE_ELEMENT: 21203 elemDecl = (xmlSchemaElementPtr) item; 21204 21205 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21206 { 21207 xmlSchemaCheckElementDeclComponent( 21208 (xmlSchemaElementPtr) elemDecl, pctxt); 21209 FIXHFAILURE; 21210 } 21211 21212#ifdef WXS_ELEM_DECL_CONS_ENABLED 21213 /* 21214 * Schema Component Constraint: Element Declarations Consistent 21215 * Apply this constraint to local types of element declarations. 21216 */ 21217 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21218 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21219 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21220 { 21221 xmlSchemaCheckElementDeclConsistent(pctxt, 21222 WXS_BASIC_CAST elemDecl, 21223 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21224 NULL, NULL, 0); 21225 } 21226#endif 21227 break; 21228 default: 21229 break; 21230 } 21231 } 21232 if (pctxt->nberrors != 0) 21233 goto exit_error; 21234 21235 /* 21236 * Finally we can build the automaton from the content model of 21237 * complex types. 21238 */ 21239 21240 for (i = 0; i < nbItems; i++) { 21241 item = items[i]; 21242 switch (item->type) { 21243 case XML_SCHEMA_TYPE_COMPLEX: 21244 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21245 /* FIXHFAILURE; */ 21246 break; 21247 default: 21248 break; 21249 } 21250 } 21251 if (pctxt->nberrors != 0) 21252 goto exit_error; 21253 /* 21254 * URGENT TODO: cos-element-consistent 21255 */ 21256 goto exit; 21257 21258exit_error: 21259 ret = pctxt->err; 21260 goto exit; 21261 21262exit_failure: 21263 ret = -1; 21264 21265exit: 21266 /* 21267 * Reset the constructor. This is needed for XSI acquisition, since 21268 * those items will be processed over and over again for every XSI 21269 * if not cleared here. 21270 */ 21271 con->bucket = oldbucket; 21272 con->pending->nbItems = 0; 21273 if (con->substGroups != NULL) { 21274 xmlHashFree(con->substGroups, 21275 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 21276 con->substGroups = NULL; 21277 } 21278 if (con->redefs != NULL) { 21279 xmlSchemaRedefListFree(con->redefs); 21280 con->redefs = NULL; 21281 } 21282 return(ret); 21283} 21284/** 21285 * xmlSchemaParse: 21286 * @ctxt: a schema validation context 21287 * 21288 * parse a schema definition resource and build an internal 21289 * XML Shema struture which can be used to validate instances. 21290 * 21291 * Returns the internal XML Schema structure built from the resource or 21292 * NULL in case of error 21293 */ 21294xmlSchemaPtr 21295xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21296{ 21297 xmlSchemaPtr mainSchema = NULL; 21298 xmlSchemaBucketPtr bucket = NULL; 21299 int res; 21300 21301 /* 21302 * This one is used if the schema to be parsed was specified via 21303 * the API; i.e. not automatically by the validated instance document. 21304 */ 21305 21306 xmlSchemaInitTypes(); 21307 21308 if (ctxt == NULL) 21309 return (NULL); 21310 21311 /* TODO: Init the context. Is this all we need?*/ 21312 ctxt->nberrors = 0; 21313 ctxt->err = 0; 21314 ctxt->counter = 0; 21315 21316 /* Create the *main* schema. */ 21317 mainSchema = xmlSchemaNewSchema(ctxt); 21318 if (mainSchema == NULL) 21319 goto exit_failure; 21320 /* 21321 * Create the schema constructor. 21322 */ 21323 if (ctxt->constructor == NULL) { 21324 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21325 if (ctxt->constructor == NULL) 21326 return(NULL); 21327 /* Take ownership of the constructor to be able to free it. */ 21328 ctxt->ownsConstructor = 1; 21329 } 21330 ctxt->constructor->mainSchema = mainSchema; 21331 /* 21332 * Locate and add the schema document. 21333 */ 21334 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21335 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21336 NULL, NULL, &bucket); 21337 if (res == -1) 21338 goto exit_failure; 21339 if (res != 0) 21340 goto exit; 21341 21342 if (bucket == NULL) { 21343 /* TODO: Error code, actually we failed to *locate* the schema. */ 21344 if (ctxt->URL) 21345 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21346 NULL, NULL, 21347 "Failed to locate the main schema resource at '%s'", 21348 ctxt->URL, NULL); 21349 else 21350 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21351 NULL, NULL, 21352 "Failed to locate the main schema resource", 21353 NULL, NULL); 21354 goto exit; 21355 } 21356 /* Then do the parsing for good. */ 21357 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21358 goto exit_failure; 21359 if (ctxt->nberrors != 0) 21360 goto exit; 21361 21362 mainSchema->doc = bucket->doc; 21363 mainSchema->preserve = ctxt->preserve; 21364 21365 ctxt->schema = mainSchema; 21366 21367 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21368 goto exit_failure; 21369 21370 /* 21371 * TODO: This is not nice, since we cannot distinguish from the 21372 * result if there was an internal error or not. 21373 */ 21374exit: 21375 if (ctxt->nberrors != 0) { 21376 if (mainSchema) { 21377 xmlSchemaFree(mainSchema); 21378 mainSchema = NULL; 21379 } 21380 if (ctxt->constructor) { 21381 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21382 ctxt->constructor = NULL; 21383 ctxt->ownsConstructor = 0; 21384 } 21385 } 21386 ctxt->schema = NULL; 21387 return(mainSchema); 21388exit_failure: 21389 /* 21390 * Quite verbose, but should catch internal errors, which were 21391 * not communitated. 21392 */ 21393 if (mainSchema) { 21394 xmlSchemaFree(mainSchema); 21395 mainSchema = NULL; 21396 } 21397 if (ctxt->constructor) { 21398 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21399 ctxt->constructor = NULL; 21400 ctxt->ownsConstructor = 0; 21401 } 21402 PERROR_INT2("xmlSchemaParse", 21403 "An internal error occured"); 21404 ctxt->schema = NULL; 21405 return(NULL); 21406} 21407 21408/** 21409 * xmlSchemaSetParserErrors: 21410 * @ctxt: a schema validation context 21411 * @err: the error callback 21412 * @warn: the warning callback 21413 * @ctx: contextual data for the callbacks 21414 * 21415 * Set the callback functions used to handle errors for a validation context 21416 */ 21417void 21418xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21419 xmlSchemaValidityErrorFunc err, 21420 xmlSchemaValidityWarningFunc warn, void *ctx) 21421{ 21422 if (ctxt == NULL) 21423 return; 21424 ctxt->error = err; 21425 ctxt->warning = warn; 21426 ctxt->errCtxt = ctx; 21427 if (ctxt->vctxt != NULL) 21428 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21429} 21430 21431/** 21432 * xmlSchemaSetParserStructuredErrors: 21433 * @ctxt: a schema parser context 21434 * @serror: the structured error function 21435 * @ctx: the functions context 21436 * 21437 * Set the structured error callback 21438 */ 21439void 21440xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21441 xmlStructuredErrorFunc serror, 21442 void *ctx) 21443{ 21444 if (ctxt == NULL) 21445 return; 21446 ctxt->serror = serror; 21447 ctxt->errCtxt = ctx; 21448 if (ctxt->vctxt != NULL) 21449 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21450} 21451 21452/** 21453 * xmlSchemaGetParserErrors: 21454 * @ctxt: a XMl-Schema parser context 21455 * @err: the error callback result 21456 * @warn: the warning callback result 21457 * @ctx: contextual data for the callbacks result 21458 * 21459 * Get the callback information used to handle errors for a parser context 21460 * 21461 * Returns -1 in case of failure, 0 otherwise 21462 */ 21463int 21464xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21465 xmlSchemaValidityErrorFunc * err, 21466 xmlSchemaValidityWarningFunc * warn, void **ctx) 21467{ 21468 if (ctxt == NULL) 21469 return(-1); 21470 if (err != NULL) 21471 *err = ctxt->error; 21472 if (warn != NULL) 21473 *warn = ctxt->warning; 21474 if (ctx != NULL) 21475 *ctx = ctxt->errCtxt; 21476 return(0); 21477} 21478 21479/** 21480 * xmlSchemaFacetTypeToString: 21481 * @type: the facet type 21482 * 21483 * Convert the xmlSchemaTypeType to a char string. 21484 * 21485 * Returns the char string representation of the facet type if the 21486 * type is a facet and an "Internal Error" string otherwise. 21487 */ 21488static const xmlChar * 21489xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21490{ 21491 switch (type) { 21492 case XML_SCHEMA_FACET_PATTERN: 21493 return (BAD_CAST "pattern"); 21494 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21495 return (BAD_CAST "maxExclusive"); 21496 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21497 return (BAD_CAST "maxInclusive"); 21498 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21499 return (BAD_CAST "minExclusive"); 21500 case XML_SCHEMA_FACET_MININCLUSIVE: 21501 return (BAD_CAST "minInclusive"); 21502 case XML_SCHEMA_FACET_WHITESPACE: 21503 return (BAD_CAST "whiteSpace"); 21504 case XML_SCHEMA_FACET_ENUMERATION: 21505 return (BAD_CAST "enumeration"); 21506 case XML_SCHEMA_FACET_LENGTH: 21507 return (BAD_CAST "length"); 21508 case XML_SCHEMA_FACET_MAXLENGTH: 21509 return (BAD_CAST "maxLength"); 21510 case XML_SCHEMA_FACET_MINLENGTH: 21511 return (BAD_CAST "minLength"); 21512 case XML_SCHEMA_FACET_TOTALDIGITS: 21513 return (BAD_CAST "totalDigits"); 21514 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21515 return (BAD_CAST "fractionDigits"); 21516 default: 21517 break; 21518 } 21519 return (BAD_CAST "Internal Error"); 21520} 21521 21522static xmlSchemaWhitespaceValueType 21523xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21524{ 21525 /* 21526 * The normalization type can be changed only for types which are derived 21527 * from xsd:string. 21528 */ 21529 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21530 /* 21531 * Note that we assume a whitespace of preserve for anySimpleType. 21532 */ 21533 if ((type->builtInType == XML_SCHEMAS_STRING) || 21534 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21535 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21536 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21537 return(XML_SCHEMA_WHITESPACE_REPLACE); 21538 else { 21539 /* 21540 * For all `atomic` datatypes other than string (and types `derived` 21541 * by `restriction` from it) the value of whiteSpace is fixed to 21542 * collapse 21543 * Note that this includes built-in list datatypes. 21544 */ 21545 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21546 } 21547 } else if (WXS_IS_LIST(type)) { 21548 /* 21549 * For list types the facet "whiteSpace" is fixed to "collapse". 21550 */ 21551 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21552 } else if (WXS_IS_UNION(type)) { 21553 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21554 } else if (WXS_IS_ATOMIC(type)) { 21555 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21556 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21557 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21558 return (XML_SCHEMA_WHITESPACE_REPLACE); 21559 else 21560 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21561 } 21562 return (-1); 21563} 21564 21565/************************************************************************ 21566 * * 21567 * Simple type validation * 21568 * * 21569 ************************************************************************/ 21570 21571 21572/************************************************************************ 21573 * * 21574 * DOM Validation code * 21575 * * 21576 ************************************************************************/ 21577 21578/** 21579 * xmlSchemaAssembleByLocation: 21580 * @pctxt: a schema parser context 21581 * @vctxt: a schema validation context 21582 * @schema: the existing schema 21583 * @node: the node that fired the assembling 21584 * @nsName: the namespace name of the new schema 21585 * @location: the location of the schema 21586 * 21587 * Expands an existing schema by an additional schema. 21588 * 21589 * Returns 0 if the new schema is correct, a positive error code 21590 * number otherwise and -1 in case of an internal or API error. 21591 */ 21592static int 21593xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21594 xmlSchemaPtr schema, 21595 xmlNodePtr node, 21596 const xmlChar *nsName, 21597 const xmlChar *location) 21598{ 21599 int ret = 0; 21600 xmlSchemaParserCtxtPtr pctxt; 21601 xmlSchemaBucketPtr bucket = NULL; 21602 21603 if ((vctxt == NULL) || (schema == NULL)) 21604 return (-1); 21605 21606 if (vctxt->pctxt == NULL) { 21607 VERROR_INT("xmlSchemaAssembleByLocation", 21608 "no parser context available"); 21609 return(-1); 21610 } 21611 pctxt = vctxt->pctxt; 21612 if (pctxt->constructor == NULL) { 21613 PERROR_INT("xmlSchemaAssembleByLocation", 21614 "no constructor"); 21615 return(-1); 21616 } 21617 /* 21618 * Acquire the schema document. 21619 */ 21620 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21621 location, node); 21622 /* 21623 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21624 * the process will automatically change this to 21625 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21626 */ 21627 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21628 location, NULL, NULL, 0, node, NULL, nsName, 21629 &bucket); 21630 if (ret != 0) 21631 return(ret); 21632 if (bucket == NULL) { 21633 /* 21634 * Generate a warning that the document could not be located. 21635 */ 21636 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21637 node, NULL, 21638 "The document at location '%s' could not be acquired", 21639 location, NULL, NULL); 21640 return(ret); 21641 } 21642 /* 21643 * The first located schema will be handled as if all other 21644 * schemas imported by XSI were imported by this first schema. 21645 */ 21646 if ((bucket != NULL) && 21647 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21648 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21649 /* 21650 * TODO: Is this handled like an import? I.e. is it not an error 21651 * if the schema cannot be located? 21652 */ 21653 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21654 return(0); 21655 /* 21656 * We will reuse the parser context for every schema imported 21657 * directly via XSI. So reset the context. 21658 */ 21659 pctxt->nberrors = 0; 21660 pctxt->err = 0; 21661 pctxt->doc = bucket->doc; 21662 21663 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21664 if (ret == -1) { 21665 pctxt->doc = NULL; 21666 goto exit_failure; 21667 } 21668 /* Paranoid error channelling. */ 21669 if ((ret == 0) && (pctxt->nberrors != 0)) 21670 ret = pctxt->err; 21671 if (pctxt->nberrors == 0) { 21672 /* 21673 * Only bother to fixup pending components, if there was 21674 * no error yet. 21675 * For every XSI acquired schema (and its sub-schemata) we will 21676 * fixup the components. 21677 */ 21678 xmlSchemaFixupComponents(pctxt, bucket); 21679 ret = pctxt->err; 21680 /* 21681 * Not nice, but we need somehow to channel the schema parser 21682 * error to the validation context. 21683 */ 21684 if ((ret != 0) && (vctxt->err == 0)) 21685 vctxt->err = ret; 21686 vctxt->nberrors += pctxt->nberrors; 21687 } else { 21688 /* Add to validation error sum. */ 21689 vctxt->nberrors += pctxt->nberrors; 21690 } 21691 pctxt->doc = NULL; 21692 return(ret); 21693exit_failure: 21694 pctxt->doc = NULL; 21695 return (-1); 21696} 21697 21698static xmlSchemaAttrInfoPtr 21699xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21700 int metaType) 21701{ 21702 if (vctxt->nbAttrInfos == 0) 21703 return (NULL); 21704 { 21705 int i; 21706 xmlSchemaAttrInfoPtr iattr; 21707 21708 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21709 iattr = vctxt->attrInfos[i]; 21710 if (iattr->metaType == metaType) 21711 return (iattr); 21712 } 21713 21714 } 21715 return (NULL); 21716} 21717 21718/** 21719 * xmlSchemaAssembleByXSI: 21720 * @vctxt: a schema validation context 21721 * 21722 * Expands an existing schema by an additional schema using 21723 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21724 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21725 * must be set to 1. 21726 * 21727 * Returns 0 if the new schema is correct, a positive error code 21728 * number otherwise and -1 in case of an internal or API error. 21729 */ 21730static int 21731xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21732{ 21733 const xmlChar *cur, *end; 21734 const xmlChar *nsname = NULL, *location; 21735 int count = 0; 21736 int ret = 0; 21737 xmlSchemaAttrInfoPtr iattr; 21738 21739 /* 21740 * Parse the value; we will assume an even number of values 21741 * to be given (this is how Xerces and XSV work). 21742 * 21743 * URGENT TODO: !! This needs to work for both 21744 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21745 * element !! 21746 */ 21747 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21748 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21749 if (iattr == NULL) 21750 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21751 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21752 if (iattr == NULL) 21753 return (0); 21754 cur = iattr->value; 21755 do { 21756 /* 21757 * TODO: Move the string parsing mechanism away from here. 21758 */ 21759 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21760 /* 21761 * Get the namespace name. 21762 */ 21763 while (IS_BLANK_CH(*cur)) 21764 cur++; 21765 end = cur; 21766 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21767 end++; 21768 if (end == cur) 21769 break; 21770 count++; /* TODO: Don't use the schema's dict. */ 21771 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21772 cur = end; 21773 } 21774 /* 21775 * Get the URI. 21776 */ 21777 while (IS_BLANK_CH(*cur)) 21778 cur++; 21779 end = cur; 21780 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21781 end++; 21782 if (end == cur) { 21783 if (iattr->metaType == 21784 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21785 { 21786 /* 21787 * If using @schemaLocation then tuples are expected. 21788 * I.e. the namespace name *and* the document's URI. 21789 */ 21790 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21791 iattr->node, NULL, 21792 "The value must consist of tuples: the target namespace " 21793 "name and the document's URI", NULL, NULL, NULL); 21794 } 21795 break; 21796 } 21797 count++; /* TODO: Don't use the schema's dict. */ 21798 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21799 cur = end; 21800 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21801 iattr->node, nsname, location); 21802 if (ret == -1) { 21803 VERROR_INT("xmlSchemaAssembleByXSI", 21804 "assembling schemata"); 21805 return (-1); 21806 } 21807 } while (*cur != 0); 21808 return (ret); 21809} 21810 21811static const xmlChar * 21812xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21813 const xmlChar *prefix) 21814{ 21815 if (vctxt->sax != NULL) { 21816 int i, j; 21817 xmlSchemaNodeInfoPtr inode; 21818 21819 for (i = vctxt->depth; i >= 0; i--) { 21820 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21821 inode = vctxt->elemInfos[i]; 21822 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21823 if (((prefix == NULL) && 21824 (inode->nsBindings[j] == NULL)) || 21825 ((prefix != NULL) && xmlStrEqual(prefix, 21826 inode->nsBindings[j]))) { 21827 21828 /* 21829 * Note that the namespace bindings are already 21830 * in a string dict. 21831 */ 21832 return (inode->nsBindings[j+1]); 21833 } 21834 } 21835 } 21836 } 21837 return (NULL); 21838#ifdef LIBXML_READER_ENABLED 21839 } else if (vctxt->reader != NULL) { 21840 xmlChar *nsName; 21841 21842 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21843 if (nsName != NULL) { 21844 const xmlChar *ret; 21845 21846 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21847 xmlFree(nsName); 21848 return (ret); 21849 } else 21850 return (NULL); 21851#endif 21852 } else { 21853 xmlNsPtr ns; 21854 21855 if ((vctxt->inode->node == NULL) || 21856 (vctxt->inode->node->doc == NULL)) { 21857 VERROR_INT("xmlSchemaLookupNamespace", 21858 "no node or node's doc avaliable"); 21859 return (NULL); 21860 } 21861 ns = xmlSearchNs(vctxt->inode->node->doc, 21862 vctxt->inode->node, prefix); 21863 if (ns != NULL) 21864 return (ns->href); 21865 return (NULL); 21866 } 21867} 21868 21869/* 21870* This one works on the schema of the validation context. 21871*/ 21872static int 21873xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21874 xmlSchemaPtr schema, 21875 xmlNodePtr node, 21876 const xmlChar *value, 21877 xmlSchemaValPtr *val, 21878 int valNeeded) 21879{ 21880 int ret; 21881 21882 if (vctxt && (vctxt->schema == NULL)) { 21883 VERROR_INT("xmlSchemaValidateNotation", 21884 "a schema is needed on the validation context"); 21885 return (-1); 21886 } 21887 ret = xmlValidateQName(value, 1); 21888 if (ret != 0) 21889 return (ret); 21890 { 21891 xmlChar *localName = NULL; 21892 xmlChar *prefix = NULL; 21893 21894 localName = xmlSplitQName2(value, &prefix); 21895 if (prefix != NULL) { 21896 const xmlChar *nsName = NULL; 21897 21898 if (vctxt != NULL) 21899 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21900 else if (node != NULL) { 21901 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21902 if (ns != NULL) 21903 nsName = ns->href; 21904 } else { 21905 xmlFree(prefix); 21906 xmlFree(localName); 21907 return (1); 21908 } 21909 if (nsName == NULL) { 21910 xmlFree(prefix); 21911 xmlFree(localName); 21912 return (1); 21913 } 21914 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21915 if ((valNeeded) && (val != NULL)) { 21916 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21917 xmlStrdup(nsName)); 21918 if (*val == NULL) 21919 ret = -1; 21920 } 21921 } else 21922 ret = 1; 21923 xmlFree(prefix); 21924 xmlFree(localName); 21925 } else { 21926 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21927 if (valNeeded && (val != NULL)) { 21928 (*val) = xmlSchemaNewNOTATIONValue( 21929 BAD_CAST xmlStrdup(value), NULL); 21930 if (*val == NULL) 21931 ret = -1; 21932 } 21933 } else 21934 return (1); 21935 } 21936 } 21937 return (ret); 21938} 21939 21940static int 21941xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21942 const xmlChar* lname, 21943 const xmlChar* nsname) 21944{ 21945 int i; 21946 21947 lname = xmlDictLookup(vctxt->dict, lname, -1); 21948 if (lname == NULL) 21949 return(-1); 21950 if (nsname != NULL) { 21951 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21952 if (nsname == NULL) 21953 return(-1); 21954 } 21955 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21956 if ((vctxt->nodeQNames->items [i] == lname) && 21957 (vctxt->nodeQNames->items[i +1] == nsname)) 21958 /* Already there */ 21959 return(i); 21960 } 21961 /* Add new entry. */ 21962 i = vctxt->nodeQNames->nbItems; 21963 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21964 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21965 return(i); 21966} 21967 21968/************************************************************************ 21969 * * 21970 * Validation of identity-constraints (IDC) * 21971 * * 21972 ************************************************************************/ 21973 21974/** 21975 * xmlSchemaAugmentIDC: 21976 * @idcDef: the IDC definition 21977 * 21978 * Creates an augmented IDC definition item. 21979 * 21980 * Returns the item, or NULL on internal errors. 21981 */ 21982static void 21983xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, 21984 xmlSchemaValidCtxtPtr vctxt) 21985{ 21986 xmlSchemaIDCAugPtr aidc; 21987 21988 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 21989 if (aidc == NULL) { 21990 xmlSchemaVErrMemory(vctxt, 21991 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 21992 NULL); 21993 return; 21994 } 21995 aidc->keyrefDepth = -1; 21996 aidc->def = idcDef; 21997 aidc->next = NULL; 21998 if (vctxt->aidcs == NULL) 21999 vctxt->aidcs = aidc; 22000 else { 22001 aidc->next = vctxt->aidcs; 22002 vctxt->aidcs = aidc; 22003 } 22004 /* 22005 * Save if we have keyrefs at all. 22006 */ 22007 if ((vctxt->hasKeyrefs == 0) && 22008 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 22009 vctxt->hasKeyrefs = 1; 22010} 22011 22012/** 22013 * xmlSchemaAugmentImportedIDC: 22014 * @imported: the imported schema 22015 * 22016 * Creates an augmented IDC definition for the imported schema. 22017 */ 22018static void 22019xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) { 22020 if (imported->schema->idcDef != NULL) { 22021 xmlHashScan(imported->schema->idcDef , 22022 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); 22023 } 22024} 22025 22026/** 22027 * xmlSchemaIDCNewBinding: 22028 * @idcDef: the IDC definition of this binding 22029 * 22030 * Creates a new IDC binding. 22031 * 22032 * Returns the new IDC binding, NULL on internal errors. 22033 */ 22034static xmlSchemaPSVIIDCBindingPtr 22035xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22036{ 22037 xmlSchemaPSVIIDCBindingPtr ret; 22038 22039 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22040 sizeof(xmlSchemaPSVIIDCBinding)); 22041 if (ret == NULL) { 22042 xmlSchemaVErrMemory(NULL, 22043 "allocating a PSVI IDC binding item", NULL); 22044 return (NULL); 22045 } 22046 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22047 ret->definition = idcDef; 22048 return (ret); 22049} 22050 22051/** 22052 * xmlSchemaIDCStoreNodeTableItem: 22053 * @vctxt: the WXS validation context 22054 * @item: the IDC node table item 22055 * 22056 * The validation context is used to store IDC node table items. 22057 * They are stored to avoid copying them if IDC node-tables are merged 22058 * with corresponding parent IDC node-tables (bubbling). 22059 * 22060 * Returns 0 if succeeded, -1 on internal errors. 22061 */ 22062static int 22063xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22064 xmlSchemaPSVIIDCNodePtr item) 22065{ 22066 /* 22067 * Add to gobal list. 22068 */ 22069 if (vctxt->idcNodes == NULL) { 22070 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22071 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22072 if (vctxt->idcNodes == NULL) { 22073 xmlSchemaVErrMemory(vctxt, 22074 "allocating the IDC node table item list", NULL); 22075 return (-1); 22076 } 22077 vctxt->sizeIdcNodes = 20; 22078 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22079 vctxt->sizeIdcNodes *= 2; 22080 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22081 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22082 sizeof(xmlSchemaPSVIIDCNodePtr)); 22083 if (vctxt->idcNodes == NULL) { 22084 xmlSchemaVErrMemory(vctxt, 22085 "re-allocating the IDC node table item list", NULL); 22086 return (-1); 22087 } 22088 } 22089 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22090 22091 return (0); 22092} 22093 22094/** 22095 * xmlSchemaIDCStoreKey: 22096 * @vctxt: the WXS validation context 22097 * @item: the IDC key 22098 * 22099 * The validation context is used to store an IDC key. 22100 * 22101 * Returns 0 if succeeded, -1 on internal errors. 22102 */ 22103static int 22104xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22105 xmlSchemaPSVIIDCKeyPtr key) 22106{ 22107 /* 22108 * Add to gobal list. 22109 */ 22110 if (vctxt->idcKeys == NULL) { 22111 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22112 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22113 if (vctxt->idcKeys == NULL) { 22114 xmlSchemaVErrMemory(vctxt, 22115 "allocating the IDC key storage list", NULL); 22116 return (-1); 22117 } 22118 vctxt->sizeIdcKeys = 40; 22119 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22120 vctxt->sizeIdcKeys *= 2; 22121 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22122 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22123 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22124 if (vctxt->idcKeys == NULL) { 22125 xmlSchemaVErrMemory(vctxt, 22126 "re-allocating the IDC key storage list", NULL); 22127 return (-1); 22128 } 22129 } 22130 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22131 22132 return (0); 22133} 22134 22135/** 22136 * xmlSchemaIDCAppendNodeTableItem: 22137 * @bind: the IDC binding 22138 * @ntItem: the node-table item 22139 * 22140 * Appends the IDC node-table item to the binding. 22141 * 22142 * Returns 0 on success and -1 on internal errors. 22143 */ 22144static int 22145xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22146 xmlSchemaPSVIIDCNodePtr ntItem) 22147{ 22148 if (bind->nodeTable == NULL) { 22149 bind->sizeNodes = 10; 22150 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22151 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22152 if (bind->nodeTable == NULL) { 22153 xmlSchemaVErrMemory(NULL, 22154 "allocating an array of IDC node-table items", NULL); 22155 return(-1); 22156 } 22157 } else if (bind->sizeNodes <= bind->nbNodes) { 22158 bind->sizeNodes *= 2; 22159 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22160 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22161 sizeof(xmlSchemaPSVIIDCNodePtr)); 22162 if (bind->nodeTable == NULL) { 22163 xmlSchemaVErrMemory(NULL, 22164 "re-allocating an array of IDC node-table items", NULL); 22165 return(-1); 22166 } 22167 } 22168 bind->nodeTable[bind->nbNodes++] = ntItem; 22169 return(0); 22170} 22171 22172/** 22173 * xmlSchemaIDCAcquireBinding: 22174 * @vctxt: the WXS validation context 22175 * @matcher: the IDC matcher 22176 * 22177 * Looks up an PSVI IDC binding, for the IDC definition and 22178 * of the given matcher. If none found, a new one is created 22179 * and added to the IDC table. 22180 * 22181 * Returns an IDC binding or NULL on internal errors. 22182 */ 22183static xmlSchemaPSVIIDCBindingPtr 22184xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22185 xmlSchemaIDCMatcherPtr matcher) 22186{ 22187 xmlSchemaNodeInfoPtr ielem; 22188 22189 ielem = vctxt->elemInfos[matcher->depth]; 22190 22191 if (ielem->idcTable == NULL) { 22192 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22193 if (ielem->idcTable == NULL) 22194 return (NULL); 22195 return(ielem->idcTable); 22196 } else { 22197 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22198 22199 bind = ielem->idcTable; 22200 do { 22201 if (bind->definition == matcher->aidc->def) 22202 return(bind); 22203 if (bind->next == NULL) { 22204 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22205 if (bind->next == NULL) 22206 return (NULL); 22207 return(bind->next); 22208 } 22209 bind = bind->next; 22210 } while (bind != NULL); 22211 } 22212 return (NULL); 22213} 22214 22215static xmlSchemaItemListPtr 22216xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22217 xmlSchemaIDCMatcherPtr matcher) 22218{ 22219 if (matcher->targets == NULL) 22220 matcher->targets = xmlSchemaItemListCreate(); 22221 return(matcher->targets); 22222} 22223 22224/** 22225 * xmlSchemaIDCFreeKey: 22226 * @key: the IDC key 22227 * 22228 * Frees an IDC key together with its compiled value. 22229 */ 22230static void 22231xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22232{ 22233 if (key->val != NULL) 22234 xmlSchemaFreeValue(key->val); 22235 xmlFree(key); 22236} 22237 22238/** 22239 * xmlSchemaIDCFreeBinding: 22240 * 22241 * Frees an IDC binding. Note that the node table-items 22242 * are not freed. 22243 */ 22244static void 22245xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22246{ 22247 if (bind->nodeTable != NULL) 22248 xmlFree(bind->nodeTable); 22249 if (bind->dupls != NULL) 22250 xmlSchemaItemListFree(bind->dupls); 22251 xmlFree(bind); 22252} 22253 22254/** 22255 * xmlSchemaIDCFreeIDCTable: 22256 * @bind: the first IDC binding in the list 22257 * 22258 * Frees an IDC table, i.e. all the IDC bindings in the list. 22259 */ 22260static void 22261xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22262{ 22263 xmlSchemaPSVIIDCBindingPtr prev; 22264 22265 while (bind != NULL) { 22266 prev = bind; 22267 bind = bind->next; 22268 xmlSchemaIDCFreeBinding(prev); 22269 } 22270} 22271 22272/** 22273 * xmlSchemaIDCFreeMatcherList: 22274 * @matcher: the first IDC matcher in the list 22275 * 22276 * Frees a list of IDC matchers. 22277 */ 22278static void 22279xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22280{ 22281 xmlSchemaIDCMatcherPtr next; 22282 22283 while (matcher != NULL) { 22284 next = matcher->next; 22285 if (matcher->keySeqs != NULL) { 22286 int i; 22287 for (i = 0; i < matcher->sizeKeySeqs; i++) 22288 if (matcher->keySeqs[i] != NULL) 22289 xmlFree(matcher->keySeqs[i]); 22290 xmlFree(matcher->keySeqs); 22291 } 22292 if (matcher->targets != NULL) { 22293 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22294 int i; 22295 xmlSchemaPSVIIDCNodePtr idcNode; 22296 /* 22297 * Node-table items for keyrefs are not stored globally 22298 * to the validation context, since they are not bubbled. 22299 * We need to free them here. 22300 */ 22301 for (i = 0; i < matcher->targets->nbItems; i++) { 22302 idcNode = 22303 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22304 xmlFree(idcNode->keys); 22305 xmlFree(idcNode); 22306 } 22307 } 22308 xmlSchemaItemListFree(matcher->targets); 22309 } 22310 xmlFree(matcher); 22311 matcher = next; 22312 } 22313} 22314 22315/** 22316 * xmlSchemaIDCReleaseMatcherList: 22317 * @vctxt: the WXS validation context 22318 * @matcher: the first IDC matcher in the list 22319 * 22320 * Caches a list of IDC matchers for reuse. 22321 */ 22322static void 22323xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22324 xmlSchemaIDCMatcherPtr matcher) 22325{ 22326 xmlSchemaIDCMatcherPtr next; 22327 22328 while (matcher != NULL) { 22329 next = matcher->next; 22330 if (matcher->keySeqs != NULL) { 22331 int i; 22332 /* 22333 * Don't free the array, but only the content. 22334 */ 22335 for (i = 0; i < matcher->sizeKeySeqs; i++) 22336 if (matcher->keySeqs[i] != NULL) { 22337 xmlFree(matcher->keySeqs[i]); 22338 matcher->keySeqs[i] = NULL; 22339 } 22340 } 22341 if (matcher->targets) { 22342 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22343 int i; 22344 xmlSchemaPSVIIDCNodePtr idcNode; 22345 /* 22346 * Node-table items for keyrefs are not stored globally 22347 * to the validation context, since they are not bubbled. 22348 * We need to free them here. 22349 */ 22350 for (i = 0; i < matcher->targets->nbItems; i++) { 22351 idcNode = 22352 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22353 xmlFree(idcNode->keys); 22354 xmlFree(idcNode); 22355 } 22356 } 22357 xmlSchemaItemListFree(matcher->targets); 22358 matcher->targets = NULL; 22359 } 22360 matcher->next = NULL; 22361 /* 22362 * Cache the matcher. 22363 */ 22364 if (vctxt->idcMatcherCache != NULL) 22365 matcher->nextCached = vctxt->idcMatcherCache; 22366 vctxt->idcMatcherCache = matcher; 22367 22368 matcher = next; 22369 } 22370} 22371 22372/** 22373 * xmlSchemaIDCAddStateObject: 22374 * @vctxt: the WXS validation context 22375 * @matcher: the IDC matcher 22376 * @sel: the XPath information 22377 * @parent: the parent "selector" state object if any 22378 * @type: "selector" or "field" 22379 * 22380 * Creates/reuses and activates state objects for the given 22381 * XPath information; if the XPath expression consists of unions, 22382 * multiple state objects are created for every unioned expression. 22383 * 22384 * Returns 0 on success and -1 on internal errors. 22385 */ 22386static int 22387xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22388 xmlSchemaIDCMatcherPtr matcher, 22389 xmlSchemaIDCSelectPtr sel, 22390 int type) 22391{ 22392 xmlSchemaIDCStateObjPtr sto; 22393 22394 /* 22395 * Reuse the state objects from the pool. 22396 */ 22397 if (vctxt->xpathStatePool != NULL) { 22398 sto = vctxt->xpathStatePool; 22399 vctxt->xpathStatePool = sto->next; 22400 sto->next = NULL; 22401 } else { 22402 /* 22403 * Create a new state object. 22404 */ 22405 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22406 if (sto == NULL) { 22407 xmlSchemaVErrMemory(NULL, 22408 "allocating an IDC state object", NULL); 22409 return (-1); 22410 } 22411 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22412 } 22413 /* 22414 * Add to global list. 22415 */ 22416 if (vctxt->xpathStates != NULL) 22417 sto->next = vctxt->xpathStates; 22418 vctxt->xpathStates = sto; 22419 22420 /* 22421 * Free the old xpath validation context. 22422 */ 22423 if (sto->xpathCtxt != NULL) 22424 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22425 22426 /* 22427 * Create a new XPath (pattern) validation context. 22428 */ 22429 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22430 (xmlPatternPtr) sel->xpathComp); 22431 if (sto->xpathCtxt == NULL) { 22432 VERROR_INT("xmlSchemaIDCAddStateObject", 22433 "failed to create an XPath validation context"); 22434 return (-1); 22435 } 22436 sto->type = type; 22437 sto->depth = vctxt->depth; 22438 sto->matcher = matcher; 22439 sto->sel = sel; 22440 sto->nbHistory = 0; 22441 22442#ifdef DEBUG_IDC 22443 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22444 sto->sel->xpath); 22445#endif 22446 return (0); 22447} 22448 22449/** 22450 * xmlSchemaXPathEvaluate: 22451 * @vctxt: the WXS validation context 22452 * @nodeType: the nodeType of the current node 22453 * 22454 * Evaluates all active XPath state objects. 22455 * 22456 * Returns the number of IC "field" state objects which resolved to 22457 * this node, 0 if none resolved and -1 on internal errors. 22458 */ 22459static int 22460xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22461 xmlElementType nodeType) 22462{ 22463 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22464 int res, resolved = 0, depth = vctxt->depth; 22465 22466 if (vctxt->xpathStates == NULL) 22467 return (0); 22468 22469 if (nodeType == XML_ATTRIBUTE_NODE) 22470 depth++; 22471#ifdef DEBUG_IDC 22472 { 22473 xmlChar *str = NULL; 22474 xmlGenericError(xmlGenericErrorContext, 22475 "IDC: EVAL on %s, depth %d, type %d\n", 22476 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22477 vctxt->inode->localName), depth, nodeType); 22478 FREE_AND_NULL(str) 22479 } 22480#endif 22481 /* 22482 * Process all active XPath state objects. 22483 */ 22484 first = vctxt->xpathStates; 22485 sto = first; 22486 while (sto != head) { 22487#ifdef DEBUG_IDC 22488 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22489 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22490 sto->matcher->aidc->def->name, sto->sel->xpath); 22491 else 22492 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22493 sto->matcher->aidc->def->name, sto->sel->xpath); 22494#endif 22495 if (nodeType == XML_ELEMENT_NODE) 22496 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22497 vctxt->inode->localName, vctxt->inode->nsName); 22498 else 22499 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22500 vctxt->inode->localName, vctxt->inode->nsName); 22501 22502 if (res == -1) { 22503 VERROR_INT("xmlSchemaXPathEvaluate", 22504 "calling xmlStreamPush()"); 22505 return (-1); 22506 } 22507 if (res == 0) 22508 goto next_sto; 22509 /* 22510 * Full match. 22511 */ 22512#ifdef DEBUG_IDC 22513 xmlGenericError(xmlGenericErrorContext, "IDC: " 22514 "MATCH\n"); 22515#endif 22516 /* 22517 * Register a match in the state object history. 22518 */ 22519 if (sto->history == NULL) { 22520 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22521 if (sto->history == NULL) { 22522 xmlSchemaVErrMemory(NULL, 22523 "allocating the state object history", NULL); 22524 return(-1); 22525 } 22526 sto->sizeHistory = 5; 22527 } else if (sto->sizeHistory <= sto->nbHistory) { 22528 sto->sizeHistory *= 2; 22529 sto->history = (int *) xmlRealloc(sto->history, 22530 sto->sizeHistory * sizeof(int)); 22531 if (sto->history == NULL) { 22532 xmlSchemaVErrMemory(NULL, 22533 "re-allocating the state object history", NULL); 22534 return(-1); 22535 } 22536 } 22537 sto->history[sto->nbHistory++] = depth; 22538 22539#ifdef DEBUG_IDC 22540 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22541 vctxt->depth); 22542#endif 22543 22544 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22545 xmlSchemaIDCSelectPtr sel; 22546 /* 22547 * Activate state objects for the IDC fields of 22548 * the IDC selector. 22549 */ 22550#ifdef DEBUG_IDC 22551 xmlGenericError(xmlGenericErrorContext, "IDC: " 22552 "activating field states\n"); 22553#endif 22554 sel = sto->matcher->aidc->def->fields; 22555 while (sel != NULL) { 22556 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22557 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22558 return (-1); 22559 sel = sel->next; 22560 } 22561 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22562 /* 22563 * An IDC key node was found by the IDC field. 22564 */ 22565#ifdef DEBUG_IDC 22566 xmlGenericError(xmlGenericErrorContext, 22567 "IDC: key found\n"); 22568#endif 22569 /* 22570 * Notify that the character value of this node is 22571 * needed. 22572 */ 22573 if (resolved == 0) { 22574 if ((vctxt->inode->flags & 22575 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22576 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22577 } 22578 resolved++; 22579 } 22580next_sto: 22581 if (sto->next == NULL) { 22582 /* 22583 * Evaluate field state objects created on this node as well. 22584 */ 22585 head = first; 22586 sto = vctxt->xpathStates; 22587 } else 22588 sto = sto->next; 22589 } 22590 return (resolved); 22591} 22592 22593static const xmlChar * 22594xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22595 xmlChar **buf, 22596 xmlSchemaPSVIIDCKeyPtr *seq, 22597 int count) 22598{ 22599 int i, res; 22600 xmlChar *value = NULL; 22601 22602 *buf = xmlStrdup(BAD_CAST "["); 22603 for (i = 0; i < count; i++) { 22604 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22605 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22606 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22607 &value); 22608 if (res == 0) 22609 *buf = xmlStrcat(*buf, BAD_CAST value); 22610 else { 22611 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22612 "failed to compute a canonical value"); 22613 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22614 } 22615 if (i < count -1) 22616 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22617 else 22618 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22619 if (value != NULL) { 22620 xmlFree(value); 22621 value = NULL; 22622 } 22623 } 22624 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22625 22626 return (BAD_CAST *buf); 22627} 22628 22629/** 22630 * xmlSchemaXPathPop: 22631 * @vctxt: the WXS validation context 22632 * 22633 * Pops all XPath states. 22634 * 22635 * Returns 0 on success and -1 on internal errors. 22636 */ 22637static int 22638xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22639{ 22640 xmlSchemaIDCStateObjPtr sto; 22641 int res; 22642 22643 if (vctxt->xpathStates == NULL) 22644 return(0); 22645 sto = vctxt->xpathStates; 22646 do { 22647 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22648 if (res == -1) 22649 return (-1); 22650 sto = sto->next; 22651 } while (sto != NULL); 22652 return(0); 22653} 22654 22655/** 22656 * xmlSchemaXPathProcessHistory: 22657 * @vctxt: the WXS validation context 22658 * @type: the simple/complex type of the current node if any at all 22659 * @val: the precompiled value 22660 * 22661 * Processes and pops the history items of the IDC state objects. 22662 * IDC key-sequences are validated/created on IDC bindings. 22663 * 22664 * Returns 0 on success and -1 on internal errors. 22665 */ 22666static int 22667xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22668 int depth) 22669{ 22670 xmlSchemaIDCStateObjPtr sto, nextsto; 22671 int res, matchDepth; 22672 xmlSchemaPSVIIDCKeyPtr key = NULL; 22673 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22674 22675 if (vctxt->xpathStates == NULL) 22676 return (0); 22677 sto = vctxt->xpathStates; 22678 22679#ifdef DEBUG_IDC 22680 { 22681 xmlChar *str = NULL; 22682 xmlGenericError(xmlGenericErrorContext, 22683 "IDC: BACK on %s, depth %d\n", 22684 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22685 vctxt->inode->localName), vctxt->depth); 22686 FREE_AND_NULL(str) 22687 } 22688#endif 22689 /* 22690 * Evaluate the state objects. 22691 */ 22692 while (sto != NULL) { 22693 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22694 if (res == -1) { 22695 VERROR_INT("xmlSchemaXPathProcessHistory", 22696 "calling xmlStreamPop()"); 22697 return (-1); 22698 } 22699#ifdef DEBUG_IDC 22700 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22701 sto->sel->xpath); 22702#endif 22703 if (sto->nbHistory == 0) 22704 goto deregister_check; 22705 22706 matchDepth = sto->history[sto->nbHistory -1]; 22707 22708 /* 22709 * Only matches at the current depth are of interest. 22710 */ 22711 if (matchDepth != depth) { 22712 sto = sto->next; 22713 continue; 22714 } 22715 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22716 /* 22717 * NOTE: According to 22718 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22719 * ... the simple-content of complex types is also allowed. 22720 */ 22721 22722 if (WXS_IS_COMPLEX(type)) { 22723 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22724 /* 22725 * Sanity check for complex types with simple content. 22726 */ 22727 simpleType = type->contentTypeDef; 22728 if (simpleType == NULL) { 22729 VERROR_INT("xmlSchemaXPathProcessHistory", 22730 "field resolves to a CT with simple content " 22731 "but the CT is missing the ST definition"); 22732 return (-1); 22733 } 22734 } else 22735 simpleType = NULL; 22736 } else 22737 simpleType = type; 22738 if (simpleType == NULL) { 22739 xmlChar *str = NULL; 22740 22741 /* 22742 * Not qualified if the field resolves to a node of non 22743 * simple type. 22744 */ 22745 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22746 XML_SCHEMAV_CVC_IDC, NULL, 22747 WXS_BASIC_CAST sto->matcher->aidc->def, 22748 "The XPath '%s' of a field of %s does evaluate to a node of " 22749 "non-simple type", 22750 sto->sel->xpath, 22751 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22752 FREE_AND_NULL(str); 22753 sto->nbHistory--; 22754 goto deregister_check; 22755 } 22756 22757 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22758 /* 22759 * Failed to provide the normalized value; maybe 22760 * the value was invalid. 22761 */ 22762 VERROR(XML_SCHEMAV_CVC_IDC, 22763 WXS_BASIC_CAST sto->matcher->aidc->def, 22764 "Warning: No precomputed value available, the value " 22765 "was either invalid or something strange happend"); 22766 sto->nbHistory--; 22767 goto deregister_check; 22768 } else { 22769 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22770 xmlSchemaPSVIIDCKeyPtr *keySeq; 22771 int pos, idx; 22772 22773 /* 22774 * The key will be anchored on the matcher's list of 22775 * key-sequences. The position in this list is determined 22776 * by the target node's depth relative to the matcher's 22777 * depth of creation (i.e. the depth of the scope element). 22778 * 22779 * Element Depth Pos List-entries 22780 * <scope> 0 NULL 22781 * <bar> 1 NULL 22782 * <target/> 2 2 target 22783 * <bar> 22784 * </scope> 22785 * 22786 * The size of the list is only dependant on the depth of 22787 * the tree. 22788 * An entry will be NULLed in selector_leave, i.e. when 22789 * we hit the target's 22790 */ 22791 pos = sto->depth - matcher->depth; 22792 idx = sto->sel->index; 22793 22794 /* 22795 * Create/grow the array of key-sequences. 22796 */ 22797 if (matcher->keySeqs == NULL) { 22798 if (pos > 9) 22799 matcher->sizeKeySeqs = pos * 2; 22800 else 22801 matcher->sizeKeySeqs = 10; 22802 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22803 xmlMalloc(matcher->sizeKeySeqs * 22804 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22805 if (matcher->keySeqs == NULL) { 22806 xmlSchemaVErrMemory(NULL, 22807 "allocating an array of key-sequences", 22808 NULL); 22809 return(-1); 22810 } 22811 memset(matcher->keySeqs, 0, 22812 matcher->sizeKeySeqs * 22813 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22814 } else if (pos >= matcher->sizeKeySeqs) { 22815 int i = matcher->sizeKeySeqs; 22816 22817 matcher->sizeKeySeqs *= 2; 22818 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22819 xmlRealloc(matcher->keySeqs, 22820 matcher->sizeKeySeqs * 22821 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22822 if (matcher->keySeqs == NULL) { 22823 xmlSchemaVErrMemory(NULL, 22824 "reallocating an array of key-sequences", 22825 NULL); 22826 return (-1); 22827 } 22828 /* 22829 * The array needs to be NULLed. 22830 * TODO: Use memset? 22831 */ 22832 for (; i < matcher->sizeKeySeqs; i++) 22833 matcher->keySeqs[i] = NULL; 22834 } 22835 22836 /* 22837 * Get/create the key-sequence. 22838 */ 22839 keySeq = matcher->keySeqs[pos]; 22840 if (keySeq == NULL) { 22841 goto create_sequence; 22842 } else if (keySeq[idx] != NULL) { 22843 xmlChar *str = NULL; 22844 /* 22845 * cvc-identity-constraint: 22846 * 3 For each node in the `target node set` all 22847 * of the {fields}, with that node as the context 22848 * node, evaluate to either an empty node-set or 22849 * a node-set with exactly one member, which must 22850 * have a simple type. 22851 * 22852 * The key was already set; report an error. 22853 */ 22854 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22855 XML_SCHEMAV_CVC_IDC, NULL, 22856 WXS_BASIC_CAST matcher->aidc->def, 22857 "The XPath '%s' of a field of %s evaluates to a " 22858 "node-set with more than one member", 22859 sto->sel->xpath, 22860 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22861 FREE_AND_NULL(str); 22862 sto->nbHistory--; 22863 goto deregister_check; 22864 } else 22865 goto create_key; 22866 22867create_sequence: 22868 /* 22869 * Create a key-sequence. 22870 */ 22871 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22872 matcher->aidc->def->nbFields * 22873 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22874 if (keySeq == NULL) { 22875 xmlSchemaVErrMemory(NULL, 22876 "allocating an IDC key-sequence", NULL); 22877 return(-1); 22878 } 22879 memset(keySeq, 0, matcher->aidc->def->nbFields * 22880 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22881 matcher->keySeqs[pos] = keySeq; 22882create_key: 22883 /* 22884 * Create a key once per node only. 22885 */ 22886 if (key == NULL) { 22887 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22888 sizeof(xmlSchemaPSVIIDCKey)); 22889 if (key == NULL) { 22890 xmlSchemaVErrMemory(NULL, 22891 "allocating a IDC key", NULL); 22892 xmlFree(keySeq); 22893 matcher->keySeqs[pos] = NULL; 22894 return(-1); 22895 } 22896 /* 22897 * Consume the compiled value. 22898 */ 22899 key->type = simpleType; 22900 key->val = vctxt->inode->val; 22901 vctxt->inode->val = NULL; 22902 /* 22903 * Store the key in a global list. 22904 */ 22905 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22906 xmlSchemaIDCFreeKey(key); 22907 return (-1); 22908 } 22909 } 22910 keySeq[idx] = key; 22911 } 22912 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22913 22914 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22915 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22916 xmlSchemaPSVIIDCNodePtr ntItem; 22917 xmlSchemaIDCMatcherPtr matcher; 22918 xmlSchemaIDCPtr idc; 22919 xmlSchemaItemListPtr targets; 22920 int pos, i, j, nbKeys; 22921 /* 22922 * Here we have the following scenario: 22923 * An IDC 'selector' state object resolved to a target node, 22924 * during the time this target node was in the 22925 * ancestor-or-self axis, the 'field' state object(s) looked 22926 * out for matching nodes to create a key-sequence for this 22927 * target node. Now we are back to this target node and need 22928 * to put the key-sequence, together with the target node 22929 * itself, into the node-table of the corresponding IDC 22930 * binding. 22931 */ 22932 matcher = sto->matcher; 22933 idc = matcher->aidc->def; 22934 nbKeys = idc->nbFields; 22935 pos = depth - matcher->depth; 22936 /* 22937 * Check if the matcher has any key-sequences at all, plus 22938 * if it has a key-sequence for the current target node. 22939 */ 22940 if ((matcher->keySeqs == NULL) || 22941 (matcher->sizeKeySeqs <= pos)) { 22942 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22943 goto selector_key_error; 22944 else 22945 goto selector_leave; 22946 } 22947 22948 keySeq = &(matcher->keySeqs[pos]); 22949 if (*keySeq == NULL) { 22950 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22951 goto selector_key_error; 22952 else 22953 goto selector_leave; 22954 } 22955 22956 for (i = 0; i < nbKeys; i++) { 22957 if ((*keySeq)[i] == NULL) { 22958 /* 22959 * Not qualified, if not all fields did resolve. 22960 */ 22961 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22962 /* 22963 * All fields of a "key" IDC must resolve. 22964 */ 22965 goto selector_key_error; 22966 } 22967 goto selector_leave; 22968 } 22969 } 22970 /* 22971 * All fields did resolve. 22972 */ 22973 22974 /* 22975 * 4.1 If the {identity-constraint category} is unique(/key), 22976 * then no two members of the `qualified node set` have 22977 * `key-sequences` whose members are pairwise equal, as 22978 * defined by Equal in [XML Schemas: Datatypes]. 22979 * 22980 * Get the IDC binding from the matcher and check for 22981 * duplicate key-sequences. 22982 */ 22983#if 0 22984 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 22985#endif 22986 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 22987 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 22988 (targets->nbItems != 0)) { 22989 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 22990 22991 i = 0; 22992 res = 0; 22993 /* 22994 * Compare the key-sequences, key by key. 22995 */ 22996 do { 22997 bkeySeq = 22998 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 22999 for (j = 0; j < nbKeys; j++) { 23000 ckey = (*keySeq)[j]; 23001 bkey = bkeySeq[j]; 23002 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 23003 if (res == -1) { 23004 return (-1); 23005 } else if (res == 0) { 23006 /* 23007 * One of the keys differs, so the key-sequence 23008 * won't be equal; get out. 23009 */ 23010 break; 23011 } 23012 } 23013 if (res == 1) { 23014 /* 23015 * Duplicate key-sequence found. 23016 */ 23017 break; 23018 } 23019 i++; 23020 } while (i < targets->nbItems); 23021 if (i != targets->nbItems) { 23022 xmlChar *str = NULL, *strB = NULL; 23023 /* 23024 * TODO: Try to report the key-sequence. 23025 */ 23026 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23027 XML_SCHEMAV_CVC_IDC, NULL, 23028 WXS_BASIC_CAST idc, 23029 "Duplicate key-sequence %s in %s", 23030 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23031 (*keySeq), nbKeys), 23032 xmlSchemaGetIDCDesignation(&strB, idc)); 23033 FREE_AND_NULL(str); 23034 FREE_AND_NULL(strB); 23035 goto selector_leave; 23036 } 23037 } 23038 /* 23039 * Add a node-table item to the IDC binding. 23040 */ 23041 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23042 sizeof(xmlSchemaPSVIIDCNode)); 23043 if (ntItem == NULL) { 23044 xmlSchemaVErrMemory(NULL, 23045 "allocating an IDC node-table item", NULL); 23046 xmlFree(*keySeq); 23047 *keySeq = NULL; 23048 return(-1); 23049 } 23050 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23051 23052 /* 23053 * Store the node-table item in a global list. 23054 */ 23055 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23056 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23057 xmlFree(ntItem); 23058 xmlFree(*keySeq); 23059 *keySeq = NULL; 23060 return (-1); 23061 } 23062 ntItem->nodeQNameID = -1; 23063 } else { 23064 /* 23065 * Save a cached QName for this node on the IDC node, to be 23066 * able to report it, even if the node is not saved. 23067 */ 23068 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23069 vctxt->inode->localName, vctxt->inode->nsName); 23070 if (ntItem->nodeQNameID == -1) { 23071 xmlFree(ntItem); 23072 xmlFree(*keySeq); 23073 *keySeq = NULL; 23074 return (-1); 23075 } 23076 } 23077 /* 23078 * Init the node-table item: Save the node, position and 23079 * consume the key-sequence. 23080 */ 23081 ntItem->node = vctxt->node; 23082 ntItem->nodeLine = vctxt->inode->nodeLine; 23083 ntItem->keys = *keySeq; 23084 *keySeq = NULL; 23085#if 0 23086 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23087#endif 23088 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23089 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23090 /* 23091 * Free the item, since keyref items won't be 23092 * put on a global list. 23093 */ 23094 xmlFree(ntItem->keys); 23095 xmlFree(ntItem); 23096 } 23097 return (-1); 23098 } 23099 23100 goto selector_leave; 23101selector_key_error: 23102 { 23103 xmlChar *str = NULL; 23104 /* 23105 * 4.2.1 (KEY) The `target node set` and the 23106 * `qualified node set` are equal, that is, every 23107 * member of the `target node set` is also a member 23108 * of the `qualified node set` and vice versa. 23109 */ 23110 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23111 XML_SCHEMAV_CVC_IDC, NULL, 23112 WXS_BASIC_CAST idc, 23113 "Not all fields of %s evaluate to a node", 23114 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23115 FREE_AND_NULL(str); 23116 } 23117selector_leave: 23118 /* 23119 * Free the key-sequence if not added to the IDC table. 23120 */ 23121 if ((keySeq != NULL) && (*keySeq != NULL)) { 23122 xmlFree(*keySeq); 23123 *keySeq = NULL; 23124 } 23125 } /* if selector */ 23126 23127 sto->nbHistory--; 23128 23129deregister_check: 23130 /* 23131 * Deregister state objects if they reach the depth of creation. 23132 */ 23133 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23134#ifdef DEBUG_IDC 23135 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23136 sto->sel->xpath); 23137#endif 23138 if (vctxt->xpathStates != sto) { 23139 VERROR_INT("xmlSchemaXPathProcessHistory", 23140 "The state object to be removed is not the first " 23141 "in the list"); 23142 } 23143 nextsto = sto->next; 23144 /* 23145 * Unlink from the list of active XPath state objects. 23146 */ 23147 vctxt->xpathStates = sto->next; 23148 sto->next = vctxt->xpathStatePool; 23149 /* 23150 * Link it to the pool of reusable state objects. 23151 */ 23152 vctxt->xpathStatePool = sto; 23153 sto = nextsto; 23154 } else 23155 sto = sto->next; 23156 } /* while (sto != NULL) */ 23157 return (0); 23158} 23159 23160/** 23161 * xmlSchemaIDCRegisterMatchers: 23162 * @vctxt: the WXS validation context 23163 * @elemDecl: the element declaration 23164 * 23165 * Creates helper objects to evaluate IDC selectors/fields 23166 * successively. 23167 * 23168 * Returns 0 if OK and -1 on internal errors. 23169 */ 23170static int 23171xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23172 xmlSchemaElementPtr elemDecl) 23173{ 23174 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23175 xmlSchemaIDCPtr idc, refIdc; 23176 xmlSchemaIDCAugPtr aidc; 23177 23178 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23179 if (idc == NULL) 23180 return (0); 23181 23182#ifdef DEBUG_IDC 23183 { 23184 xmlChar *str = NULL; 23185 xmlGenericError(xmlGenericErrorContext, 23186 "IDC: REGISTER on %s, depth %d\n", 23187 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23188 vctxt->inode->localName), vctxt->depth); 23189 FREE_AND_NULL(str) 23190 } 23191#endif 23192 if (vctxt->inode->idcMatchers != NULL) { 23193 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23194 "The chain of IDC matchers is expected to be empty"); 23195 return (-1); 23196 } 23197 do { 23198 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23199 /* 23200 * Since IDCs bubbles are expensive we need to know the 23201 * depth at which the bubbles should stop; this will be 23202 * the depth of the top-most keyref IDC. If no keyref 23203 * references a key/unique IDC, the keyrefDepth will 23204 * be -1, indicating that no bubbles are needed. 23205 */ 23206 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23207 if (refIdc != NULL) { 23208 /* 23209 * Remember that we have keyrefs on this node. 23210 */ 23211 vctxt->inode->hasKeyrefs = 1; 23212 /* 23213 * Lookup the referenced augmented IDC info. 23214 */ 23215 aidc = vctxt->aidcs; 23216 while (aidc != NULL) { 23217 if (aidc->def == refIdc) 23218 break; 23219 aidc = aidc->next; 23220 } 23221 if (aidc == NULL) { 23222 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23223 "Could not find an augmented IDC item for an IDC " 23224 "definition"); 23225 return (-1); 23226 } 23227 if ((aidc->keyrefDepth == -1) || 23228 (vctxt->depth < aidc->keyrefDepth)) 23229 aidc->keyrefDepth = vctxt->depth; 23230 } 23231 } 23232 /* 23233 * Lookup the augmented IDC item for the IDC definition. 23234 */ 23235 aidc = vctxt->aidcs; 23236 while (aidc != NULL) { 23237 if (aidc->def == idc) 23238 break; 23239 aidc = aidc->next; 23240 } 23241 if (aidc == NULL) { 23242 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23243 "Could not find an augmented IDC item for an IDC definition"); 23244 return (-1); 23245 } 23246 /* 23247 * Create an IDC matcher for every IDC definition. 23248 */ 23249 if (vctxt->idcMatcherCache != NULL) { 23250 /* 23251 * Reuse a cached matcher. 23252 */ 23253 matcher = vctxt->idcMatcherCache; 23254 vctxt->idcMatcherCache = matcher->nextCached; 23255 matcher->nextCached = NULL; 23256 } else { 23257 matcher = (xmlSchemaIDCMatcherPtr) 23258 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23259 if (matcher == NULL) { 23260 xmlSchemaVErrMemory(vctxt, 23261 "allocating an IDC matcher", NULL); 23262 return (-1); 23263 } 23264 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23265 } 23266 if (last == NULL) 23267 vctxt->inode->idcMatchers = matcher; 23268 else 23269 last->next = matcher; 23270 last = matcher; 23271 23272 matcher->type = IDC_MATCHER; 23273 matcher->depth = vctxt->depth; 23274 matcher->aidc = aidc; 23275 matcher->idcType = aidc->def->type; 23276#ifdef DEBUG_IDC 23277 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23278#endif 23279 /* 23280 * Init the automaton state object. 23281 */ 23282 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23283 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23284 return (-1); 23285 23286 idc = idc->next; 23287 } while (idc != NULL); 23288 return (0); 23289} 23290 23291static int 23292xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23293 xmlSchemaNodeInfoPtr ielem) 23294{ 23295 xmlSchemaPSVIIDCBindingPtr bind; 23296 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23297 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23298 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23299 23300 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23301 /* vctxt->createIDCNodeTables */ 23302 while (matcher != NULL) { 23303 /* 23304 * Skip keyref IDCs and empty IDC target-lists. 23305 */ 23306 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23307 WXS_ILIST_IS_EMPTY(matcher->targets)) 23308 { 23309 matcher = matcher->next; 23310 continue; 23311 } 23312 /* 23313 * If we _want_ the IDC node-table to be created in any case 23314 * then do so. Otherwise create them only if keyrefs need them. 23315 */ 23316 if ((! vctxt->createIDCNodeTables) && 23317 ((matcher->aidc->keyrefDepth == -1) || 23318 (matcher->aidc->keyrefDepth > vctxt->depth))) 23319 { 23320 matcher = matcher->next; 23321 continue; 23322 } 23323 /* 23324 * Get/create the IDC binding on this element for the IDC definition. 23325 */ 23326 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23327 23328 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23329 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23330 nbDupls = bind->dupls->nbItems; 23331 } else { 23332 dupls = NULL; 23333 nbDupls = 0; 23334 } 23335 if (bind->nodeTable != NULL) { 23336 nbNodeTable = bind->nbNodes; 23337 } else { 23338 nbNodeTable = 0; 23339 } 23340 23341 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23342 /* 23343 * Transfer all IDC target-nodes to the IDC node-table. 23344 */ 23345 bind->nodeTable = 23346 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23347 bind->sizeNodes = matcher->targets->sizeItems; 23348 bind->nbNodes = matcher->targets->nbItems; 23349 23350 matcher->targets->items = NULL; 23351 matcher->targets->sizeItems = 0; 23352 matcher->targets->nbItems = 0; 23353 } else { 23354 /* 23355 * Compare the key-sequences and add to the IDC node-table. 23356 */ 23357 nbTargets = matcher->targets->nbItems; 23358 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23359 nbFields = matcher->aidc->def->nbFields; 23360 i = 0; 23361 do { 23362 keys = targets[i]->keys; 23363 if (nbDupls) { 23364 /* 23365 * Search in already found duplicates first. 23366 */ 23367 j = 0; 23368 do { 23369 if (nbFields == 1) { 23370 res = xmlSchemaAreValuesEqual(keys[0]->val, 23371 dupls[j]->keys[0]->val); 23372 if (res == -1) 23373 goto internal_error; 23374 if (res == 1) { 23375 /* 23376 * Equal key-sequence. 23377 */ 23378 goto next_target; 23379 } 23380 } else { 23381 res = 0; 23382 ntkeys = dupls[j]->keys; 23383 for (k = 0; k < nbFields; k++) { 23384 res = xmlSchemaAreValuesEqual(keys[k]->val, 23385 ntkeys[k]->val); 23386 if (res == -1) 23387 goto internal_error; 23388 if (res == 0) { 23389 /* 23390 * One of the keys differs. 23391 */ 23392 break; 23393 } 23394 } 23395 if (res == 1) { 23396 /* 23397 * Equal key-sequence found. 23398 */ 23399 goto next_target; 23400 } 23401 } 23402 j++; 23403 } while (j < nbDupls); 23404 } 23405 if (nbNodeTable) { 23406 j = 0; 23407 do { 23408 if (nbFields == 1) { 23409 res = xmlSchemaAreValuesEqual(keys[0]->val, 23410 bind->nodeTable[j]->keys[0]->val); 23411 if (res == -1) 23412 goto internal_error; 23413 if (res == 0) { 23414 /* 23415 * The key-sequence differs. 23416 */ 23417 goto next_node_table_entry; 23418 } 23419 } else { 23420 res = 0; 23421 ntkeys = bind->nodeTable[j]->keys; 23422 for (k = 0; k < nbFields; k++) { 23423 res = xmlSchemaAreValuesEqual(keys[k]->val, 23424 ntkeys[k]->val); 23425 if (res == -1) 23426 goto internal_error; 23427 if (res == 0) { 23428 /* 23429 * One of the keys differs. 23430 */ 23431 goto next_node_table_entry; 23432 } 23433 } 23434 } 23435 /* 23436 * Add the duplicate to the list of duplicates. 23437 */ 23438 if (bind->dupls == NULL) { 23439 bind->dupls = xmlSchemaItemListCreate(); 23440 if (bind->dupls == NULL) 23441 goto internal_error; 23442 } 23443 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23444 goto internal_error; 23445 /* 23446 * Remove the duplicate entry from the IDC node-table. 23447 */ 23448 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23449 bind->nbNodes--; 23450 23451 goto next_target; 23452 23453next_node_table_entry: 23454 j++; 23455 } while (j < nbNodeTable); 23456 } 23457 /* 23458 * If everything is fine, then add the IDC target-node to 23459 * the IDC node-table. 23460 */ 23461 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23462 goto internal_error; 23463 23464next_target: 23465 i++; 23466 } while (i < nbTargets); 23467 } 23468 matcher = matcher->next; 23469 } 23470 return(0); 23471 23472internal_error: 23473 return(-1); 23474} 23475 23476/** 23477 * xmlSchemaBubbleIDCNodeTables: 23478 * @depth: the current tree depth 23479 * 23480 * Merges IDC bindings of an element at @depth into the corresponding IDC 23481 * bindings of its parent element. If a duplicate note-table entry is found, 23482 * both, the parent node-table entry and child entry are discarded from the 23483 * node-table of the parent. 23484 * 23485 * Returns 0 if OK and -1 on internal errors. 23486 */ 23487static int 23488xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23489{ 23490 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23491 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23492 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23493 xmlSchemaIDCAugPtr aidc; 23494 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23495 23496 bind = vctxt->inode->idcTable; 23497 if (bind == NULL) { 23498 /* Fine, no table, no bubbles. */ 23499 return (0); 23500 } 23501 23502 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23503 /* 23504 * Walk all bindings; create new or add to existing bindings. 23505 * Remove duplicate key-sequences. 23506 */ 23507 while (bind != NULL) { 23508 23509 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23510 goto next_binding; 23511 /* 23512 * Check if the key/unique IDC table needs to be bubbled. 23513 */ 23514 if (! vctxt->createIDCNodeTables) { 23515 aidc = vctxt->aidcs; 23516 do { 23517 if (aidc->def == bind->definition) { 23518 if ((aidc->keyrefDepth == -1) || 23519 (aidc->keyrefDepth >= vctxt->depth)) { 23520 goto next_binding; 23521 } 23522 break; 23523 } 23524 aidc = aidc->next; 23525 } while (aidc != NULL); 23526 } 23527 23528 if (parTable != NULL) 23529 parBind = *parTable; 23530 /* 23531 * Search a matching parent binding for the 23532 * IDC definition. 23533 */ 23534 while (parBind != NULL) { 23535 if (parBind->definition == bind->definition) 23536 break; 23537 parBind = parBind->next; 23538 } 23539 23540 if (parBind != NULL) { 23541 /* 23542 * Compare every node-table entry of the child node, 23543 * i.e. the key-sequence within, ... 23544 */ 23545 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23546 23547 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23548 oldDupls = parBind->dupls->nbItems; 23549 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23550 } else { 23551 dupls = NULL; 23552 oldDupls = 0; 23553 } 23554 23555 parNodes = parBind->nodeTable; 23556 nbFields = bind->definition->nbFields; 23557 23558 for (i = 0; i < bind->nbNodes; i++) { 23559 node = bind->nodeTable[i]; 23560 if (node == NULL) 23561 continue; 23562 /* 23563 * ...with every key-sequence of the parent node, already 23564 * evaluated to be a duplicate key-sequence. 23565 */ 23566 if (oldDupls) { 23567 j = 0; 23568 while (j < oldDupls) { 23569 if (nbFields == 1) { 23570 ret = xmlSchemaAreValuesEqual( 23571 node->keys[0]->val, 23572 dupls[j]->keys[0]->val); 23573 if (ret == -1) 23574 goto internal_error; 23575 if (ret == 0) { 23576 j++; 23577 continue; 23578 } 23579 } else { 23580 parNode = dupls[j]; 23581 for (k = 0; k < nbFields; k++) { 23582 ret = xmlSchemaAreValuesEqual( 23583 node->keys[k]->val, 23584 parNode->keys[k]->val); 23585 if (ret == -1) 23586 goto internal_error; 23587 if (ret == 0) 23588 break; 23589 } 23590 } 23591 if (ret == 1) 23592 /* Duplicate found. */ 23593 break; 23594 j++; 23595 } 23596 if (j != oldDupls) { 23597 /* Duplicate found. Skip this entry. */ 23598 continue; 23599 } 23600 } 23601 /* 23602 * ... and with every key-sequence of the parent node. 23603 */ 23604 if (oldNum) { 23605 j = 0; 23606 while (j < oldNum) { 23607 parNode = parNodes[j]; 23608 if (nbFields == 1) { 23609 ret = xmlSchemaAreValuesEqual( 23610 node->keys[0]->val, 23611 parNode->keys[0]->val); 23612 if (ret == -1) 23613 goto internal_error; 23614 if (ret == 0) { 23615 j++; 23616 continue; 23617 } 23618 } else { 23619 for (k = 0; k < nbFields; k++) { 23620 ret = xmlSchemaAreValuesEqual( 23621 node->keys[k]->val, 23622 parNode->keys[k]->val); 23623 if (ret == -1) 23624 goto internal_error; 23625 if (ret == 0) 23626 break; 23627 } 23628 } 23629 if (ret == 1) 23630 /* Duplicate found. */ 23631 break; 23632 j++; 23633 } 23634 if (j != oldNum) { 23635 /* 23636 * Handle duplicates. Move the duplicate in 23637 * the parent's node-table to the list of 23638 * duplicates. 23639 */ 23640 oldNum--; 23641 parBind->nbNodes--; 23642 /* 23643 * Move last old item to pos of duplicate. 23644 */ 23645 parNodes[j] = parNodes[oldNum]; 23646 23647 if (parBind->nbNodes != oldNum) { 23648 /* 23649 * If new items exist, move last new item to 23650 * last of old items. 23651 */ 23652 parNodes[oldNum] = 23653 parNodes[parBind->nbNodes]; 23654 } 23655 if (parBind->dupls == NULL) { 23656 parBind->dupls = xmlSchemaItemListCreate(); 23657 if (parBind->dupls == NULL) 23658 goto internal_error; 23659 } 23660 xmlSchemaItemListAdd(parBind->dupls, parNode); 23661 } else { 23662 /* 23663 * Add the node-table entry (node and key-sequence) of 23664 * the child node to the node table of the parent node. 23665 */ 23666 if (parBind->nodeTable == NULL) { 23667 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23668 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23669 if (parBind->nodeTable == NULL) { 23670 xmlSchemaVErrMemory(NULL, 23671 "allocating IDC list of node-table items", NULL); 23672 goto internal_error; 23673 } 23674 parBind->sizeNodes = 1; 23675 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23676 parBind->sizeNodes *= 2; 23677 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23678 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23679 sizeof(xmlSchemaPSVIIDCNodePtr)); 23680 if (parBind->nodeTable == NULL) { 23681 xmlSchemaVErrMemory(NULL, 23682 "re-allocating IDC list of node-table items", NULL); 23683 goto internal_error; 23684 } 23685 } 23686 parNodes = parBind->nodeTable; 23687 /* 23688 * Append the new node-table entry to the 'new node-table 23689 * entries' section. 23690 */ 23691 parNodes[parBind->nbNodes++] = node; 23692 } 23693 23694 } 23695 23696 } 23697 } else { 23698 /* 23699 * No binding for the IDC was found: create a new one and 23700 * copy all node-tables. 23701 */ 23702 parBind = xmlSchemaIDCNewBinding(bind->definition); 23703 if (parBind == NULL) 23704 goto internal_error; 23705 23706 /* 23707 * TODO: Hmm, how to optimize the initial number of 23708 * allocated entries? 23709 */ 23710 if (bind->nbNodes != 0) { 23711 /* 23712 * Add all IDC node-table entries. 23713 */ 23714 if (! vctxt->psviExposeIDCNodeTables) { 23715 /* 23716 * Just move the entries. 23717 * NOTE: this is quite save here, since 23718 * all the keyref lookups have already been 23719 * performed. 23720 */ 23721 parBind->nodeTable = bind->nodeTable; 23722 bind->nodeTable = NULL; 23723 parBind->sizeNodes = bind->sizeNodes; 23724 bind->sizeNodes = 0; 23725 parBind->nbNodes = bind->nbNodes; 23726 bind->nbNodes = 0; 23727 } else { 23728 /* 23729 * Copy the entries. 23730 */ 23731 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23732 xmlMalloc(bind->nbNodes * 23733 sizeof(xmlSchemaPSVIIDCNodePtr)); 23734 if (parBind->nodeTable == NULL) { 23735 xmlSchemaVErrMemory(NULL, 23736 "allocating an array of IDC node-table " 23737 "items", NULL); 23738 xmlSchemaIDCFreeBinding(parBind); 23739 goto internal_error; 23740 } 23741 parBind->sizeNodes = bind->nbNodes; 23742 parBind->nbNodes = bind->nbNodes; 23743 memcpy(parBind->nodeTable, bind->nodeTable, 23744 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23745 } 23746 } 23747 if (bind->dupls) { 23748 /* 23749 * Move the duplicates. 23750 */ 23751 if (parBind->dupls != NULL) 23752 xmlSchemaItemListFree(parBind->dupls); 23753 parBind->dupls = bind->dupls; 23754 bind->dupls = NULL; 23755 } 23756 if (parTable != NULL) { 23757 if (*parTable == NULL) 23758 *parTable = parBind; 23759 else { 23760 parBind->next = *parTable; 23761 *parTable = parBind; 23762 } 23763 } 23764 } 23765 23766next_binding: 23767 bind = bind->next; 23768 } 23769 return (0); 23770 23771internal_error: 23772 return(-1); 23773} 23774 23775/** 23776 * xmlSchemaCheckCVCIDCKeyRef: 23777 * @vctxt: the WXS validation context 23778 * @elemDecl: the element declaration 23779 * 23780 * Check the cvc-idc-keyref constraints. 23781 */ 23782static int 23783xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23784{ 23785 xmlSchemaIDCMatcherPtr matcher; 23786 xmlSchemaPSVIIDCBindingPtr bind; 23787 23788 matcher = vctxt->inode->idcMatchers; 23789 /* 23790 * Find a keyref. 23791 */ 23792 while (matcher != NULL) { 23793 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23794 matcher->targets && 23795 matcher->targets->nbItems) 23796 { 23797 int i, j, k, res, nbFields, hasDupls; 23798 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23799 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23800 23801 nbFields = matcher->aidc->def->nbFields; 23802 23803 /* 23804 * Find the IDC node-table for the referenced IDC key/unique. 23805 */ 23806 bind = vctxt->inode->idcTable; 23807 while (bind != NULL) { 23808 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23809 bind->definition) 23810 break; 23811 bind = bind->next; 23812 } 23813 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23814 /* 23815 * Search for a matching key-sequences. 23816 */ 23817 for (i = 0; i < matcher->targets->nbItems; i++) { 23818 res = 0; 23819 refNode = matcher->targets->items[i]; 23820 if (bind != NULL) { 23821 refKeys = refNode->keys; 23822 for (j = 0; j < bind->nbNodes; j++) { 23823 keys = bind->nodeTable[j]->keys; 23824 for (k = 0; k < nbFields; k++) { 23825 res = xmlSchemaAreValuesEqual(keys[k]->val, 23826 refKeys[k]->val); 23827 if (res == 0) 23828 break; 23829 else if (res == -1) { 23830 return (-1); 23831 } 23832 } 23833 if (res == 1) { 23834 /* 23835 * Match found. 23836 */ 23837 break; 23838 } 23839 } 23840 if ((res == 0) && hasDupls) { 23841 /* 23842 * Search in duplicates 23843 */ 23844 for (j = 0; j < bind->dupls->nbItems; j++) { 23845 keys = ((xmlSchemaPSVIIDCNodePtr) 23846 bind->dupls->items[j])->keys; 23847 for (k = 0; k < nbFields; k++) { 23848 res = xmlSchemaAreValuesEqual(keys[k]->val, 23849 refKeys[k]->val); 23850 if (res == 0) 23851 break; 23852 else if (res == -1) { 23853 return (-1); 23854 } 23855 } 23856 if (res == 1) { 23857 /* 23858 * Match in duplicates found. 23859 */ 23860 xmlChar *str = NULL, *strB = NULL; 23861 xmlSchemaKeyrefErr(vctxt, 23862 XML_SCHEMAV_CVC_IDC, refNode, 23863 (xmlSchemaTypePtr) matcher->aidc->def, 23864 "More than one match found for " 23865 "key-sequence %s of keyref '%s'", 23866 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23867 refNode->keys, nbFields), 23868 xmlSchemaGetComponentQName(&strB, 23869 matcher->aidc->def)); 23870 FREE_AND_NULL(str); 23871 FREE_AND_NULL(strB); 23872 break; 23873 } 23874 } 23875 } 23876 } 23877 23878 if (res == 0) { 23879 xmlChar *str = NULL, *strB = NULL; 23880 xmlSchemaKeyrefErr(vctxt, 23881 XML_SCHEMAV_CVC_IDC, refNode, 23882 (xmlSchemaTypePtr) matcher->aidc->def, 23883 "No match found for key-sequence %s of keyref '%s'", 23884 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23885 refNode->keys, nbFields), 23886 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23887 FREE_AND_NULL(str); 23888 FREE_AND_NULL(strB); 23889 } 23890 } 23891 } 23892 matcher = matcher->next; 23893 } 23894 /* TODO: Return an error if any error encountered. */ 23895 return (0); 23896} 23897 23898/************************************************************************ 23899 * * 23900 * XML Reader validation code * 23901 * * 23902 ************************************************************************/ 23903 23904static xmlSchemaAttrInfoPtr 23905xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23906{ 23907 xmlSchemaAttrInfoPtr iattr; 23908 /* 23909 * Grow/create list of attribute infos. 23910 */ 23911 if (vctxt->attrInfos == NULL) { 23912 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23913 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23914 vctxt->sizeAttrInfos = 1; 23915 if (vctxt->attrInfos == NULL) { 23916 xmlSchemaVErrMemory(vctxt, 23917 "allocating attribute info list", NULL); 23918 return (NULL); 23919 } 23920 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23921 vctxt->sizeAttrInfos++; 23922 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23923 xmlRealloc(vctxt->attrInfos, 23924 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23925 if (vctxt->attrInfos == NULL) { 23926 xmlSchemaVErrMemory(vctxt, 23927 "re-allocating attribute info list", NULL); 23928 return (NULL); 23929 } 23930 } else { 23931 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23932 if (iattr->localName != NULL) { 23933 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23934 "attr info not cleared"); 23935 return (NULL); 23936 } 23937 iattr->nodeType = XML_ATTRIBUTE_NODE; 23938 return (iattr); 23939 } 23940 /* 23941 * Create an attribute info. 23942 */ 23943 iattr = (xmlSchemaAttrInfoPtr) 23944 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23945 if (iattr == NULL) { 23946 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23947 return (NULL); 23948 } 23949 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23950 iattr->nodeType = XML_ATTRIBUTE_NODE; 23951 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23952 23953 return (iattr); 23954} 23955 23956static int 23957xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23958 xmlNodePtr attrNode, 23959 int nodeLine, 23960 const xmlChar *localName, 23961 const xmlChar *nsName, 23962 int ownedNames, 23963 xmlChar *value, 23964 int ownedValue) 23965{ 23966 xmlSchemaAttrInfoPtr attr; 23967 23968 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23969 if (attr == NULL) { 23970 VERROR_INT("xmlSchemaPushAttribute", 23971 "calling xmlSchemaGetFreshAttrInfo()"); 23972 return (-1); 23973 } 23974 attr->node = attrNode; 23975 attr->nodeLine = nodeLine; 23976 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 23977 attr->localName = localName; 23978 attr->nsName = nsName; 23979 if (ownedNames) 23980 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 23981 /* 23982 * Evaluate if it's an XSI attribute. 23983 */ 23984 if (nsName != NULL) { 23985 if (xmlStrEqual(localName, BAD_CAST "nil")) { 23986 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23987 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 23988 } 23989 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 23990 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23991 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 23992 } 23993 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 23994 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23995 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 23996 } 23997 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 23998 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23999 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 24000 } 24001 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 24002 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 24003 } 24004 } 24005 attr->value = value; 24006 if (ownedValue) 24007 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 24008 if (attr->metaType != 0) 24009 attr->state = XML_SCHEMAS_ATTR_META; 24010 return (0); 24011} 24012 24013/** 24014 * xmlSchemaClearElemInfo: 24015 * @vctxt: the WXS validation context 24016 * @ielem: the element information item 24017 */ 24018static void 24019xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 24020 xmlSchemaNodeInfoPtr ielem) 24021{ 24022 ielem->hasKeyrefs = 0; 24023 ielem->appliedXPath = 0; 24024 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 24025 FREE_AND_NULL(ielem->localName); 24026 FREE_AND_NULL(ielem->nsName); 24027 } else { 24028 ielem->localName = NULL; 24029 ielem->nsName = NULL; 24030 } 24031 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24032 FREE_AND_NULL(ielem->value); 24033 } else { 24034 ielem->value = NULL; 24035 } 24036 if (ielem->val != NULL) { 24037 /* 24038 * PSVI TODO: Be careful not to free it when the value is 24039 * exposed via PSVI. 24040 */ 24041 xmlSchemaFreeValue(ielem->val); 24042 ielem->val = NULL; 24043 } 24044 if (ielem->idcMatchers != NULL) { 24045 /* 24046 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24047 * Does it work? 24048 */ 24049 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24050#if 0 24051 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24052#endif 24053 ielem->idcMatchers = NULL; 24054 } 24055 if (ielem->idcTable != NULL) { 24056 /* 24057 * OPTIMIZE TODO: Use a pool of IDC tables??. 24058 */ 24059 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24060 ielem->idcTable = NULL; 24061 } 24062 if (ielem->regexCtxt != NULL) { 24063 xmlRegFreeExecCtxt(ielem->regexCtxt); 24064 ielem->regexCtxt = NULL; 24065 } 24066 if (ielem->nsBindings != NULL) { 24067 xmlFree((xmlChar **)ielem->nsBindings); 24068 ielem->nsBindings = NULL; 24069 ielem->nbNsBindings = 0; 24070 ielem->sizeNsBindings = 0; 24071 } 24072} 24073 24074/** 24075 * xmlSchemaGetFreshElemInfo: 24076 * @vctxt: the schema validation context 24077 * 24078 * Creates/reuses and initializes the element info item for 24079 * the currect tree depth. 24080 * 24081 * Returns the element info item or NULL on API or internal errors. 24082 */ 24083static xmlSchemaNodeInfoPtr 24084xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24085{ 24086 xmlSchemaNodeInfoPtr info = NULL; 24087 24088 if (vctxt->depth > vctxt->sizeElemInfos) { 24089 VERROR_INT("xmlSchemaGetFreshElemInfo", 24090 "inconsistent depth encountered"); 24091 return (NULL); 24092 } 24093 if (vctxt->elemInfos == NULL) { 24094 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24095 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24096 if (vctxt->elemInfos == NULL) { 24097 xmlSchemaVErrMemory(vctxt, 24098 "allocating the element info array", NULL); 24099 return (NULL); 24100 } 24101 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24102 vctxt->sizeElemInfos = 10; 24103 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24104 int i = vctxt->sizeElemInfos; 24105 24106 vctxt->sizeElemInfos *= 2; 24107 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24108 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24109 sizeof(xmlSchemaNodeInfoPtr)); 24110 if (vctxt->elemInfos == NULL) { 24111 xmlSchemaVErrMemory(vctxt, 24112 "re-allocating the element info array", NULL); 24113 return (NULL); 24114 } 24115 /* 24116 * We need the new memory to be NULLed. 24117 * TODO: Use memset instead? 24118 */ 24119 for (; i < vctxt->sizeElemInfos; i++) 24120 vctxt->elemInfos[i] = NULL; 24121 } else 24122 info = vctxt->elemInfos[vctxt->depth]; 24123 24124 if (info == NULL) { 24125 info = (xmlSchemaNodeInfoPtr) 24126 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24127 if (info == NULL) { 24128 xmlSchemaVErrMemory(vctxt, 24129 "allocating an element info", NULL); 24130 return (NULL); 24131 } 24132 vctxt->elemInfos[vctxt->depth] = info; 24133 } else { 24134 if (info->localName != NULL) { 24135 VERROR_INT("xmlSchemaGetFreshElemInfo", 24136 "elem info has not been cleared"); 24137 return (NULL); 24138 } 24139 } 24140 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24141 info->nodeType = XML_ELEMENT_NODE; 24142 info->depth = vctxt->depth; 24143 24144 return (info); 24145} 24146 24147#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24148#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24149#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24150 24151static int 24152xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24153 xmlNodePtr node, 24154 xmlSchemaTypePtr type, 24155 xmlSchemaValType valType, 24156 const xmlChar * value, 24157 xmlSchemaValPtr val, 24158 unsigned long length, 24159 int fireErrors) 24160{ 24161 int ret, error = 0; 24162 24163 xmlSchemaTypePtr tmpType; 24164 xmlSchemaFacetLinkPtr facetLink; 24165 xmlSchemaFacetPtr facet; 24166 unsigned long len = 0; 24167 xmlSchemaWhitespaceValueType ws; 24168 24169 /* 24170 * In Libxml2, derived built-in types have currently no explicit facets. 24171 */ 24172 if (type->type == XML_SCHEMA_TYPE_BASIC) 24173 return (0); 24174 24175 /* 24176 * NOTE: Do not jump away, if the facetSet of the given type is 24177 * empty: until now, "pattern" and "enumeration" facets of the 24178 * *base types* need to be checked as well. 24179 */ 24180 if (type->facetSet == NULL) 24181 goto pattern_and_enum; 24182 24183 if (! WXS_IS_ATOMIC(type)) { 24184 if (WXS_IS_LIST(type)) 24185 goto WXS_IS_LIST; 24186 else 24187 goto pattern_and_enum; 24188 } 24189 /* 24190 * Whitespace handling is only of importance for string-based 24191 * types. 24192 */ 24193 tmpType = xmlSchemaGetPrimitiveType(type); 24194 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24195 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24196 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24197 } else 24198 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24199 /* 24200 * If the value was not computed (for string or 24201 * anySimpleType based types), then use the provided 24202 * type. 24203 */ 24204 if (val == NULL) 24205 valType = valType; 24206 else 24207 valType = xmlSchemaGetValType(val); 24208 24209 ret = 0; 24210 for (facetLink = type->facetSet; facetLink != NULL; 24211 facetLink = facetLink->next) { 24212 /* 24213 * Skip the pattern "whiteSpace": it is used to 24214 * format the character content beforehand. 24215 */ 24216 switch (facetLink->facet->type) { 24217 case XML_SCHEMA_FACET_WHITESPACE: 24218 case XML_SCHEMA_FACET_PATTERN: 24219 case XML_SCHEMA_FACET_ENUMERATION: 24220 continue; 24221 case XML_SCHEMA_FACET_LENGTH: 24222 case XML_SCHEMA_FACET_MINLENGTH: 24223 case XML_SCHEMA_FACET_MAXLENGTH: 24224 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24225 valType, value, val, &len, ws); 24226 break; 24227 default: 24228 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24229 valType, value, val, ws); 24230 break; 24231 } 24232 if (ret < 0) { 24233 AERROR_INT("xmlSchemaValidateFacets", 24234 "validating against a atomic type facet"); 24235 return (-1); 24236 } else if (ret > 0) { 24237 if (fireErrors) 24238 xmlSchemaFacetErr(actxt, ret, node, 24239 value, len, type, facetLink->facet, NULL, NULL, NULL); 24240 else 24241 return (ret); 24242 if (error == 0) 24243 error = ret; 24244 } 24245 ret = 0; 24246 } 24247 24248WXS_IS_LIST: 24249 if (! WXS_IS_LIST(type)) 24250 goto pattern_and_enum; 24251 /* 24252 * "length", "minLength" and "maxLength" of list types. 24253 */ 24254 ret = 0; 24255 for (facetLink = type->facetSet; facetLink != NULL; 24256 facetLink = facetLink->next) { 24257 24258 switch (facetLink->facet->type) { 24259 case XML_SCHEMA_FACET_LENGTH: 24260 case XML_SCHEMA_FACET_MINLENGTH: 24261 case XML_SCHEMA_FACET_MAXLENGTH: 24262 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24263 value, length, NULL); 24264 break; 24265 default: 24266 continue; 24267 } 24268 if (ret < 0) { 24269 AERROR_INT("xmlSchemaValidateFacets", 24270 "validating against a list type facet"); 24271 return (-1); 24272 } else if (ret > 0) { 24273 if (fireErrors) 24274 xmlSchemaFacetErr(actxt, ret, node, 24275 value, length, type, facetLink->facet, NULL, NULL, NULL); 24276 else 24277 return (ret); 24278 if (error == 0) 24279 error = ret; 24280 } 24281 ret = 0; 24282 } 24283 24284pattern_and_enum: 24285 if (error >= 0) { 24286 int found = 0; 24287 /* 24288 * Process enumerations. Facet values are in the value space 24289 * of the defining type's base type. This seems to be a bug in the 24290 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24291 * Only the first set of enumerations in the ancestor-or-self axis 24292 * is used for validation. 24293 */ 24294 ret = 0; 24295 tmpType = type; 24296 do { 24297 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24298 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24299 continue; 24300 found = 1; 24301 ret = xmlSchemaAreValuesEqual(facet->val, val); 24302 if (ret == 1) 24303 break; 24304 else if (ret < 0) { 24305 AERROR_INT("xmlSchemaValidateFacets", 24306 "validating against an enumeration facet"); 24307 return (-1); 24308 } 24309 } 24310 if (ret != 0) 24311 break; 24312 /* 24313 * Break on the first set of enumerations. Any additional 24314 * enumerations which might be existent on the ancestors 24315 * of the current type are restricted by this set; thus 24316 * *must* *not* be taken into account. 24317 */ 24318 if (found) 24319 break; 24320 tmpType = tmpType->baseType; 24321 } while ((tmpType != NULL) && 24322 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24323 if (found && (ret == 0)) { 24324 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24325 if (fireErrors) { 24326 xmlSchemaFacetErr(actxt, ret, node, 24327 value, 0, type, NULL, NULL, NULL, NULL); 24328 } else 24329 return (ret); 24330 if (error == 0) 24331 error = ret; 24332 } 24333 } 24334 24335 if (error >= 0) { 24336 int found; 24337 /* 24338 * Process patters. Pattern facets are ORed at type level 24339 * and ANDed if derived. Walk the base type axis. 24340 */ 24341 tmpType = type; 24342 facet = NULL; 24343 do { 24344 found = 0; 24345 for (facetLink = tmpType->facetSet; facetLink != NULL; 24346 facetLink = facetLink->next) { 24347 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24348 continue; 24349 found = 1; 24350 /* 24351 * NOTE that for patterns, @value needs to be the 24352 * normalized vaule. 24353 */ 24354 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24355 if (ret == 1) 24356 break; 24357 else if (ret < 0) { 24358 AERROR_INT("xmlSchemaValidateFacets", 24359 "validating against a pattern facet"); 24360 return (-1); 24361 } else { 24362 /* 24363 * Save the last non-validating facet. 24364 */ 24365 facet = facetLink->facet; 24366 } 24367 } 24368 if (found && (ret != 1)) { 24369 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24370 if (fireErrors) { 24371 xmlSchemaFacetErr(actxt, ret, node, 24372 value, 0, type, facet, NULL, NULL, NULL); 24373 } else 24374 return (ret); 24375 if (error == 0) 24376 error = ret; 24377 break; 24378 } 24379 tmpType = tmpType->baseType; 24380 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24381 } 24382 24383 return (error); 24384} 24385 24386static xmlChar * 24387xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24388 const xmlChar *value) 24389{ 24390 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24391 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24392 return (xmlSchemaCollapseString(value)); 24393 case XML_SCHEMA_WHITESPACE_REPLACE: 24394 return (xmlSchemaWhiteSpaceReplace(value)); 24395 default: 24396 return (NULL); 24397 } 24398} 24399 24400static int 24401xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24402 const xmlChar *value, 24403 xmlSchemaValPtr *val, 24404 int valNeeded) 24405{ 24406 int ret; 24407 const xmlChar *nsName; 24408 xmlChar *local, *prefix = NULL; 24409 24410 ret = xmlValidateQName(value, 1); 24411 if (ret != 0) { 24412 if (ret == -1) { 24413 VERROR_INT("xmlSchemaValidateQName", 24414 "calling xmlValidateQName()"); 24415 return (-1); 24416 } 24417 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24418 } 24419 /* 24420 * NOTE: xmlSplitQName2 will always return a duplicated 24421 * strings. 24422 */ 24423 local = xmlSplitQName2(value, &prefix); 24424 if (local == NULL) 24425 local = xmlStrdup(value); 24426 /* 24427 * OPTIMIZE TODO: Use flags for: 24428 * - is there any namespace binding? 24429 * - is there a default namespace? 24430 */ 24431 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24432 24433 if (prefix != NULL) { 24434 xmlFree(prefix); 24435 /* 24436 * A namespace must be found if the prefix is 24437 * NOT NULL. 24438 */ 24439 if (nsName == NULL) { 24440 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24441 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24442 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24443 "The QName value '%s' has no " 24444 "corresponding namespace declaration in " 24445 "scope", value, NULL); 24446 if (local != NULL) 24447 xmlFree(local); 24448 return (ret); 24449 } 24450 } 24451 if (valNeeded && val) { 24452 if (nsName != NULL) 24453 *val = xmlSchemaNewQNameValue( 24454 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24455 else 24456 *val = xmlSchemaNewQNameValue(NULL, 24457 BAD_CAST local); 24458 } else 24459 xmlFree(local); 24460 return (0); 24461} 24462 24463/* 24464* cvc-simple-type 24465*/ 24466static int 24467xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24468 xmlNodePtr node, 24469 xmlSchemaTypePtr type, 24470 const xmlChar *value, 24471 xmlSchemaValPtr *retVal, 24472 int fireErrors, 24473 int normalize, 24474 int isNormalized) 24475{ 24476 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24477 xmlSchemaValPtr val = NULL; 24478 /* xmlSchemaWhitespaceValueType ws; */ 24479 xmlChar *normValue = NULL; 24480 24481#define NORMALIZE(atype) \ 24482 if ((! isNormalized) && \ 24483 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24484 normValue = xmlSchemaNormalizeValue(atype, value); \ 24485 if (normValue != NULL) \ 24486 value = normValue; \ 24487 isNormalized = 1; \ 24488 } 24489 24490 if ((retVal != NULL) && (*retVal != NULL)) { 24491 xmlSchemaFreeValue(*retVal); 24492 *retVal = NULL; 24493 } 24494 /* 24495 * 3.14.4 Simple Type Definition Validation Rules 24496 * Validation Rule: String Valid 24497 */ 24498 /* 24499 * 1 It is schema-valid with respect to that definition as defined 24500 * by Datatype Valid in [XML Schemas: Datatypes]. 24501 */ 24502 /* 24503 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24504 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then 24505 * the string must be a `declared entity name`. 24506 */ 24507 /* 24508 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24509 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), 24510 * then every whitespace-delimited substring of the string must be a `declared 24511 * entity name`. 24512 */ 24513 /* 24514 * 2.3 otherwise no further condition applies. 24515 */ 24516 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24517 valNeeded = 1; 24518 if (value == NULL) 24519 value = BAD_CAST ""; 24520 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24521 xmlSchemaTypePtr biType; /* The built-in type. */ 24522 /* 24523 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match` 24524 * a literal in the `lexical space` of {base type definition}" 24525 */ 24526 /* 24527 * Whitespace-normalize. 24528 */ 24529 NORMALIZE(type); 24530 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24531 /* 24532 * Get the built-in type. 24533 */ 24534 biType = type->baseType; 24535 while ((biType != NULL) && 24536 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24537 biType = biType->baseType; 24538 24539 if (biType == NULL) { 24540 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24541 "could not get the built-in type"); 24542 goto internal_error; 24543 } 24544 } else 24545 biType = type; 24546 /* 24547 * NOTATIONs need to be processed here, since they need 24548 * to lookup in the hashtable of NOTATION declarations of the schema. 24549 */ 24550 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24551 switch (biType->builtInType) { 24552 case XML_SCHEMAS_NOTATION: 24553 ret = xmlSchemaValidateNotation( 24554 (xmlSchemaValidCtxtPtr) actxt, 24555 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24556 NULL, value, &val, valNeeded); 24557 break; 24558 case XML_SCHEMAS_QNAME: 24559 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24560 value, &val, valNeeded); 24561 break; 24562 default: 24563 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24564 if (valNeeded) 24565 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24566 value, &val, node); 24567 else 24568 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24569 value, NULL, node); 24570 break; 24571 } 24572 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24573 switch (biType->builtInType) { 24574 case XML_SCHEMAS_NOTATION: 24575 ret = xmlSchemaValidateNotation(NULL, 24576 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24577 value, &val, valNeeded); 24578 break; 24579 default: 24580 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24581 if (valNeeded) 24582 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24583 value, &val, node); 24584 else 24585 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24586 value, NULL, node); 24587 break; 24588 } 24589 } else { 24590 /* 24591 * Validation via a public API is not implemented yet. 24592 */ 24593 TODO 24594 goto internal_error; 24595 } 24596 if (ret != 0) { 24597 if (ret < 0) { 24598 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24599 "validating against a built-in type"); 24600 goto internal_error; 24601 } 24602 if (WXS_IS_LIST(type)) 24603 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24604 else 24605 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24606 } 24607 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24608 /* 24609 * Check facets. 24610 */ 24611 ret = xmlSchemaValidateFacets(actxt, node, type, 24612 (xmlSchemaValType) biType->builtInType, value, val, 24613 0, fireErrors); 24614 if (ret != 0) { 24615 if (ret < 0) { 24616 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24617 "validating facets of atomic simple type"); 24618 goto internal_error; 24619 } 24620 if (WXS_IS_LIST(type)) 24621 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24622 else 24623 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24624 } 24625 } 24626 if (fireErrors && (ret > 0)) 24627 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24628 } else if (WXS_IS_LIST(type)) { 24629 24630 xmlSchemaTypePtr itemType; 24631 const xmlChar *cur, *end; 24632 xmlChar *tmpValue = NULL; 24633 unsigned long len = 0; 24634 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24635 /* 1.2.2 if {variety} is `list` then the string must be a sequence 24636 * of white space separated tokens, each of which `match`es a literal 24637 * in the `lexical space` of {item type definition} 24638 */ 24639 /* 24640 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24641 * the list type has an enum or pattern facet. 24642 */ 24643 NORMALIZE(type); 24644 /* 24645 * VAL TODO: Optimize validation of empty values. 24646 * VAL TODO: We do not have computed values for lists. 24647 */ 24648 itemType = WXS_LIST_ITEMTYPE(type); 24649 cur = value; 24650 do { 24651 while (IS_BLANK_CH(*cur)) 24652 cur++; 24653 end = cur; 24654 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24655 end++; 24656 if (end == cur) 24657 break; 24658 tmpValue = xmlStrndup(cur, end - cur); 24659 len++; 24660 24661 if (valNeeded) 24662 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24663 tmpValue, &curVal, fireErrors, 0, 1); 24664 else 24665 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24666 tmpValue, NULL, fireErrors, 0, 1); 24667 FREE_AND_NULL(tmpValue); 24668 if (curVal != NULL) { 24669 /* 24670 * Add to list of computed values. 24671 */ 24672 if (val == NULL) 24673 val = curVal; 24674 else 24675 xmlSchemaValueAppend(prevVal, curVal); 24676 prevVal = curVal; 24677 curVal = NULL; 24678 } 24679 if (ret != 0) { 24680 if (ret < 0) { 24681 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24682 "validating an item of list simple type"); 24683 goto internal_error; 24684 } 24685 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24686 break; 24687 } 24688 cur = end; 24689 } while (*cur != 0); 24690 FREE_AND_NULL(tmpValue); 24691 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24692 /* 24693 * Apply facets (pattern, enumeration). 24694 */ 24695 ret = xmlSchemaValidateFacets(actxt, node, type, 24696 XML_SCHEMAS_UNKNOWN, value, val, 24697 len, fireErrors); 24698 if (ret != 0) { 24699 if (ret < 0) { 24700 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24701 "validating facets of list simple type"); 24702 goto internal_error; 24703 } 24704 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24705 } 24706 } 24707 if (fireErrors && (ret > 0)) { 24708 /* 24709 * Report the normalized value. 24710 */ 24711 normalize = 1; 24712 NORMALIZE(type); 24713 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24714 } 24715 } else if (WXS_IS_UNION(type)) { 24716 xmlSchemaTypeLinkPtr memberLink; 24717 /* 24718 * TODO: For all datatypes `derived` by `union` whiteSpace does 24719 * not apply directly; however, the normalization behavior of `union` 24720 * types is controlled by the value of whiteSpace on that one of the 24721 * `memberTypes` against which the `union` is successfully validated. 24722 * 24723 * This means that the value is normalized by the first validating 24724 * member type, then the facets of the union type are applied. This 24725 * needs changing of the value! 24726 */ 24727 24728 /* 24729 * 1.2.3 if {variety} is `union` then the string must `match` a 24730 * literal in the `lexical space` of at least one member of 24731 * {member type definitions} 24732 */ 24733 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24734 if (memberLink == NULL) { 24735 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24736 "union simple type has no member types"); 24737 goto internal_error; 24738 } 24739 /* 24740 * Always normalize union type values, since we currently 24741 * cannot store the whitespace information with the value 24742 * itself; otherwise a later value-comparison would be 24743 * not possible. 24744 */ 24745 while (memberLink != NULL) { 24746 if (valNeeded) 24747 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24748 memberLink->type, value, &val, 0, 1, 0); 24749 else 24750 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24751 memberLink->type, value, NULL, 0, 1, 0); 24752 if (ret <= 0) 24753 break; 24754 memberLink = memberLink->next; 24755 } 24756 if (ret != 0) { 24757 if (ret < 0) { 24758 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24759 "validating members of union simple type"); 24760 goto internal_error; 24761 } 24762 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24763 } 24764 /* 24765 * Apply facets (pattern, enumeration). 24766 */ 24767 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24768 /* 24769 * The normalization behavior of `union` types is controlled by 24770 * the value of whiteSpace on that one of the `memberTypes` 24771 * against which the `union` is successfully validated. 24772 */ 24773 NORMALIZE(memberLink->type); 24774 ret = xmlSchemaValidateFacets(actxt, node, type, 24775 XML_SCHEMAS_UNKNOWN, value, val, 24776 0, fireErrors); 24777 if (ret != 0) { 24778 if (ret < 0) { 24779 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24780 "validating facets of union simple type"); 24781 goto internal_error; 24782 } 24783 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24784 } 24785 } 24786 if (fireErrors && (ret > 0)) 24787 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24788 } 24789 24790 if (normValue != NULL) 24791 xmlFree(normValue); 24792 if (ret == 0) { 24793 if (retVal != NULL) 24794 *retVal = val; 24795 else if (val != NULL) 24796 xmlSchemaFreeValue(val); 24797 } else if (val != NULL) 24798 xmlSchemaFreeValue(val); 24799 return (ret); 24800internal_error: 24801 if (normValue != NULL) 24802 xmlFree(normValue); 24803 if (val != NULL) 24804 xmlSchemaFreeValue(val); 24805 return (-1); 24806} 24807 24808static int 24809xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24810 const xmlChar *value, 24811 const xmlChar **nsName, 24812 const xmlChar **localName) 24813{ 24814 int ret = 0; 24815 24816 if ((nsName == NULL) || (localName == NULL)) 24817 return (-1); 24818 *nsName = NULL; 24819 *localName = NULL; 24820 24821 ret = xmlValidateQName(value, 1); 24822 if (ret == -1) 24823 return (-1); 24824 if (ret > 0) { 24825 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24826 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24827 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24828 return (1); 24829 } 24830 { 24831 xmlChar *local = NULL; 24832 xmlChar *prefix; 24833 24834 /* 24835 * NOTE: xmlSplitQName2 will return a duplicated 24836 * string. 24837 */ 24838 local = xmlSplitQName2(value, &prefix); 24839 if (local == NULL) 24840 *localName = xmlDictLookup(vctxt->dict, value, -1); 24841 else { 24842 *localName = xmlDictLookup(vctxt->dict, local, -1); 24843 xmlFree(local); 24844 } 24845 24846 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24847 24848 if (prefix != NULL) { 24849 xmlFree(prefix); 24850 /* 24851 * A namespace must be found if the prefix is NOT NULL. 24852 */ 24853 if (*nsName == NULL) { 24854 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24855 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24856 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24857 "The QName value '%s' has no " 24858 "corresponding namespace declaration in scope", 24859 value, NULL); 24860 return (2); 24861 } 24862 } 24863 } 24864 return (0); 24865} 24866 24867static int 24868xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24869 xmlSchemaAttrInfoPtr iattr, 24870 xmlSchemaTypePtr *localType, 24871 xmlSchemaElementPtr elemDecl) 24872{ 24873 int ret = 0; 24874 /* 24875 * cvc-elt (3.3.4) : (4) 24876 * AND 24877 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24878 * (1.2.1.2.1) - (1.2.1.2.4) 24879 * Handle 'xsi:type'. 24880 */ 24881 if (localType == NULL) 24882 return (-1); 24883 *localType = NULL; 24884 if (iattr == NULL) 24885 return (0); 24886 else { 24887 const xmlChar *nsName = NULL, *local = NULL; 24888 /* 24889 * TODO: We should report a *warning* that the type was overriden 24890 * by the instance. 24891 */ 24892 ACTIVATE_ATTRIBUTE(iattr); 24893 /* 24894 * (cvc-elt) (3.3.4) : (4.1) 24895 * (cvc-assess-elt) (1.2.1.2.2) 24896 */ 24897 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24898 &nsName, &local); 24899 if (ret != 0) { 24900 if (ret < 0) { 24901 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24902 "calling xmlSchemaQNameExpand() to validate the " 24903 "attribute 'xsi:type'"); 24904 goto internal_error; 24905 } 24906 goto exit; 24907 } 24908 /* 24909 * (cvc-elt) (3.3.4) : (4.2) 24910 * (cvc-assess-elt) (1.2.1.2.3) 24911 */ 24912 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24913 if (*localType == NULL) { 24914 xmlChar *str = NULL; 24915 24916 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24917 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24918 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24919 "The QName value '%s' of the xsi:type attribute does not " 24920 "resolve to a type definition", 24921 xmlSchemaFormatQName(&str, nsName, local), NULL); 24922 FREE_AND_NULL(str); 24923 ret = vctxt->err; 24924 goto exit; 24925 } 24926 if (elemDecl != NULL) { 24927 int set = 0; 24928 24929 /* 24930 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24931 * "The `local type definition` must be validly 24932 * derived from the {type definition} given the union of 24933 * the {disallowed substitutions} and the {type definition}'s 24934 * {prohibited substitutions}, as defined in 24935 * Type Derivation OK (Complex) ($3.4.6) 24936 * (if it is a complex type definition), 24937 * or given {disallowed substitutions} as defined in Type 24938 * Derivation OK (Simple) ($3.14.6) (if it is a simple type 24939 * definition)." 24940 * 24941 * {disallowed substitutions}: the "block" on the element decl. 24942 * {prohibited substitutions}: the "block" on the type def. 24943 */ 24944 /* 24945 * OPTIMIZE TODO: We could map types already evaluated 24946 * to be validly derived from other types to avoid checking 24947 * this over and over for the same types. 24948 */ 24949 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24950 (elemDecl->subtypes->flags & 24951 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24952 set |= SUBSET_EXTENSION; 24953 24954 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24955 (elemDecl->subtypes->flags & 24956 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24957 set |= SUBSET_RESTRICTION; 24958 24959 /* 24960 * REMOVED and CHANGED since this produced a parser context 24961 * which adds to the string dict of the schema. So this would 24962 * change the schema and we don't want this. We don't need 24963 * the parser context anymore. 24964 * 24965 * if ((vctxt->pctxt == NULL) && 24966 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24967 * return (-1); 24968 */ 24969 24970 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24971 elemDecl->subtypes, set) != 0) { 24972 xmlChar *str = NULL; 24973 24974 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24975 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 24976 "The type definition '%s', specified by xsi:type, is " 24977 "blocked or not validly derived from the type definition " 24978 "of the element declaration", 24979 xmlSchemaFormatQName(&str, 24980 (*localType)->targetNamespace, 24981 (*localType)->name), 24982 NULL); 24983 FREE_AND_NULL(str); 24984 ret = vctxt->err; 24985 *localType = NULL; 24986 } 24987 } 24988 } 24989exit: 24990 ACTIVATE_ELEM; 24991 return (ret); 24992internal_error: 24993 ACTIVATE_ELEM; 24994 return (-1); 24995} 24996 24997static int 24998xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 24999{ 25000 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 25001 xmlSchemaTypePtr actualType; 25002 25003 /* 25004 * cvc-elt (3.3.4) : 1 25005 */ 25006 if (elemDecl == NULL) { 25007 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 25008 "No matching declaration available"); 25009 return (vctxt->err); 25010 } 25011 actualType = WXS_ELEM_TYPEDEF(elemDecl); 25012 /* 25013 * cvc-elt (3.3.4) : 2 25014 */ 25015 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 25016 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 25017 "The element declaration is abstract"); 25018 return (vctxt->err); 25019 } 25020 if (actualType == NULL) { 25021 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25022 "The type definition is absent"); 25023 return (XML_SCHEMAV_CVC_TYPE_1); 25024 } 25025 if (vctxt->nbAttrInfos != 0) { 25026 int ret; 25027 xmlSchemaAttrInfoPtr iattr; 25028 /* 25029 * cvc-elt (3.3.4) : 3 25030 * Handle 'xsi:nil'. 25031 */ 25032 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25033 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25034 if (iattr) { 25035 ACTIVATE_ATTRIBUTE(iattr); 25036 /* 25037 * Validate the value. 25038 */ 25039 ret = xmlSchemaVCheckCVCSimpleType( 25040 ACTXT_CAST vctxt, NULL, 25041 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25042 iattr->value, &(iattr->val), 1, 0, 0); 25043 ACTIVATE_ELEM; 25044 if (ret < 0) { 25045 VERROR_INT("xmlSchemaValidateElemDecl", 25046 "calling xmlSchemaVCheckCVCSimpleType() to " 25047 "validate the attribute 'xsi:nil'"); 25048 return (-1); 25049 } 25050 if (ret == 0) { 25051 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25052 /* 25053 * cvc-elt (3.3.4) : 3.1 25054 */ 25055 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25056 "The element is not 'nillable'"); 25057 /* Does not return an error on purpose. */ 25058 } else { 25059 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25060 /* 25061 * cvc-elt (3.3.4) : 3.2.2 25062 */ 25063 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25064 (elemDecl->value != NULL)) { 25065 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25066 "The element cannot be 'nilled' because " 25067 "there is a fixed value constraint defined " 25068 "for it"); 25069 /* Does not return an error on purpose. */ 25070 } else 25071 vctxt->inode->flags |= 25072 XML_SCHEMA_ELEM_INFO_NILLED; 25073 } 25074 } 25075 } 25076 } 25077 /* 25078 * cvc-elt (3.3.4) : 4 25079 * Handle 'xsi:type'. 25080 */ 25081 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25082 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25083 if (iattr) { 25084 xmlSchemaTypePtr localType = NULL; 25085 25086 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25087 elemDecl); 25088 if (ret != 0) { 25089 if (ret == -1) { 25090 VERROR_INT("xmlSchemaValidateElemDecl", 25091 "calling xmlSchemaProcessXSIType() to " 25092 "process the attribute 'xsi:type'"); 25093 return (-1); 25094 } 25095 /* Does not return an error on purpose. */ 25096 } 25097 if (localType != NULL) { 25098 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25099 actualType = localType; 25100 } 25101 } 25102 } 25103 /* 25104 * IDC: Register identity-constraint XPath matchers. 25105 */ 25106 if ((elemDecl->idcs != NULL) && 25107 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25108 return (-1); 25109 /* 25110 * No actual type definition. 25111 */ 25112 if (actualType == NULL) { 25113 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25114 "The type definition is absent"); 25115 return (XML_SCHEMAV_CVC_TYPE_1); 25116 } 25117 /* 25118 * Remember the actual type definition. 25119 */ 25120 vctxt->inode->typeDef = actualType; 25121 25122 return (0); 25123} 25124 25125static int 25126xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25127{ 25128 xmlSchemaAttrInfoPtr iattr; 25129 int ret = 0, i; 25130 25131 /* 25132 * SPEC cvc-type (3.1.1) 25133 * "The attributes of must be empty, excepting those whose namespace 25134 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25135 * whose local name is one of type, nil, schemaLocation or 25136 * noNamespaceSchemaLocation." 25137 */ 25138 if (vctxt->nbAttrInfos == 0) 25139 return (0); 25140 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25141 iattr = vctxt->attrInfos[i]; 25142 if (! iattr->metaType) { 25143 ACTIVATE_ATTRIBUTE(iattr) 25144 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25145 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25146 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25147 } 25148 } 25149 ACTIVATE_ELEM 25150 return (ret); 25151} 25152 25153/* 25154* Cleanup currently used attribute infos. 25155*/ 25156static void 25157xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25158{ 25159 int i; 25160 xmlSchemaAttrInfoPtr attr; 25161 25162 if (vctxt->nbAttrInfos == 0) 25163 return; 25164 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25165 attr = vctxt->attrInfos[i]; 25166 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25167 if (attr->localName != NULL) 25168 xmlFree((xmlChar *) attr->localName); 25169 if (attr->nsName != NULL) 25170 xmlFree((xmlChar *) attr->nsName); 25171 } 25172 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25173 if (attr->value != NULL) 25174 xmlFree((xmlChar *) attr->value); 25175 } 25176 if (attr->val != NULL) { 25177 xmlSchemaFreeValue(attr->val); 25178 attr->val = NULL; 25179 } 25180 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25181 } 25182 vctxt->nbAttrInfos = 0; 25183} 25184 25185/* 25186* 3.4.4 Complex Type Definition Validation Rules 25187* Element Locally Valid (Complex Type) (cvc-complex-type) 25188* 3.2.4 Attribute Declaration Validation Rules 25189* Validation Rule: Attribute Locally Valid (cvc-attribute) 25190* Attribute Locally Valid (Use) (cvc-au) 25191* 25192* Only "assessed" attribute information items will be visible to 25193* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25194*/ 25195static int 25196xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25197{ 25198 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25199 xmlSchemaItemListPtr attrUseList; 25200 xmlSchemaAttributeUsePtr attrUse = NULL; 25201 xmlSchemaAttributePtr attrDecl = NULL; 25202 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25203 int i, j, found, nbAttrs, nbUses; 25204 int xpathRes = 0, res, wildIDs = 0, fixed; 25205 xmlNodePtr defAttrOwnerElem = NULL; 25206 25207 /* 25208 * SPEC (cvc-attribute) 25209 * (1) "The declaration must not be `absent` (see Missing 25210 * Sub-components ($5.3) for how this can fail to be 25211 * the case)." 25212 * (2) "Its {type definition} must not be absent." 25213 * 25214 * NOTE (1) + (2): This is not handled here, since we currently do not 25215 * allow validation against schemas which have missing sub-components. 25216 * 25217 * SPEC (cvc-complex-type) 25218 * (3) "For each attribute information item in the element information 25219 * item's [attributes] excepting those whose [namespace name] is 25220 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25221 * [local name] is one of type, nil, schemaLocation or 25222 * noNamespaceSchemaLocation, the appropriate case among the following 25223 * must be true: 25224 * 25225 */ 25226 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25227 /* 25228 * @nbAttrs is the number of attributes present in the instance. 25229 */ 25230 nbAttrs = vctxt->nbAttrInfos; 25231 if (attrUseList != NULL) 25232 nbUses = attrUseList->nbItems; 25233 else 25234 nbUses = 0; 25235 for (i = 0; i < nbUses; i++) { 25236 found = 0; 25237 attrUse = attrUseList->items[i]; 25238 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25239 for (j = 0; j < nbAttrs; j++) { 25240 iattr = vctxt->attrInfos[j]; 25241 /* 25242 * SPEC (cvc-complex-type) (3) 25243 * Skip meta attributes. 25244 */ 25245 if (iattr->metaType) 25246 continue; 25247 if (iattr->localName[0] != attrDecl->name[0]) 25248 continue; 25249 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25250 continue; 25251 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25252 continue; 25253 found = 1; 25254 /* 25255 * SPEC (cvc-complex-type) 25256 * (3.1) "If there is among the {attribute uses} an attribute 25257 * use with an {attribute declaration} whose {name} matches 25258 * the attribute information item's [local name] and whose 25259 * {target namespace} is identical to the attribute information 25260 * item's [namespace name] (where an `absent` {target namespace} 25261 * is taken to be identical to a [namespace name] with no value), 25262 * then the attribute information must be `valid` with respect 25263 * to that attribute use as per Attribute Locally Valid (Use) 25264 * ($3.5.4). In this case the {attribute declaration} of that 25265 * attribute use is the `context-determined declaration` for the 25266 * attribute information item with respect to Schema-Validity 25267 * Assessment (Attribute) ($3.2.4) and 25268 * Assessment Outcome (Attribute) ($3.2.5). 25269 */ 25270 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25271 iattr->use = attrUse; 25272 /* 25273 * Context-determined declaration. 25274 */ 25275 iattr->decl = attrDecl; 25276 iattr->typeDef = attrDecl->subtypes; 25277 break; 25278 } 25279 25280 if (found) 25281 continue; 25282 25283 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25284 /* 25285 * Handle non-existent, required attributes. 25286 * 25287 * SPEC (cvc-complex-type) 25288 * (4) "The {attribute declaration} of each attribute use in 25289 * the {attribute uses} whose {required} is true matches one 25290 * of the attribute information items in the element information 25291 * item's [attributes] as per clause 3.1 above." 25292 */ 25293 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25294 if (tmpiattr == NULL) { 25295 VERROR_INT( 25296 "xmlSchemaVAttributesComplex", 25297 "calling xmlSchemaGetFreshAttrInfo()"); 25298 return (-1); 25299 } 25300 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25301 tmpiattr->use = attrUse; 25302 tmpiattr->decl = attrDecl; 25303 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25304 ((attrUse->defValue != NULL) || 25305 (attrDecl->defValue != NULL))) { 25306 /* 25307 * Handle non-existent, optional, default/fixed attributes. 25308 */ 25309 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25310 if (tmpiattr == NULL) { 25311 VERROR_INT( 25312 "xmlSchemaVAttributesComplex", 25313 "calling xmlSchemaGetFreshAttrInfo()"); 25314 return (-1); 25315 } 25316 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25317 tmpiattr->use = attrUse; 25318 tmpiattr->decl = attrDecl; 25319 tmpiattr->typeDef = attrDecl->subtypes; 25320 tmpiattr->localName = attrDecl->name; 25321 tmpiattr->nsName = attrDecl->targetNamespace; 25322 } 25323 } 25324 25325 if (vctxt->nbAttrInfos == 0) 25326 return (0); 25327 /* 25328 * Validate against the wildcard. 25329 */ 25330 if (type->attributeWildcard != NULL) { 25331 /* 25332 * SPEC (cvc-complex-type) 25333 * (3.2.1) "There must be an {attribute wildcard}." 25334 */ 25335 for (i = 0; i < nbAttrs; i++) { 25336 iattr = vctxt->attrInfos[i]; 25337 /* 25338 * SPEC (cvc-complex-type) (3) 25339 * Skip meta attributes. 25340 */ 25341 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25342 continue; 25343 /* 25344 * SPEC (cvc-complex-type) 25345 * (3.2.2) "The attribute information item must be `valid` with 25346 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)." 25347 * 25348 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25349 * "... its [namespace name] must be `valid` with respect to 25350 * the wildcard constraint, as defined in Wildcard allows 25351 * Namespace Name ($3.10.4)." 25352 */ 25353 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25354 iattr->nsName) == 0) { 25355 /* 25356 * Handle processContents. 25357 * 25358 * SPEC (cvc-wildcard): 25359 * processContents | context-determined declaration: 25360 * "strict" "mustFind" 25361 * "lax" "none" 25362 * "skip" "skip" 25363 */ 25364 if (type->attributeWildcard->processContents == 25365 XML_SCHEMAS_ANY_SKIP) { 25366 /* 25367 * context-determined declaration = "skip" 25368 * 25369 * SPEC PSVI Assessment Outcome (Attribute) 25370 * [validity] = "notKnown" 25371 * [validation attempted] = "none" 25372 */ 25373 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25374 continue; 25375 } 25376 /* 25377 * Find an attribute declaration. 25378 */ 25379 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25380 iattr->localName, iattr->nsName); 25381 if (iattr->decl != NULL) { 25382 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25383 /* 25384 * SPEC (cvc-complex-type) 25385 * (5) "Let [Definition:] the wild IDs be the set of 25386 * all attribute information item to which clause 3.2 25387 * applied and whose `validation` resulted in a 25388 * `context-determined declaration` of mustFind or no 25389 * `context-determined declaration` at all, and whose 25390 * [local name] and [namespace name] resolve (as 25391 * defined by QName resolution (Instance) ($3.15.4)) to 25392 * an attribute declaration whose {type definition} is 25393 * or is derived from ID. Then all of the following 25394 * must be true:" 25395 */ 25396 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25397 if (xmlSchemaIsDerivedFromBuiltInType( 25398 iattr->typeDef, XML_SCHEMAS_ID)) { 25399 /* 25400 * SPEC (5.1) "There must be no more than one 25401 * item in `wild IDs`." 25402 */ 25403 if (wildIDs != 0) { 25404 /* VAL TODO */ 25405 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25406 TODO 25407 continue; 25408 } 25409 wildIDs++; 25410 /* 25411 * SPEC (cvc-complex-type) 25412 * (5.2) "If `wild IDs` is non-empty, there must not 25413 * be any attribute uses among the {attribute uses} 25414 * whose {attribute declaration}'s {type definition} 25415 * is or is derived from ID." 25416 */ 25417 if (attrUseList != NULL) { 25418 for (j = 0; j < attrUseList->nbItems; j++) { 25419 if (xmlSchemaIsDerivedFromBuiltInType( 25420 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25421 XML_SCHEMAS_ID)) { 25422 /* URGENT VAL TODO: implement */ 25423 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25424 TODO 25425 break; 25426 } 25427 } 25428 } 25429 } 25430 } else if (type->attributeWildcard->processContents == 25431 XML_SCHEMAS_ANY_LAX) { 25432 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25433 /* 25434 * SPEC PSVI Assessment Outcome (Attribute) 25435 * [validity] = "notKnown" 25436 * [validation attempted] = "none" 25437 */ 25438 } else { 25439 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25440 } 25441 } 25442 } 25443 } 25444 25445 if (vctxt->nbAttrInfos == 0) 25446 return (0); 25447 25448 /* 25449 * Get the owner element; needed for creation of default attributes. 25450 * This fixes bug #341337, reported by David Grohmann. 25451 */ 25452 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25453 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25454 if (ielem && ielem->node && ielem->node->doc) 25455 defAttrOwnerElem = ielem->node; 25456 } 25457 /* 25458 * Validate values, create default attributes, evaluate IDCs. 25459 */ 25460 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25461 iattr = vctxt->attrInfos[i]; 25462 /* 25463 * VAL TODO: Note that we won't try to resolve IDCs to 25464 * "lax" and "skip" validated attributes. Check what to 25465 * do in this case. 25466 */ 25467 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25468 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25469 continue; 25470 /* 25471 * VAL TODO: What to do if the type definition is missing? 25472 */ 25473 if (iattr->typeDef == NULL) { 25474 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25475 continue; 25476 } 25477 25478 ACTIVATE_ATTRIBUTE(iattr); 25479 fixed = 0; 25480 xpathRes = 0; 25481 25482 if (vctxt->xpathStates != NULL) { 25483 /* 25484 * Evaluate IDCs. 25485 */ 25486 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25487 XML_ATTRIBUTE_NODE); 25488 if (xpathRes == -1) { 25489 VERROR_INT("xmlSchemaVAttributesComplex", 25490 "calling xmlSchemaXPathEvaluate()"); 25491 goto internal_error; 25492 } 25493 } 25494 25495 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25496 /* 25497 * Default/fixed attributes. 25498 * We need the value only if we need to resolve IDCs or 25499 * will create default attributes. 25500 */ 25501 if ((xpathRes) || (defAttrOwnerElem)) { 25502 if (iattr->use->defValue != NULL) { 25503 iattr->value = (xmlChar *) iattr->use->defValue; 25504 iattr->val = iattr->use->defVal; 25505 } else { 25506 iattr->value = (xmlChar *) iattr->decl->defValue; 25507 iattr->val = iattr->decl->defVal; 25508 } 25509 /* 25510 * IDCs will consume the precomputed default value, 25511 * so we need to clone it. 25512 */ 25513 if (iattr->val == NULL) { 25514 VERROR_INT("xmlSchemaVAttributesComplex", 25515 "default/fixed value on an attribute use was " 25516 "not precomputed"); 25517 goto internal_error; 25518 } 25519 iattr->val = xmlSchemaCopyValue(iattr->val); 25520 if (iattr->val == NULL) { 25521 VERROR_INT("xmlSchemaVAttributesComplex", 25522 "calling xmlSchemaCopyValue()"); 25523 goto internal_error; 25524 } 25525 } 25526 /* 25527 * PSVI: Add the default attribute to the current element. 25528 * VAL TODO: Should we use the *normalized* value? This currently 25529 * uses the *initial* value. 25530 */ 25531 25532 if (defAttrOwnerElem) { 25533 xmlChar *normValue; 25534 const xmlChar *value; 25535 25536 value = iattr->value; 25537 /* 25538 * Normalize the value. 25539 */ 25540 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25541 iattr->value); 25542 if (normValue != NULL) 25543 value = BAD_CAST normValue; 25544 25545 if (iattr->nsName == NULL) { 25546 if (xmlNewProp(defAttrOwnerElem, 25547 iattr->localName, value) == NULL) { 25548 VERROR_INT("xmlSchemaVAttributesComplex", 25549 "callling xmlNewProp()"); 25550 if (normValue != NULL) 25551 xmlFree(normValue); 25552 goto internal_error; 25553 } 25554 } else { 25555 xmlNsPtr ns; 25556 25557 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25558 defAttrOwnerElem, iattr->nsName); 25559 if (ns == NULL) { 25560 xmlChar prefix[12]; 25561 int counter = 0; 25562 25563 /* 25564 * Create a namespace declaration on the validation 25565 * root node if no namespace declaration is in scope. 25566 */ 25567 do { 25568 snprintf((char *) prefix, 12, "p%d", counter++); 25569 ns = xmlSearchNs(defAttrOwnerElem->doc, 25570 defAttrOwnerElem, BAD_CAST prefix); 25571 if (counter > 1000) { 25572 VERROR_INT( 25573 "xmlSchemaVAttributesComplex", 25574 "could not compute a ns prefix for a " 25575 "default/fixed attribute"); 25576 if (normValue != NULL) 25577 xmlFree(normValue); 25578 goto internal_error; 25579 } 25580 } while (ns != NULL); 25581 ns = xmlNewNs(vctxt->validationRoot, 25582 iattr->nsName, BAD_CAST prefix); 25583 } 25584 /* 25585 * TODO: 25586 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25587 * If we have QNames: do we need to ensure there's a 25588 * prefix defined for the QName? 25589 */ 25590 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25591 } 25592 if (normValue != NULL) 25593 xmlFree(normValue); 25594 } 25595 /* 25596 * Go directly to IDC evaluation. 25597 */ 25598 goto eval_idcs; 25599 } 25600 /* 25601 * Validate the value. 25602 */ 25603 if (vctxt->value != NULL) { 25604 /* 25605 * Free last computed value; just for safety reasons. 25606 */ 25607 xmlSchemaFreeValue(vctxt->value); 25608 vctxt->value = NULL; 25609 } 25610 /* 25611 * Note that the attribute *use* can be unavailable, if 25612 * the attribute was a wild attribute. 25613 */ 25614 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25615 ((iattr->use != NULL) && 25616 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25617 fixed = 1; 25618 else 25619 fixed = 0; 25620 /* 25621 * SPEC (cvc-attribute) 25622 * (3) "The item's `normalized value` must be locally `valid` 25623 * with respect to that {type definition} as per 25624 * String Valid ($3.14.4)." 25625 * 25626 * VAL TODO: Do we already have the 25627 * "normalized attribute value" here? 25628 */ 25629 if (xpathRes || fixed) { 25630 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25631 /* 25632 * Request a computed value. 25633 */ 25634 res = xmlSchemaVCheckCVCSimpleType( 25635 ACTXT_CAST vctxt, 25636 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25637 1, 1, 0); 25638 } else { 25639 res = xmlSchemaVCheckCVCSimpleType( 25640 ACTXT_CAST vctxt, 25641 iattr->node, iattr->typeDef, iattr->value, NULL, 25642 1, 0, 0); 25643 } 25644 25645 if (res != 0) { 25646 if (res == -1) { 25647 VERROR_INT("xmlSchemaVAttributesComplex", 25648 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25649 goto internal_error; 25650 } 25651 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25652 /* 25653 * SPEC PSVI Assessment Outcome (Attribute) 25654 * [validity] = "invalid" 25655 */ 25656 goto eval_idcs; 25657 } 25658 25659 if (fixed) { 25660 /* 25661 * SPEC Attribute Locally Valid (Use) (cvc-au) 25662 * "For an attribute information item to be `valid` 25663 * with respect to an attribute use its *normalized* 25664 * value must match the *canonical* lexical 25665 * representation of the attribute use's {value 25666 * constraint}value, if it is present and fixed." 25667 * 25668 * VAL TODO: The requirement for the *canonical* value 25669 * will be removed in XML Schema 1.1. 25670 */ 25671 /* 25672 * SPEC Attribute Locally Valid (cvc-attribute) 25673 * (4) "The item's *actual* value must match the *value* of 25674 * the {value constraint}, if it is present and fixed." 25675 */ 25676 if (iattr->val == NULL) { 25677 /* VAL TODO: A value was not precomputed. */ 25678 TODO 25679 goto eval_idcs; 25680 } 25681 if ((iattr->use != NULL) && 25682 (iattr->use->defValue != NULL)) { 25683 if (iattr->use->defVal == NULL) { 25684 /* VAL TODO: A default value was not precomputed. */ 25685 TODO 25686 goto eval_idcs; 25687 } 25688 iattr->vcValue = iattr->use->defValue; 25689 /* 25690 if (xmlSchemaCompareValuesWhtsp(attr->val, 25691 (xmlSchemaWhitespaceValueType) ws, 25692 attr->use->defVal, 25693 (xmlSchemaWhitespaceValueType) ws) != 0) { 25694 */ 25695 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25696 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25697 } else { 25698 if (iattr->decl->defVal == NULL) { 25699 /* VAL TODO: A default value was not precomputed. */ 25700 TODO 25701 goto eval_idcs; 25702 } 25703 iattr->vcValue = iattr->decl->defValue; 25704 /* 25705 if (xmlSchemaCompareValuesWhtsp(attr->val, 25706 (xmlSchemaWhitespaceValueType) ws, 25707 attrDecl->defVal, 25708 (xmlSchemaWhitespaceValueType) ws) != 0) { 25709 */ 25710 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25711 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25712 } 25713 /* 25714 * [validity] = "valid" 25715 */ 25716 } 25717eval_idcs: 25718 /* 25719 * Evaluate IDCs. 25720 */ 25721 if (xpathRes) { 25722 if (xmlSchemaXPathProcessHistory(vctxt, 25723 vctxt->depth +1) == -1) { 25724 VERROR_INT("xmlSchemaVAttributesComplex", 25725 "calling xmlSchemaXPathEvaluate()"); 25726 goto internal_error; 25727 } 25728 } else if (vctxt->xpathStates != NULL) 25729 xmlSchemaXPathPop(vctxt); 25730 } 25731 25732 /* 25733 * Report errors. 25734 */ 25735 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25736 iattr = vctxt->attrInfos[i]; 25737 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25738 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25739 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25740 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25741 continue; 25742 ACTIVATE_ATTRIBUTE(iattr); 25743 switch (iattr->state) { 25744 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25745 xmlChar *str = NULL; 25746 ACTIVATE_ELEM; 25747 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25748 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25749 "The attribute '%s' is required but missing", 25750 xmlSchemaFormatQName(&str, 25751 iattr->decl->targetNamespace, 25752 iattr->decl->name), 25753 NULL); 25754 FREE_AND_NULL(str) 25755 break; 25756 } 25757 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25758 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25759 "The type definition is absent"); 25760 break; 25761 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25762 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25763 XML_SCHEMAV_CVC_AU, NULL, NULL, 25764 "The value '%s' does not match the fixed " 25765 "value constraint '%s'", 25766 iattr->value, iattr->vcValue); 25767 break; 25768 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25769 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25770 "No matching global attribute declaration available, but " 25771 "demanded by the strict wildcard"); 25772 break; 25773 case XML_SCHEMAS_ATTR_UNKNOWN: 25774 if (iattr->metaType) 25775 break; 25776 /* 25777 * MAYBE VAL TODO: One might report different error messages 25778 * for the following errors. 25779 */ 25780 if (type->attributeWildcard == NULL) { 25781 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25782 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25783 } else { 25784 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25785 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25786 } 25787 break; 25788 default: 25789 break; 25790 } 25791 } 25792 25793 ACTIVATE_ELEM; 25794 return (0); 25795internal_error: 25796 ACTIVATE_ELEM; 25797 return (-1); 25798} 25799 25800static int 25801xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25802 int *skip) 25803{ 25804 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25805 /* 25806 * The namespace of the element was already identified to be 25807 * matching the wildcard. 25808 */ 25809 if ((skip == NULL) || (wild == NULL) || 25810 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25811 VERROR_INT("xmlSchemaValidateElemWildcard", 25812 "bad arguments"); 25813 return (-1); 25814 } 25815 *skip = 0; 25816 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25817 /* 25818 * URGENT VAL TODO: Either we need to position the stream to the 25819 * next sibling, or walk the whole subtree. 25820 */ 25821 *skip = 1; 25822 return (0); 25823 } 25824 { 25825 xmlSchemaElementPtr decl = NULL; 25826 25827 decl = xmlSchemaGetElem(vctxt->schema, 25828 vctxt->inode->localName, vctxt->inode->nsName); 25829 if (decl != NULL) { 25830 vctxt->inode->decl = decl; 25831 return (0); 25832 } 25833 } 25834 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25835 /* VAL TODO: Change to proper error code. */ 25836 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25837 "No matching global element declaration available, but " 25838 "demanded by the strict wildcard"); 25839 return (vctxt->err); 25840 } 25841 if (vctxt->nbAttrInfos != 0) { 25842 xmlSchemaAttrInfoPtr iattr; 25843 /* 25844 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25845 * (1.2.1.2.1) - (1.2.1.2.3 ) 25846 * 25847 * Use the xsi:type attribute for the type definition. 25848 */ 25849 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25850 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25851 if (iattr != NULL) { 25852 if (xmlSchemaProcessXSIType(vctxt, iattr, 25853 &(vctxt->inode->typeDef), NULL) == -1) { 25854 VERROR_INT("xmlSchemaValidateElemWildcard", 25855 "calling xmlSchemaProcessXSIType() to " 25856 "process the attribute 'xsi:nil'"); 25857 return (-1); 25858 } 25859 /* 25860 * Don't return an error on purpose. 25861 */ 25862 return (0); 25863 } 25864 } 25865 /* 25866 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25867 * 25868 * Fallback to "anyType". 25869 */ 25870 vctxt->inode->typeDef = 25871 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25872 return (0); 25873} 25874 25875/* 25876* xmlSchemaCheckCOSValidDefault: 25877* 25878* This will be called if: not nilled, no content and a default/fixed 25879* value is provided. 25880*/ 25881 25882static int 25883xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25884 const xmlChar *value, 25885 xmlSchemaValPtr *val) 25886{ 25887 int ret = 0; 25888 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25889 25890 /* 25891 * cos-valid-default: 25892 * Schema Component Constraint: Element Default Valid (Immediate) 25893 * For a string to be a valid default with respect to a type 25894 * definition the appropriate case among the following must be true: 25895 */ 25896 if WXS_IS_COMPLEX(inode->typeDef) { 25897 /* 25898 * Complex type. 25899 * 25900 * SPEC (2.1) "its {content type} must be a simple type definition 25901 * or mixed." 25902 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25903 * type}'s particle must be `emptiable` as defined by 25904 * Particle Emptiable ($3.9.6)." 25905 */ 25906 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25907 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25908 (! WXS_EMPTIABLE(inode->typeDef)))) { 25909 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25910 /* NOTE that this covers (2.2.2) as well. */ 25911 VERROR(ret, NULL, 25912 "For a string to be a valid default, the type definition " 25913 "must be a simple type or a complex type with simple content " 25914 "or mixed content and a particle emptiable"); 25915 return(ret); 25916 } 25917 } 25918 /* 25919 * 1 If the type definition is a simple type definition, then the string 25920 * must be `valid` with respect to that definition as defined by String 25921 * Valid ($3.14.4). 25922 * 25923 * AND 25924 * 25925 * 2.2.1 If the {content type} is a simple type definition, then the 25926 * string must be `valid` with respect to that simple type definition 25927 * as defined by String Valid ($3.14.4). 25928 */ 25929 if (WXS_IS_SIMPLE(inode->typeDef)) { 25930 25931 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25932 NULL, inode->typeDef, value, val, 1, 1, 0); 25933 25934 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25935 25936 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25937 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25938 } 25939 if (ret < 0) { 25940 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25941 "calling xmlSchemaVCheckCVCSimpleType()"); 25942 } 25943 return (ret); 25944} 25945 25946static void 25947xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 25948 const xmlChar * name ATTRIBUTE_UNUSED, 25949 xmlSchemaElementPtr item, 25950 xmlSchemaNodeInfoPtr inode) 25951{ 25952 inode->decl = item; 25953#ifdef DEBUG_CONTENT 25954 { 25955 xmlChar *str = NULL; 25956 25957 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25958 xmlGenericError(xmlGenericErrorContext, 25959 "AUTOMATON callback for '%s' [declaration]\n", 25960 xmlSchemaFormatQName(&str, 25961 inode->localName, inode->nsName)); 25962 } else { 25963 xmlGenericError(xmlGenericErrorContext, 25964 "AUTOMATON callback for '%s' [wildcard]\n", 25965 xmlSchemaFormatQName(&str, 25966 inode->localName, inode->nsName)); 25967 25968 } 25969 FREE_AND_NULL(str) 25970 } 25971#endif 25972} 25973 25974static int 25975xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 25976{ 25977 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 25978 if (vctxt->inode == NULL) { 25979 VERROR_INT("xmlSchemaValidatorPushElem", 25980 "calling xmlSchemaGetFreshElemInfo()"); 25981 return (-1); 25982 } 25983 vctxt->nbAttrInfos = 0; 25984 return (0); 25985} 25986 25987static int 25988xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 25989 xmlSchemaNodeInfoPtr inode, 25990 xmlSchemaTypePtr type, 25991 const xmlChar *value) 25992{ 25993 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 25994 return (xmlSchemaVCheckCVCSimpleType( 25995 ACTXT_CAST vctxt, NULL, 25996 type, value, &(inode->val), 1, 1, 0)); 25997 else 25998 return (xmlSchemaVCheckCVCSimpleType( 25999 ACTXT_CAST vctxt, NULL, 26000 type, value, NULL, 1, 0, 0)); 26001} 26002 26003 26004 26005/* 26006* Process END of element. 26007*/ 26008static int 26009xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 26010{ 26011 int ret = 0; 26012 xmlSchemaNodeInfoPtr inode = vctxt->inode; 26013 26014 if (vctxt->nbAttrInfos != 0) 26015 xmlSchemaClearAttrInfos(vctxt); 26016 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 26017 /* 26018 * This element was not expected; 26019 * we will not validate child elements of broken parents. 26020 * Skip validation of all content of the parent. 26021 */ 26022 vctxt->skipDepth = vctxt->depth -1; 26023 goto end_elem; 26024 } 26025 if ((inode->typeDef == NULL) || 26026 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 26027 /* 26028 * 1. the type definition might be missing if the element was 26029 * error prone 26030 * 2. it might be abstract. 26031 */ 26032 goto end_elem; 26033 } 26034 /* 26035 * Check the content model. 26036 */ 26037 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26038 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26039 26040 /* 26041 * Workaround for "anyType". 26042 */ 26043 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26044 goto character_content; 26045 26046 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26047 xmlChar *values[10]; 26048 int terminal, nbval = 10, nbneg; 26049 26050 if (inode->regexCtxt == NULL) { 26051 /* 26052 * Create the regex context. 26053 */ 26054 inode->regexCtxt = 26055 xmlRegNewExecCtxt(inode->typeDef->contModel, 26056 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26057 vctxt); 26058 if (inode->regexCtxt == NULL) { 26059 VERROR_INT("xmlSchemaValidatorPopElem", 26060 "failed to create a regex context"); 26061 goto internal_error; 26062 } 26063#ifdef DEBUG_AUTOMATA 26064 xmlGenericError(xmlGenericErrorContext, 26065 "AUTOMATON create on '%s'\n", inode->localName); 26066#endif 26067 } 26068 26069 /* 26070 * Do not check further content if the node has been nilled 26071 */ 26072 if (INODE_NILLED(inode)) { 26073 ret = 0; 26074#ifdef DEBUG_AUTOMATA 26075 xmlGenericError(xmlGenericErrorContext, 26076 "AUTOMATON succeeded on nilled '%s'\n", 26077 inode->localName); 26078#endif 26079 goto skip_nilled; 26080 } 26081 26082 /* 26083 * Get hold of the still expected content, since a further 26084 * call to xmlRegExecPushString() will loose this information. 26085 */ 26086 xmlRegExecNextValues(inode->regexCtxt, 26087 &nbval, &nbneg, &values[0], &terminal); 26088 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26089 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26090 /* 26091 * Still missing something. 26092 */ 26093 ret = 1; 26094 inode->flags |= 26095 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26096 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26097 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26098 "Missing child element(s)", 26099 nbval, nbneg, values); 26100#ifdef DEBUG_AUTOMATA 26101 xmlGenericError(xmlGenericErrorContext, 26102 "AUTOMATON missing ERROR on '%s'\n", 26103 inode->localName); 26104#endif 26105 } else { 26106 /* 26107 * Content model is satisfied. 26108 */ 26109 ret = 0; 26110#ifdef DEBUG_AUTOMATA 26111 xmlGenericError(xmlGenericErrorContext, 26112 "AUTOMATON succeeded on '%s'\n", 26113 inode->localName); 26114#endif 26115 } 26116 26117 } 26118 } 26119 26120skip_nilled: 26121 26122 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26123 goto end_elem; 26124 26125character_content: 26126 26127 if (vctxt->value != NULL) { 26128 xmlSchemaFreeValue(vctxt->value); 26129 vctxt->value = NULL; 26130 } 26131 /* 26132 * Check character content. 26133 */ 26134 if (inode->decl == NULL) { 26135 /* 26136 * Speedup if no declaration exists. 26137 */ 26138 if (WXS_IS_SIMPLE(inode->typeDef)) { 26139 ret = xmlSchemaVCheckINodeDataType(vctxt, 26140 inode, inode->typeDef, inode->value); 26141 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26142 ret = xmlSchemaVCheckINodeDataType(vctxt, 26143 inode, inode->typeDef->contentTypeDef, 26144 inode->value); 26145 } 26146 if (ret < 0) { 26147 VERROR_INT("xmlSchemaValidatorPopElem", 26148 "calling xmlSchemaVCheckCVCSimpleType()"); 26149 goto internal_error; 26150 } 26151 goto end_elem; 26152 } 26153 /* 26154 * cvc-elt (3.3.4) : 5 26155 * The appropriate case among the following must be true: 26156 */ 26157 /* 26158 * cvc-elt (3.3.4) : 5.1 26159 * If the declaration has a {value constraint}, 26160 * the item has neither element nor character [children] and 26161 * clause 3.2 has not applied, then all of the following must be true: 26162 */ 26163 if ((inode->decl->value != NULL) && 26164 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26165 (! INODE_NILLED(inode))) { 26166 /* 26167 * cvc-elt (3.3.4) : 5.1.1 26168 * If the `actual type definition` is a `local type definition` 26169 * then the canonical lexical representation of the {value constraint} 26170 * value must be a valid default for the `actual type definition` as 26171 * defined in Element Default Valid (Immediate) ($3.3.6). 26172 */ 26173 /* 26174 * NOTE: 'local' above means types acquired by xsi:type. 26175 * NOTE: Although the *canonical* value is stated, it is not 26176 * relevant if canonical or not. Additionally XML Schema 1.1 26177 * will removed this requirement as well. 26178 */ 26179 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26180 26181 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26182 inode->decl->value, &(inode->val)); 26183 if (ret != 0) { 26184 if (ret < 0) { 26185 VERROR_INT("xmlSchemaValidatorPopElem", 26186 "calling xmlSchemaCheckCOSValidDefault()"); 26187 goto internal_error; 26188 } 26189 goto end_elem; 26190 } 26191 /* 26192 * Stop here, to avoid redundant validation of the value 26193 * (see following). 26194 */ 26195 goto default_psvi; 26196 } 26197 /* 26198 * cvc-elt (3.3.4) : 5.1.2 26199 * The element information item with the canonical lexical 26200 * representation of the {value constraint} value used as its 26201 * `normalized value` must be `valid` with respect to the 26202 * `actual type definition` as defined by Element Locally Valid (Type) 26203 * ($3.3.4). 26204 */ 26205 if (WXS_IS_SIMPLE(inode->typeDef)) { 26206 ret = xmlSchemaVCheckINodeDataType(vctxt, 26207 inode, inode->typeDef, inode->decl->value); 26208 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26209 ret = xmlSchemaVCheckINodeDataType(vctxt, 26210 inode, inode->typeDef->contentTypeDef, 26211 inode->decl->value); 26212 } 26213 if (ret != 0) { 26214 if (ret < 0) { 26215 VERROR_INT("xmlSchemaValidatorPopElem", 26216 "calling xmlSchemaVCheckCVCSimpleType()"); 26217 goto internal_error; 26218 } 26219 goto end_elem; 26220 } 26221 26222default_psvi: 26223 /* 26224 * PSVI: Create a text node on the instance element. 26225 */ 26226 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26227 (inode->node != NULL)) { 26228 xmlNodePtr textChild; 26229 xmlChar *normValue; 26230 /* 26231 * VAL TODO: Normalize the value. 26232 */ 26233 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26234 inode->decl->value); 26235 if (normValue != NULL) { 26236 textChild = xmlNewText(BAD_CAST normValue); 26237 xmlFree(normValue); 26238 } else 26239 textChild = xmlNewText(inode->decl->value); 26240 if (textChild == NULL) { 26241 VERROR_INT("xmlSchemaValidatorPopElem", 26242 "calling xmlNewText()"); 26243 goto internal_error; 26244 } else 26245 xmlAddChild(inode->node, textChild); 26246 } 26247 26248 } else if (! INODE_NILLED(inode)) { 26249 /* 26250 * 5.2.1 The element information item must be `valid` with respect 26251 * to the `actual type definition` as defined by Element Locally 26252 * Valid (Type) ($3.3.4). 26253 */ 26254 if (WXS_IS_SIMPLE(inode->typeDef)) { 26255 /* 26256 * SPEC (cvc-type) (3.1) 26257 * "If the type definition is a simple type definition, ..." 26258 * (3.1.3) "If clause 3.2 of Element Locally Valid 26259 * (Element) ($3.3.4) did not apply, then the `normalized value` 26260 * must be `valid` with respect to the type definition as defined 26261 * by String Valid ($3.14.4). 26262 */ 26263 ret = xmlSchemaVCheckINodeDataType(vctxt, 26264 inode, inode->typeDef, inode->value); 26265 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26266 /* 26267 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26268 * definition, then the element information item must be 26269 * `valid` with respect to the type definition as per 26270 * Element Locally Valid (Complex Type) ($3.4.4);" 26271 * 26272 * SPEC (cvc-complex-type) (2.2) 26273 * "If the {content type} is a simple type definition, ... 26274 * the `normalized value` of the element information item is 26275 * `valid` with respect to that simple type definition as 26276 * defined by String Valid ($3.14.4)." 26277 */ 26278 ret = xmlSchemaVCheckINodeDataType(vctxt, 26279 inode, inode->typeDef->contentTypeDef, inode->value); 26280 } 26281 if (ret != 0) { 26282 if (ret < 0) { 26283 VERROR_INT("xmlSchemaValidatorPopElem", 26284 "calling xmlSchemaVCheckCVCSimpleType()"); 26285 goto internal_error; 26286 } 26287 goto end_elem; 26288 } 26289 /* 26290 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26291 * not applied, all of the following must be true: 26292 */ 26293 if ((inode->decl->value != NULL) && 26294 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26295 26296 /* 26297 * TODO: We will need a computed value, when comparison is 26298 * done on computed values. 26299 */ 26300 /* 26301 * 5.2.2.1 The element information item must have no element 26302 * information item [children]. 26303 */ 26304 if (inode->flags & 26305 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26306 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26307 VERROR(ret, NULL, 26308 "The content must not containt element nodes since " 26309 "there is a fixed value constraint"); 26310 goto end_elem; 26311 } else { 26312 /* 26313 * 5.2.2.2 The appropriate case among the following must 26314 * be true: 26315 */ 26316 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26317 /* 26318 * 5.2.2.2.1 If the {content type} of the `actual type 26319 * definition` is mixed, then the *initial value* of the 26320 * item must match the canonical lexical representation 26321 * of the {value constraint} value. 26322 * 26323 * ... the *initial value* of an element information 26324 * item is the string composed of, in order, the 26325 * [character code] of each character information item in 26326 * the [children] of that element information item. 26327 */ 26328 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26329 /* 26330 * VAL TODO: Report invalid & expected values as well. 26331 * VAL TODO: Implement the canonical stuff. 26332 */ 26333 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26334 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26335 ret, NULL, NULL, 26336 "The initial value '%s' does not match the fixed " 26337 "value constraint '%s'", 26338 inode->value, inode->decl->value); 26339 goto end_elem; 26340 } 26341 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26342 /* 26343 * 5.2.2.2.2 If the {content type} of the `actual type 26344 * definition` is a simple type definition, then the 26345 * *actual value* of the item must match the canonical 26346 * lexical representation of the {value constraint} value. 26347 */ 26348 /* 26349 * VAL TODO: *actual value* is the normalized value, impl. 26350 * this. 26351 * VAL TODO: Report invalid & expected values as well. 26352 * VAL TODO: Implement a comparison with the computed values. 26353 */ 26354 if (! xmlStrEqual(inode->value, 26355 inode->decl->value)) { 26356 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26357 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26358 ret, NULL, NULL, 26359 "The actual value '%s' does not match the fixed " 26360 "value constraint '%s'", 26361 inode->value, 26362 inode->decl->value); 26363 goto end_elem; 26364 } 26365 } 26366 } 26367 } 26368 } 26369 26370end_elem: 26371 if (vctxt->depth < 0) { 26372 /* TODO: raise error? */ 26373 return (0); 26374 } 26375 if (vctxt->depth == vctxt->skipDepth) 26376 vctxt->skipDepth = -1; 26377 /* 26378 * Evaluate the history of XPath state objects. 26379 */ 26380 if (inode->appliedXPath && 26381 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26382 goto internal_error; 26383 /* 26384 * MAYBE TODO: 26385 * SPEC (6) "The element information item must be `valid` with 26386 * respect to each of the {identity-constraint definitions} as per 26387 * Identity-constraint Satisfied ($3.11.4)." 26388 */ 26389 /* 26390 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26391 * need to be built in any case. 26392 * We will currently build IDC node-tables and bubble them only if 26393 * keyrefs do exist. 26394 */ 26395 26396 /* 26397 * Add the current IDC target-nodes to the IDC node-tables. 26398 */ 26399 if ((inode->idcMatchers != NULL) && 26400 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26401 { 26402 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26403 goto internal_error; 26404 } 26405 /* 26406 * Validate IDC keyrefs. 26407 */ 26408 if (vctxt->inode->hasKeyrefs) 26409 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26410 goto internal_error; 26411 /* 26412 * Merge/free the IDC table. 26413 */ 26414 if (inode->idcTable != NULL) { 26415#ifdef DEBUG_IDC_NODE_TABLE 26416 xmlSchemaDebugDumpIDCTable(stdout, 26417 inode->nsName, 26418 inode->localName, 26419 inode->idcTable); 26420#endif 26421 if ((vctxt->depth > 0) && 26422 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26423 { 26424 /* 26425 * Merge the IDC node table with the table of the parent node. 26426 */ 26427 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26428 goto internal_error; 26429 } 26430 } 26431 /* 26432 * Clear the current ielem. 26433 * VAL TODO: Don't free the PSVI IDC tables if they are 26434 * requested for the PSVI. 26435 */ 26436 xmlSchemaClearElemInfo(vctxt, inode); 26437 /* 26438 * Skip further processing if we are on the validation root. 26439 */ 26440 if (vctxt->depth == 0) { 26441 vctxt->depth--; 26442 vctxt->inode = NULL; 26443 return (0); 26444 } 26445 /* 26446 * Reset the keyrefDepth if needed. 26447 */ 26448 if (vctxt->aidcs != NULL) { 26449 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26450 do { 26451 if (aidc->keyrefDepth == vctxt->depth) { 26452 /* 26453 * A 'keyrefDepth' of a key/unique IDC matches the current 26454 * depth, this means that we are leaving the scope of the 26455 * top-most keyref IDC which refers to this IDC. 26456 */ 26457 aidc->keyrefDepth = -1; 26458 } 26459 aidc = aidc->next; 26460 } while (aidc != NULL); 26461 } 26462 vctxt->depth--; 26463 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26464 /* 26465 * VAL TODO: 7 If the element information item is the `validation root`, it must be 26466 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4). 26467 */ 26468 return (ret); 26469 26470internal_error: 26471 vctxt->err = -1; 26472 return (-1); 26473} 26474 26475/* 26476* 3.4.4 Complex Type Definition Validation Rules 26477* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26478*/ 26479static int 26480xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26481{ 26482 xmlSchemaNodeInfoPtr pielem; 26483 xmlSchemaTypePtr ptype; 26484 int ret = 0; 26485 26486 if (vctxt->depth <= 0) { 26487 VERROR_INT("xmlSchemaValidateChildElem", 26488 "not intended for the validation root"); 26489 return (-1); 26490 } 26491 pielem = vctxt->elemInfos[vctxt->depth -1]; 26492 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26493 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26494 /* 26495 * Handle 'nilled' elements. 26496 */ 26497 if (INODE_NILLED(pielem)) { 26498 /* 26499 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26500 */ 26501 ACTIVATE_PARENT_ELEM; 26502 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26503 VERROR(ret, NULL, 26504 "Neither character nor element content is allowed, " 26505 "because the element was 'nilled'"); 26506 ACTIVATE_ELEM; 26507 goto unexpected_elem; 26508 } 26509 26510 ptype = pielem->typeDef; 26511 26512 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26513 /* 26514 * Workaround for "anyType": we have currently no content model 26515 * assigned for "anyType", so handle it explicitely. 26516 * "anyType" has an unbounded, lax "any" wildcard. 26517 */ 26518 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26519 vctxt->inode->localName, 26520 vctxt->inode->nsName); 26521 26522 if (vctxt->inode->decl == NULL) { 26523 xmlSchemaAttrInfoPtr iattr; 26524 /* 26525 * Process "xsi:type". 26526 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26527 */ 26528 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26529 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26530 if (iattr != NULL) { 26531 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26532 &(vctxt->inode->typeDef), NULL); 26533 if (ret != 0) { 26534 if (ret == -1) { 26535 VERROR_INT("xmlSchemaValidateChildElem", 26536 "calling xmlSchemaProcessXSIType() to " 26537 "process the attribute 'xsi:nil'"); 26538 return (-1); 26539 } 26540 return (ret); 26541 } 26542 } else { 26543 /* 26544 * Fallback to "anyType". 26545 * 26546 * SPEC (cvc-assess-elt) 26547 * "If the item cannot be `strictly assessed`, [...] 26548 * an element information item's schema validity may be laxly 26549 * assessed if its `context-determined declaration` is not 26550 * skip by `validating` with respect to the `ur-type 26551 * definition` as per Element Locally Valid (Type) ($3.3.4)." 26552 */ 26553 vctxt->inode->typeDef = 26554 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26555 } 26556 } 26557 return (0); 26558 } 26559 26560 switch (ptype->contentType) { 26561 case XML_SCHEMA_CONTENT_EMPTY: 26562 /* 26563 * SPEC (2.1) "If the {content type} is empty, then the 26564 * element information item has no character or element 26565 * information item [children]." 26566 */ 26567 ACTIVATE_PARENT_ELEM 26568 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26569 VERROR(ret, NULL, 26570 "Element content is not allowed, " 26571 "because the content type is empty"); 26572 ACTIVATE_ELEM 26573 goto unexpected_elem; 26574 break; 26575 26576 case XML_SCHEMA_CONTENT_MIXED: 26577 case XML_SCHEMA_CONTENT_ELEMENTS: { 26578 xmlRegExecCtxtPtr regexCtxt; 26579 xmlChar *values[10]; 26580 int terminal, nbval = 10, nbneg; 26581 26582 /* VAL TODO: Optimized "anyType" validation.*/ 26583 26584 if (ptype->contModel == NULL) { 26585 VERROR_INT("xmlSchemaValidateChildElem", 26586 "type has elem content but no content model"); 26587 return (-1); 26588 } 26589 /* 26590 * Safety belf for evaluation if the cont. model was already 26591 * examined to be invalid. 26592 */ 26593 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26594 VERROR_INT("xmlSchemaValidateChildElem", 26595 "validating elem, but elem content is already invalid"); 26596 return (-1); 26597 } 26598 26599 regexCtxt = pielem->regexCtxt; 26600 if (regexCtxt == NULL) { 26601 /* 26602 * Create the regex context. 26603 */ 26604 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26605 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26606 vctxt); 26607 if (regexCtxt == NULL) { 26608 VERROR_INT("xmlSchemaValidateChildElem", 26609 "failed to create a regex context"); 26610 return (-1); 26611 } 26612 pielem->regexCtxt = regexCtxt; 26613#ifdef DEBUG_AUTOMATA 26614 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26615 pielem->localName); 26616#endif 26617 } 26618 26619 /* 26620 * SPEC (2.4) "If the {content type} is element-only or mixed, 26621 * then the sequence of the element information item's 26622 * element information item [children], if any, taken in 26623 * order, is `valid` with respect to the {content type}'s 26624 * particle, as defined in Element Sequence Locally Valid 26625 * (Particle) ($3.9.4)." 26626 */ 26627 ret = xmlRegExecPushString2(regexCtxt, 26628 vctxt->inode->localName, 26629 vctxt->inode->nsName, 26630 vctxt->inode); 26631#ifdef DEBUG_AUTOMATA 26632 if (ret < 0) 26633 xmlGenericError(xmlGenericErrorContext, 26634 "AUTOMATON push ERROR for '%s' on '%s'\n", 26635 vctxt->inode->localName, pielem->localName); 26636 else 26637 xmlGenericError(xmlGenericErrorContext, 26638 "AUTOMATON push OK for '%s' on '%s'\n", 26639 vctxt->inode->localName, pielem->localName); 26640#endif 26641 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26642 VERROR_INT("xmlSchemaValidateChildElem", 26643 "calling xmlRegExecPushString2()"); 26644 return (-1); 26645 } 26646 if (ret < 0) { 26647 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26648 &values[0], &terminal); 26649 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26650 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26651 "This element is not expected", 26652 nbval, nbneg, values); 26653 ret = vctxt->err; 26654 goto unexpected_elem; 26655 } else 26656 ret = 0; 26657 } 26658 break; 26659 case XML_SCHEMA_CONTENT_SIMPLE: 26660 case XML_SCHEMA_CONTENT_BASIC: 26661 ACTIVATE_PARENT_ELEM 26662 if (WXS_IS_COMPLEX(ptype)) { 26663 /* 26664 * SPEC (cvc-complex-type) (2.2) 26665 * "If the {content type} is a simple type definition, then 26666 * the element information item has no element information 26667 * item [children], ..." 26668 */ 26669 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26670 VERROR(ret, NULL, "Element content is not allowed, " 26671 "because the content type is a simple type definition"); 26672 } else { 26673 /* 26674 * SPEC (cvc-type) (3.1.2) "The element information item must 26675 * have no element information item [children]." 26676 */ 26677 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26678 VERROR(ret, NULL, "Element content is not allowed, " 26679 "because the type definition is simple"); 26680 } 26681 ACTIVATE_ELEM 26682 ret = vctxt->err; 26683 goto unexpected_elem; 26684 break; 26685 26686 default: 26687 break; 26688 } 26689 return (ret); 26690unexpected_elem: 26691 /* 26692 * Pop this element and set the skipDepth to skip 26693 * all further content of the parent element. 26694 */ 26695 vctxt->skipDepth = vctxt->depth; 26696 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26697 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26698 return (ret); 26699} 26700 26701#define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26702#define XML_SCHEMA_PUSH_TEXT_CREATED 2 26703#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26704 26705static int 26706xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26707 int nodeType, const xmlChar *value, int len, 26708 int mode, int *consumed) 26709{ 26710 /* 26711 * Unfortunately we have to duplicate the text sometimes. 26712 * OPTIMIZE: Maybe we could skip it, if: 26713 * 1. content type is simple 26714 * 2. whitespace is "collapse" 26715 * 3. it consists of whitespace only 26716 * 26717 * Process character content. 26718 */ 26719 if (consumed != NULL) 26720 *consumed = 0; 26721 if (INODE_NILLED(vctxt->inode)) { 26722 /* 26723 * SPEC cvc-elt (3.3.4 - 3.2.1) 26724 * "The element information item must have no character or 26725 * element information item [children]." 26726 */ 26727 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26728 "Neither character nor element content is allowed " 26729 "because the element is 'nilled'"); 26730 return (vctxt->err); 26731 } 26732 /* 26733 * SPEC (2.1) "If the {content type} is empty, then the 26734 * element information item has no character or element 26735 * information item [children]." 26736 */ 26737 if (vctxt->inode->typeDef->contentType == 26738 XML_SCHEMA_CONTENT_EMPTY) { 26739 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26740 "Character content is not allowed, " 26741 "because the content type is empty"); 26742 return (vctxt->err); 26743 } 26744 26745 if (vctxt->inode->typeDef->contentType == 26746 XML_SCHEMA_CONTENT_ELEMENTS) { 26747 if ((nodeType != XML_TEXT_NODE) || 26748 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26749 /* 26750 * SPEC cvc-complex-type (2.3) 26751 * "If the {content type} is element-only, then the 26752 * element information item has no character information 26753 * item [children] other than those whose [character 26754 * code] is defined as a white space in [XML 1.0 (Second 26755 * Edition)]." 26756 */ 26757 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26758 "Character content other than whitespace is not allowed " 26759 "because the content type is 'element-only'"); 26760 return (vctxt->err); 26761 } 26762 return (0); 26763 } 26764 26765 if ((value == NULL) || (value[0] == 0)) 26766 return (0); 26767 /* 26768 * Save the value. 26769 * NOTE that even if the content type is *mixed*, we need the 26770 * *initial value* for default/fixed value constraints. 26771 */ 26772 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26773 ((vctxt->inode->decl == NULL) || 26774 (vctxt->inode->decl->value == NULL))) 26775 return (0); 26776 26777 if (vctxt->inode->value == NULL) { 26778 /* 26779 * Set the value. 26780 */ 26781 switch (mode) { 26782 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26783 /* 26784 * When working on a tree. 26785 */ 26786 vctxt->inode->value = value; 26787 break; 26788 case XML_SCHEMA_PUSH_TEXT_CREATED: 26789 /* 26790 * When working with the reader. 26791 * The value will be freed by the element info. 26792 */ 26793 vctxt->inode->value = value; 26794 if (consumed != NULL) 26795 *consumed = 1; 26796 vctxt->inode->flags |= 26797 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26798 break; 26799 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26800 /* 26801 * When working with SAX. 26802 * The value will be freed by the element info. 26803 */ 26804 if (len != -1) 26805 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26806 else 26807 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26808 vctxt->inode->flags |= 26809 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26810 break; 26811 default: 26812 break; 26813 } 26814 } else { 26815 if (len < 0) 26816 len = xmlStrlen(value); 26817 /* 26818 * Concat the value. 26819 */ 26820 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26821 vctxt->inode->value = BAD_CAST xmlStrncat( 26822 (xmlChar *) vctxt->inode->value, value, len); 26823 } else { 26824 vctxt->inode->value = 26825 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26826 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26827 } 26828 } 26829 26830 return (0); 26831} 26832 26833static int 26834xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26835{ 26836 int ret = 0; 26837 26838 if ((vctxt->skipDepth != -1) && 26839 (vctxt->depth >= vctxt->skipDepth)) { 26840 VERROR_INT("xmlSchemaValidateElem", 26841 "in skip-state"); 26842 goto internal_error; 26843 } 26844 if (vctxt->xsiAssemble) { 26845 /* 26846 * We will stop validation if there was an error during 26847 * dynamic schema construction. 26848 * Note that we simply set @skipDepth to 0, this could 26849 * mean that a streaming document via SAX would be 26850 * still read to the end but it won't be validated any more. 26851 * TODO: If we are sure how to stop the validation at once 26852 * for all input scenarios, then this should be changed to 26853 * instantly stop the validation. 26854 */ 26855 ret = xmlSchemaAssembleByXSI(vctxt); 26856 if (ret != 0) { 26857 if (ret == -1) 26858 goto internal_error; 26859 vctxt->skipDepth = 0; 26860 return(ret); 26861 } 26862 /* 26863 * Augment the IDC definitions for the main schema and all imported ones 26864 * NOTE: main schema is the first in the imported list 26865 */ 26866 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 26867 } 26868 if (vctxt->depth > 0) { 26869 /* 26870 * Validate this element against the content model 26871 * of the parent. 26872 */ 26873 ret = xmlSchemaValidateChildElem(vctxt); 26874 if (ret != 0) { 26875 if (ret < 0) { 26876 VERROR_INT("xmlSchemaValidateElem", 26877 "calling xmlSchemaStreamValidateChildElement()"); 26878 goto internal_error; 26879 } 26880 goto exit; 26881 } 26882 if (vctxt->depth == vctxt->skipDepth) 26883 goto exit; 26884 if ((vctxt->inode->decl == NULL) && 26885 (vctxt->inode->typeDef == NULL)) { 26886 VERROR_INT("xmlSchemaValidateElem", 26887 "the child element was valid but neither the " 26888 "declaration nor the type was set"); 26889 goto internal_error; 26890 } 26891 } else { 26892 /* 26893 * Get the declaration of the validation root. 26894 */ 26895 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26896 vctxt->inode->localName, 26897 vctxt->inode->nsName); 26898 if (vctxt->inode->decl == NULL) { 26899 ret = XML_SCHEMAV_CVC_ELT_1; 26900 VERROR(ret, NULL, 26901 "No matching global declaration available " 26902 "for the validation root"); 26903 goto exit; 26904 } 26905 } 26906 26907 if (vctxt->inode->decl == NULL) 26908 goto type_validation; 26909 26910 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26911 int skip; 26912 /* 26913 * Wildcards. 26914 */ 26915 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26916 if (ret != 0) { 26917 if (ret < 0) { 26918 VERROR_INT("xmlSchemaValidateElem", 26919 "calling xmlSchemaValidateElemWildcard()"); 26920 goto internal_error; 26921 } 26922 goto exit; 26923 } 26924 if (skip) { 26925 vctxt->skipDepth = vctxt->depth; 26926 goto exit; 26927 } 26928 /* 26929 * The declaration might be set by the wildcard validation, 26930 * when the processContents is "lax" or "strict". 26931 */ 26932 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26933 /* 26934 * Clear the "decl" field to not confuse further processing. 26935 */ 26936 vctxt->inode->decl = NULL; 26937 goto type_validation; 26938 } 26939 } 26940 /* 26941 * Validate against the declaration. 26942 */ 26943 ret = xmlSchemaValidateElemDecl(vctxt); 26944 if (ret != 0) { 26945 if (ret < 0) { 26946 VERROR_INT("xmlSchemaValidateElem", 26947 "calling xmlSchemaValidateElemDecl()"); 26948 goto internal_error; 26949 } 26950 goto exit; 26951 } 26952 /* 26953 * Validate against the type definition. 26954 */ 26955type_validation: 26956 26957 if (vctxt->inode->typeDef == NULL) { 26958 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26959 ret = XML_SCHEMAV_CVC_TYPE_1; 26960 VERROR(ret, NULL, 26961 "The type definition is absent"); 26962 goto exit; 26963 } 26964 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26965 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26966 ret = XML_SCHEMAV_CVC_TYPE_2; 26967 VERROR(ret, NULL, 26968 "The type definition is abstract"); 26969 goto exit; 26970 } 26971 /* 26972 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26973 * during validation against the declaration. This must be done 26974 * _before_ attribute validation. 26975 */ 26976 if (vctxt->xpathStates != NULL) { 26977 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 26978 vctxt->inode->appliedXPath = 1; 26979 if (ret == -1) { 26980 VERROR_INT("xmlSchemaValidateElem", 26981 "calling xmlSchemaXPathEvaluate()"); 26982 goto internal_error; 26983 } 26984 } 26985 /* 26986 * Validate attributes. 26987 */ 26988 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 26989 if ((vctxt->nbAttrInfos != 0) || 26990 (vctxt->inode->typeDef->attrUses != NULL)) { 26991 26992 ret = xmlSchemaVAttributesComplex(vctxt); 26993 } 26994 } else if (vctxt->nbAttrInfos != 0) { 26995 26996 ret = xmlSchemaVAttributesSimple(vctxt); 26997 } 26998 /* 26999 * Clear registered attributes. 27000 */ 27001 if (vctxt->nbAttrInfos != 0) 27002 xmlSchemaClearAttrInfos(vctxt); 27003 if (ret == -1) { 27004 VERROR_INT("xmlSchemaValidateElem", 27005 "calling attributes validation"); 27006 goto internal_error; 27007 } 27008 /* 27009 * Don't return an error if attributes are invalid on purpose. 27010 */ 27011 ret = 0; 27012 27013exit: 27014 if (ret != 0) 27015 vctxt->skipDepth = vctxt->depth; 27016 return (ret); 27017internal_error: 27018 return (-1); 27019} 27020 27021#ifdef XML_SCHEMA_READER_ENABLED 27022static int 27023xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 27024{ 27025 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 27026 int depth, nodeType, ret = 0, consumed; 27027 xmlSchemaNodeInfoPtr ielem; 27028 27029 vctxt->depth = -1; 27030 ret = xmlTextReaderRead(vctxt->reader); 27031 /* 27032 * Move to the document element. 27033 */ 27034 while (ret == 1) { 27035 nodeType = xmlTextReaderNodeType(vctxt->reader); 27036 if (nodeType == XML_ELEMENT_NODE) 27037 goto root_found; 27038 ret = xmlTextReaderRead(vctxt->reader); 27039 } 27040 goto exit; 27041 27042root_found: 27043 27044 do { 27045 depth = xmlTextReaderDepth(vctxt->reader); 27046 nodeType = xmlTextReaderNodeType(vctxt->reader); 27047 27048 if (nodeType == XML_ELEMENT_NODE) { 27049 27050 vctxt->depth++; 27051 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27052 VERROR_INT("xmlSchemaVReaderWalk", 27053 "calling xmlSchemaValidatorPushElem()"); 27054 goto internal_error; 27055 } 27056 ielem = vctxt->inode; 27057 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27058 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27059 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27060 /* 27061 * Is the element empty? 27062 */ 27063 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27064 if (ret == -1) { 27065 VERROR_INT("xmlSchemaVReaderWalk", 27066 "calling xmlTextReaderIsEmptyElement()"); 27067 goto internal_error; 27068 } 27069 if (ret) { 27070 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27071 } 27072 /* 27073 * Register attributes. 27074 */ 27075 vctxt->nbAttrInfos = 0; 27076 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27077 if (ret == -1) { 27078 VERROR_INT("xmlSchemaVReaderWalk", 27079 "calling xmlTextReaderMoveToFirstAttribute()"); 27080 goto internal_error; 27081 } 27082 if (ret == 1) { 27083 do { 27084 /* 27085 * VAL TODO: How do we know that the reader works on a 27086 * node tree, to be able to pass a node here? 27087 */ 27088 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27089 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27090 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27091 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27092 27093 VERROR_INT("xmlSchemaVReaderWalk", 27094 "calling xmlSchemaValidatorPushAttribute()"); 27095 goto internal_error; 27096 } 27097 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27098 if (ret == -1) { 27099 VERROR_INT("xmlSchemaVReaderWalk", 27100 "calling xmlTextReaderMoveToFirstAttribute()"); 27101 goto internal_error; 27102 } 27103 } while (ret == 1); 27104 /* 27105 * Back to element position. 27106 */ 27107 ret = xmlTextReaderMoveToElement(vctxt->reader); 27108 if (ret == -1) { 27109 VERROR_INT("xmlSchemaVReaderWalk", 27110 "calling xmlTextReaderMoveToElement()"); 27111 goto internal_error; 27112 } 27113 } 27114 /* 27115 * Validate the element. 27116 */ 27117 ret= xmlSchemaValidateElem(vctxt); 27118 if (ret != 0) { 27119 if (ret == -1) { 27120 VERROR_INT("xmlSchemaVReaderWalk", 27121 "calling xmlSchemaValidateElem()"); 27122 goto internal_error; 27123 } 27124 goto exit; 27125 } 27126 if (vctxt->depth == vctxt->skipDepth) { 27127 int curDepth; 27128 /* 27129 * Skip all content. 27130 */ 27131 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27132 ret = xmlTextReaderRead(vctxt->reader); 27133 curDepth = xmlTextReaderDepth(vctxt->reader); 27134 while ((ret == 1) && (curDepth != depth)) { 27135 ret = xmlTextReaderRead(vctxt->reader); 27136 curDepth = xmlTextReaderDepth(vctxt->reader); 27137 } 27138 if (ret < 0) { 27139 /* 27140 * VAL TODO: A reader error occured; what to do here? 27141 */ 27142 ret = 1; 27143 goto exit; 27144 } 27145 } 27146 goto leave_elem; 27147 } 27148 /* 27149 * READER VAL TODO: Is an END_ELEM really never called 27150 * if the elem is empty? 27151 */ 27152 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27153 goto leave_elem; 27154 } else if (nodeType == END_ELEM) { 27155 /* 27156 * Process END of element. 27157 */ 27158leave_elem: 27159 ret = xmlSchemaValidatorPopElem(vctxt); 27160 if (ret != 0) { 27161 if (ret < 0) { 27162 VERROR_INT("xmlSchemaVReaderWalk", 27163 "calling xmlSchemaValidatorPopElem()"); 27164 goto internal_error; 27165 } 27166 goto exit; 27167 } 27168 if (vctxt->depth >= 0) 27169 ielem = vctxt->inode; 27170 else 27171 ielem = NULL; 27172 } else if ((nodeType == XML_TEXT_NODE) || 27173 (nodeType == XML_CDATA_SECTION_NODE) || 27174 (nodeType == WHTSP) || 27175 (nodeType == SIGN_WHTSP)) { 27176 /* 27177 * Process character content. 27178 */ 27179 xmlChar *value; 27180 27181 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27182 nodeType = XML_TEXT_NODE; 27183 27184 value = xmlTextReaderValue(vctxt->reader); 27185 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27186 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27187 if (! consumed) 27188 xmlFree(value); 27189 if (ret == -1) { 27190 VERROR_INT("xmlSchemaVReaderWalk", 27191 "calling xmlSchemaVPushText()"); 27192 goto internal_error; 27193 } 27194 } else if ((nodeType == XML_ENTITY_NODE) || 27195 (nodeType == XML_ENTITY_REF_NODE)) { 27196 /* 27197 * VAL TODO: What to do with entities? 27198 */ 27199 TODO 27200 } 27201 /* 27202 * Read next node. 27203 */ 27204 ret = xmlTextReaderRead(vctxt->reader); 27205 } while (ret == 1); 27206 27207exit: 27208 return (ret); 27209internal_error: 27210 return (-1); 27211} 27212#endif 27213 27214/************************************************************************ 27215 * * 27216 * SAX validation handlers * 27217 * * 27218 ************************************************************************/ 27219 27220/* 27221* Process text content. 27222*/ 27223static void 27224xmlSchemaSAXHandleText(void *ctx, 27225 const xmlChar * ch, 27226 int len) 27227{ 27228 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27229 27230 if (vctxt->depth < 0) 27231 return; 27232 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27233 return; 27234 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27235 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27236 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27237 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27238 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27239 "calling xmlSchemaVPushText()"); 27240 vctxt->err = -1; 27241 xmlStopParser(vctxt->parserCtxt); 27242 } 27243} 27244 27245/* 27246* Process CDATA content. 27247*/ 27248static void 27249xmlSchemaSAXHandleCDataSection(void *ctx, 27250 const xmlChar * ch, 27251 int len) 27252{ 27253 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27254 27255 if (vctxt->depth < 0) 27256 return; 27257 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27258 return; 27259 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27260 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27261 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27262 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27263 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27264 "calling xmlSchemaVPushText()"); 27265 vctxt->err = -1; 27266 xmlStopParser(vctxt->parserCtxt); 27267 } 27268} 27269 27270static void 27271xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27272 const xmlChar * name ATTRIBUTE_UNUSED) 27273{ 27274 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27275 27276 if (vctxt->depth < 0) 27277 return; 27278 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27279 return; 27280 /* SAX VAL TODO: What to do here? */ 27281 TODO 27282} 27283 27284static void 27285xmlSchemaSAXHandleStartElementNs(void *ctx, 27286 const xmlChar * localname, 27287 const xmlChar * prefix ATTRIBUTE_UNUSED, 27288 const xmlChar * URI, 27289 int nb_namespaces, 27290 const xmlChar ** namespaces, 27291 int nb_attributes, 27292 int nb_defaulted ATTRIBUTE_UNUSED, 27293 const xmlChar ** attributes) 27294{ 27295 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27296 int ret; 27297 xmlSchemaNodeInfoPtr ielem; 27298 int i, j; 27299 27300 /* 27301 * SAX VAL TODO: What to do with nb_defaulted? 27302 */ 27303 /* 27304 * Skip elements if inside a "skip" wildcard or invalid. 27305 */ 27306 vctxt->depth++; 27307 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27308 return; 27309 /* 27310 * Push the element. 27311 */ 27312 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27313 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27314 "calling xmlSchemaValidatorPushElem()"); 27315 goto internal_error; 27316 } 27317 ielem = vctxt->inode; 27318 /* 27319 * TODO: Is this OK? 27320 */ 27321 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27322 ielem->localName = localname; 27323 ielem->nsName = URI; 27324 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27325 /* 27326 * Register namespaces on the elem info. 27327 */ 27328 if (nb_namespaces != 0) { 27329 /* 27330 * Although the parser builds its own namespace list, 27331 * we have no access to it, so we'll use an own one. 27332 */ 27333 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27334 /* 27335 * Store prefix and namespace name. 27336 */ 27337 if (ielem->nsBindings == NULL) { 27338 ielem->nsBindings = 27339 (const xmlChar **) xmlMalloc(10 * 27340 sizeof(const xmlChar *)); 27341 if (ielem->nsBindings == NULL) { 27342 xmlSchemaVErrMemory(vctxt, 27343 "allocating namespace bindings for SAX validation", 27344 NULL); 27345 goto internal_error; 27346 } 27347 ielem->nbNsBindings = 0; 27348 ielem->sizeNsBindings = 5; 27349 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27350 ielem->sizeNsBindings *= 2; 27351 ielem->nsBindings = 27352 (const xmlChar **) xmlRealloc( 27353 (void *) ielem->nsBindings, 27354 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27355 if (ielem->nsBindings == NULL) { 27356 xmlSchemaVErrMemory(vctxt, 27357 "re-allocating namespace bindings for SAX validation", 27358 NULL); 27359 goto internal_error; 27360 } 27361 } 27362 27363 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27364 if (namespaces[j+1][0] == 0) { 27365 /* 27366 * Handle xmlns="". 27367 */ 27368 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27369 } else 27370 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27371 namespaces[j+1]; 27372 ielem->nbNsBindings++; 27373 } 27374 } 27375 /* 27376 * Register attributes. 27377 * SAX VAL TODO: We are not adding namespace declaration 27378 * attributes yet. 27379 */ 27380 if (nb_attributes != 0) { 27381 xmlChar *value; 27382 27383 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27384 /* 27385 * Duplicate the value. 27386 */ 27387 value = xmlStrndup(attributes[j+3], 27388 attributes[j+4] - attributes[j+3]); 27389 /* 27390 * TODO: Set the node line. 27391 */ 27392 ret = xmlSchemaValidatorPushAttribute(vctxt, 27393 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27394 value, 1); 27395 if (ret == -1) { 27396 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27397 "calling xmlSchemaValidatorPushAttribute()"); 27398 goto internal_error; 27399 } 27400 } 27401 } 27402 /* 27403 * Validate the element. 27404 */ 27405 ret = xmlSchemaValidateElem(vctxt); 27406 if (ret != 0) { 27407 if (ret == -1) { 27408 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27409 "calling xmlSchemaValidateElem()"); 27410 goto internal_error; 27411 } 27412 goto exit; 27413 } 27414 27415exit: 27416 return; 27417internal_error: 27418 vctxt->err = -1; 27419 xmlStopParser(vctxt->parserCtxt); 27420 return; 27421} 27422 27423static void 27424xmlSchemaSAXHandleEndElementNs(void *ctx, 27425 const xmlChar * localname ATTRIBUTE_UNUSED, 27426 const xmlChar * prefix ATTRIBUTE_UNUSED, 27427 const xmlChar * URI ATTRIBUTE_UNUSED) 27428{ 27429 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27430 int res; 27431 27432 /* 27433 * Skip elements if inside a "skip" wildcard or if invalid. 27434 */ 27435 if (vctxt->skipDepth != -1) { 27436 if (vctxt->depth > vctxt->skipDepth) { 27437 vctxt->depth--; 27438 return; 27439 } else 27440 vctxt->skipDepth = -1; 27441 } 27442 /* 27443 * SAX VAL TODO: Just a temporary check. 27444 */ 27445 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27446 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27447 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27448 "elem pop mismatch"); 27449 } 27450 res = xmlSchemaValidatorPopElem(vctxt); 27451 if (res != 0) { 27452 if (res < 0) { 27453 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27454 "calling xmlSchemaValidatorPopElem()"); 27455 goto internal_error; 27456 } 27457 goto exit; 27458 } 27459exit: 27460 return; 27461internal_error: 27462 vctxt->err = -1; 27463 xmlStopParser(vctxt->parserCtxt); 27464 return; 27465} 27466 27467/************************************************************************ 27468 * * 27469 * Validation interfaces * 27470 * * 27471 ************************************************************************/ 27472 27473/** 27474 * xmlSchemaNewValidCtxt: 27475 * @schema: a precompiled XML Schemas 27476 * 27477 * Create an XML Schemas validation context based on the given schema. 27478 * 27479 * Returns the validation context or NULL in case of error 27480 */ 27481xmlSchemaValidCtxtPtr 27482xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27483{ 27484 xmlSchemaValidCtxtPtr ret; 27485 27486 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27487 if (ret == NULL) { 27488 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27489 return (NULL); 27490 } 27491 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27492 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27493 ret->dict = xmlDictCreate(); 27494 ret->nodeQNames = xmlSchemaItemListCreate(); 27495 ret->schema = schema; 27496 return (ret); 27497} 27498 27499/** 27500 * xmlSchemaValidateSetFilename: 27501 * @vctxt: the schema validation context 27502 * @filename: the file name 27503 * 27504 * Workaround to provide file error reporting information when this is 27505 * not provided by current APIs 27506 */ 27507void 27508xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) { 27509 if (vctxt == NULL) 27510 return; 27511 if (vctxt->filename != NULL) 27512 xmlFree(vctxt->filename); 27513 if (filename != NULL) 27514 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename); 27515 else 27516 vctxt->filename = NULL; 27517} 27518 27519/** 27520 * xmlSchemaClearValidCtxt: 27521 * @vctxt: the schema validation context 27522 * 27523 * Free the resources associated to the schema validation context; 27524 * leaves some fields alive intended for reuse of the context. 27525 */ 27526static void 27527xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27528{ 27529 if (vctxt == NULL) 27530 return; 27531 27532 /* 27533 * TODO: Should we clear the flags? 27534 * Might be problematic if one reuses the context 27535 * and assumes that the options remain the same. 27536 */ 27537 vctxt->flags = 0; 27538 vctxt->validationRoot = NULL; 27539 vctxt->doc = NULL; 27540#ifdef LIBXML_READER_ENABLED 27541 vctxt->reader = NULL; 27542#endif 27543 vctxt->hasKeyrefs = 0; 27544 27545 if (vctxt->value != NULL) { 27546 xmlSchemaFreeValue(vctxt->value); 27547 vctxt->value = NULL; 27548 } 27549 /* 27550 * Augmented IDC information. 27551 */ 27552 if (vctxt->aidcs != NULL) { 27553 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27554 do { 27555 next = cur->next; 27556 xmlFree(cur); 27557 cur = next; 27558 } while (cur != NULL); 27559 vctxt->aidcs = NULL; 27560 } 27561 if (vctxt->idcMatcherCache != NULL) { 27562 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27563 27564 while (matcher) { 27565 tmp = matcher; 27566 matcher = matcher->nextCached; 27567 xmlSchemaIDCFreeMatcherList(tmp); 27568 } 27569 vctxt->idcMatcherCache = NULL; 27570 } 27571 27572 27573 if (vctxt->idcNodes != NULL) { 27574 int i; 27575 xmlSchemaPSVIIDCNodePtr item; 27576 27577 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27578 item = vctxt->idcNodes[i]; 27579 xmlFree(item->keys); 27580 xmlFree(item); 27581 } 27582 xmlFree(vctxt->idcNodes); 27583 vctxt->idcNodes = NULL; 27584 vctxt->nbIdcNodes = 0; 27585 vctxt->sizeIdcNodes = 0; 27586 } 27587 /* 27588 * Note that we won't delete the XPath state pool here. 27589 */ 27590 if (vctxt->xpathStates != NULL) { 27591 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27592 vctxt->xpathStates = NULL; 27593 } 27594 /* 27595 * Attribute info. 27596 */ 27597 if (vctxt->nbAttrInfos != 0) { 27598 xmlSchemaClearAttrInfos(vctxt); 27599 } 27600 /* 27601 * Element info. 27602 */ 27603 if (vctxt->elemInfos != NULL) { 27604 int i; 27605 xmlSchemaNodeInfoPtr ei; 27606 27607 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27608 ei = vctxt->elemInfos[i]; 27609 if (ei == NULL) 27610 break; 27611 xmlSchemaClearElemInfo(vctxt, ei); 27612 } 27613 } 27614 xmlSchemaItemListClear(vctxt->nodeQNames); 27615 /* Recreate the dict. */ 27616 xmlDictFree(vctxt->dict); 27617 /* 27618 * TODO: Is is save to recreate it? Do we have a scenario 27619 * where the user provides the dict? 27620 */ 27621 vctxt->dict = xmlDictCreate(); 27622 27623 if (vctxt->filename != NULL) { 27624 xmlFree(vctxt->filename); 27625 vctxt->filename = NULL; 27626 } 27627} 27628 27629/** 27630 * xmlSchemaFreeValidCtxt: 27631 * @ctxt: the schema validation context 27632 * 27633 * Free the resources associated to the schema validation context 27634 */ 27635void 27636xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27637{ 27638 if (ctxt == NULL) 27639 return; 27640 if (ctxt->value != NULL) 27641 xmlSchemaFreeValue(ctxt->value); 27642 if (ctxt->pctxt != NULL) 27643 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27644 if (ctxt->idcNodes != NULL) { 27645 int i; 27646 xmlSchemaPSVIIDCNodePtr item; 27647 27648 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27649 item = ctxt->idcNodes[i]; 27650 xmlFree(item->keys); 27651 xmlFree(item); 27652 } 27653 xmlFree(ctxt->idcNodes); 27654 } 27655 if (ctxt->idcKeys != NULL) { 27656 int i; 27657 for (i = 0; i < ctxt->nbIdcKeys; i++) 27658 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27659 xmlFree(ctxt->idcKeys); 27660 } 27661 27662 if (ctxt->xpathStates != NULL) { 27663 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27664 ctxt->xpathStates = NULL; 27665 } 27666 if (ctxt->xpathStatePool != NULL) { 27667 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27668 ctxt->xpathStatePool = NULL; 27669 } 27670 27671 /* 27672 * Augmented IDC information. 27673 */ 27674 if (ctxt->aidcs != NULL) { 27675 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27676 do { 27677 next = cur->next; 27678 xmlFree(cur); 27679 cur = next; 27680 } while (cur != NULL); 27681 } 27682 if (ctxt->attrInfos != NULL) { 27683 int i; 27684 xmlSchemaAttrInfoPtr attr; 27685 27686 /* Just a paranoid call to the cleanup. */ 27687 if (ctxt->nbAttrInfos != 0) 27688 xmlSchemaClearAttrInfos(ctxt); 27689 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27690 attr = ctxt->attrInfos[i]; 27691 xmlFree(attr); 27692 } 27693 xmlFree(ctxt->attrInfos); 27694 } 27695 if (ctxt->elemInfos != NULL) { 27696 int i; 27697 xmlSchemaNodeInfoPtr ei; 27698 27699 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27700 ei = ctxt->elemInfos[i]; 27701 if (ei == NULL) 27702 break; 27703 xmlSchemaClearElemInfo(ctxt, ei); 27704 xmlFree(ei); 27705 } 27706 xmlFree(ctxt->elemInfos); 27707 } 27708 if (ctxt->nodeQNames != NULL) 27709 xmlSchemaItemListFree(ctxt->nodeQNames); 27710 if (ctxt->dict != NULL) 27711 xmlDictFree(ctxt->dict); 27712 if (ctxt->filename != NULL) 27713 xmlFree(ctxt->filename); 27714 xmlFree(ctxt); 27715} 27716 27717/** 27718 * xmlSchemaIsValid: 27719 * @ctxt: the schema validation context 27720 * 27721 * Check if any error was detected during validation. 27722 * 27723 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27724 * of internal error. 27725 */ 27726int 27727xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27728{ 27729 if (ctxt == NULL) 27730 return(-1); 27731 return(ctxt->err == 0); 27732} 27733 27734/** 27735 * xmlSchemaSetValidErrors: 27736 * @ctxt: a schema validation context 27737 * @err: the error function 27738 * @warn: the warning function 27739 * @ctx: the functions context 27740 * 27741 * Set the error and warning callback informations 27742 */ 27743void 27744xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27745 xmlSchemaValidityErrorFunc err, 27746 xmlSchemaValidityWarningFunc warn, void *ctx) 27747{ 27748 if (ctxt == NULL) 27749 return; 27750 ctxt->error = err; 27751 ctxt->warning = warn; 27752 ctxt->errCtxt = ctx; 27753 if (ctxt->pctxt != NULL) 27754 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27755} 27756 27757/** 27758 * xmlSchemaSetValidStructuredErrors: 27759 * @ctxt: a schema validation context 27760 * @serror: the structured error function 27761 * @ctx: the functions context 27762 * 27763 * Set the structured error callback 27764 */ 27765void 27766xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27767 xmlStructuredErrorFunc serror, void *ctx) 27768{ 27769 if (ctxt == NULL) 27770 return; 27771 ctxt->serror = serror; 27772 ctxt->error = NULL; 27773 ctxt->warning = NULL; 27774 ctxt->errCtxt = ctx; 27775 if (ctxt->pctxt != NULL) 27776 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27777} 27778 27779/** 27780 * xmlSchemaGetValidErrors: 27781 * @ctxt: a XML-Schema validation context 27782 * @err: the error function result 27783 * @warn: the warning function result 27784 * @ctx: the functions context result 27785 * 27786 * Get the error and warning callback informations 27787 * 27788 * Returns -1 in case of error and 0 otherwise 27789 */ 27790int 27791xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27792 xmlSchemaValidityErrorFunc * err, 27793 xmlSchemaValidityWarningFunc * warn, void **ctx) 27794{ 27795 if (ctxt == NULL) 27796 return (-1); 27797 if (err != NULL) 27798 *err = ctxt->error; 27799 if (warn != NULL) 27800 *warn = ctxt->warning; 27801 if (ctx != NULL) 27802 *ctx = ctxt->errCtxt; 27803 return (0); 27804} 27805 27806 27807/** 27808 * xmlSchemaSetValidOptions: 27809 * @ctxt: a schema validation context 27810 * @options: a combination of xmlSchemaValidOption 27811 * 27812 * Sets the options to be used during the validation. 27813 * 27814 * Returns 0 in case of success, -1 in case of an 27815 * API error. 27816 */ 27817int 27818xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27819 int options) 27820 27821{ 27822 int i; 27823 27824 if (ctxt == NULL) 27825 return (-1); 27826 /* 27827 * WARNING: Change the start value if adding to the 27828 * xmlSchemaValidOption. 27829 * TODO: Is there an other, more easy to maintain, 27830 * way? 27831 */ 27832 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27833 if (options & 1<<i) 27834 return (-1); 27835 } 27836 ctxt->options = options; 27837 return (0); 27838} 27839 27840/** 27841 * xmlSchemaValidCtxtGetOptions: 27842 * @ctxt: a schema validation context 27843 * 27844 * Get the validation context options. 27845 * 27846 * Returns the option combination or -1 on error. 27847 */ 27848int 27849xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27850 27851{ 27852 if (ctxt == NULL) 27853 return (-1); 27854 else 27855 return (ctxt->options); 27856} 27857 27858static int 27859xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27860{ 27861 xmlAttrPtr attr; 27862 int ret = 0; 27863 xmlSchemaNodeInfoPtr ielem = NULL; 27864 xmlNodePtr node, valRoot; 27865 const xmlChar *nsName; 27866 27867 /* DOC VAL TODO: Move this to the start function. */ 27868 if (vctxt->validationRoot != NULL) 27869 valRoot = vctxt->validationRoot; 27870 else 27871 valRoot = xmlDocGetRootElement(vctxt->doc); 27872 if (valRoot == NULL) { 27873 /* VAL TODO: Error code? */ 27874 VERROR(1, NULL, "The document has no document element"); 27875 return (1); 27876 } 27877 vctxt->depth = -1; 27878 vctxt->validationRoot = valRoot; 27879 node = valRoot; 27880 while (node != NULL) { 27881 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27882 goto next_sibling; 27883 if (node->type == XML_ELEMENT_NODE) { 27884 27885 /* 27886 * Init the node-info. 27887 */ 27888 vctxt->depth++; 27889 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27890 goto internal_error; 27891 ielem = vctxt->inode; 27892 ielem->node = node; 27893 ielem->nodeLine = node->line; 27894 ielem->localName = node->name; 27895 if (node->ns != NULL) 27896 ielem->nsName = node->ns->href; 27897 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27898 /* 27899 * Register attributes. 27900 * DOC VAL TODO: We do not register namespace declaration 27901 * attributes yet. 27902 */ 27903 vctxt->nbAttrInfos = 0; 27904 if (node->properties != NULL) { 27905 attr = node->properties; 27906 do { 27907 if (attr->ns != NULL) 27908 nsName = attr->ns->href; 27909 else 27910 nsName = NULL; 27911 ret = xmlSchemaValidatorPushAttribute(vctxt, 27912 (xmlNodePtr) attr, 27913 /* 27914 * Note that we give it the line number of the 27915 * parent element. 27916 */ 27917 ielem->nodeLine, 27918 attr->name, nsName, 0, 27919 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27920 if (ret == -1) { 27921 VERROR_INT("xmlSchemaDocWalk", 27922 "calling xmlSchemaValidatorPushAttribute()"); 27923 goto internal_error; 27924 } 27925 attr = attr->next; 27926 } while (attr); 27927 } 27928 /* 27929 * Validate the element. 27930 */ 27931 ret = xmlSchemaValidateElem(vctxt); 27932 if (ret != 0) { 27933 if (ret == -1) { 27934 VERROR_INT("xmlSchemaDocWalk", 27935 "calling xmlSchemaValidateElem()"); 27936 goto internal_error; 27937 } 27938 /* 27939 * Don't stop validation; just skip the content 27940 * of this element. 27941 */ 27942 goto leave_node; 27943 } 27944 if ((vctxt->skipDepth != -1) && 27945 (vctxt->depth >= vctxt->skipDepth)) 27946 goto leave_node; 27947 } else if ((node->type == XML_TEXT_NODE) || 27948 (node->type == XML_CDATA_SECTION_NODE)) { 27949 /* 27950 * Process character content. 27951 */ 27952 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 27953 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27954 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 27955 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 27956 if (ret < 0) { 27957 VERROR_INT("xmlSchemaVDocWalk", 27958 "calling xmlSchemaVPushText()"); 27959 goto internal_error; 27960 } 27961 /* 27962 * DOC VAL TODO: Should we skip further validation of the 27963 * element content here? 27964 */ 27965 } else if ((node->type == XML_ENTITY_NODE) || 27966 (node->type == XML_ENTITY_REF_NODE)) { 27967 /* 27968 * DOC VAL TODO: What to do with entities? 27969 */ 27970 VERROR_INT("xmlSchemaVDocWalk", 27971 "there is at least one entity reference in the node-tree " 27972 "currently being validated. Processing of entities with " 27973 "this XML Schema processor is not supported (yet). Please " 27974 "substitute entities before validation."); 27975 goto internal_error; 27976 } else { 27977 goto leave_node; 27978 /* 27979 * DOC VAL TODO: XInclude nodes, etc. 27980 */ 27981 } 27982 /* 27983 * Walk the doc. 27984 */ 27985 if (node->children != NULL) { 27986 node = node->children; 27987 continue; 27988 } 27989leave_node: 27990 if (node->type == XML_ELEMENT_NODE) { 27991 /* 27992 * Leaving the scope of an element. 27993 */ 27994 if (node != vctxt->inode->node) { 27995 VERROR_INT("xmlSchemaVDocWalk", 27996 "element position mismatch"); 27997 goto internal_error; 27998 } 27999 ret = xmlSchemaValidatorPopElem(vctxt); 28000 if (ret != 0) { 28001 if (ret < 0) { 28002 VERROR_INT("xmlSchemaVDocWalk", 28003 "calling xmlSchemaValidatorPopElem()"); 28004 goto internal_error; 28005 } 28006 } 28007 if (node == valRoot) 28008 goto exit; 28009 } 28010next_sibling: 28011 if (node->next != NULL) 28012 node = node->next; 28013 else { 28014 node = node->parent; 28015 goto leave_node; 28016 } 28017 } 28018 28019exit: 28020 return (ret); 28021internal_error: 28022 return (-1); 28023} 28024 28025static int 28026xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 28027 /* 28028 * Some initialization. 28029 */ 28030 vctxt->err = 0; 28031 vctxt->nberrors = 0; 28032 vctxt->depth = -1; 28033 vctxt->skipDepth = -1; 28034 vctxt->xsiAssemble = 0; 28035 vctxt->hasKeyrefs = 0; 28036#ifdef ENABLE_IDC_NODE_TABLES_TEST 28037 vctxt->createIDCNodeTables = 1; 28038#else 28039 vctxt->createIDCNodeTables = 0; 28040#endif 28041 /* 28042 * Create a schema + parser if necessary. 28043 */ 28044 if (vctxt->schema == NULL) { 28045 xmlSchemaParserCtxtPtr pctxt; 28046 28047 vctxt->xsiAssemble = 1; 28048 /* 28049 * If not schema was given then we will create a schema 28050 * dynamically using XSI schema locations. 28051 * 28052 * Create the schema parser context. 28053 */ 28054 if ((vctxt->pctxt == NULL) && 28055 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 28056 return (-1); 28057 pctxt = vctxt->pctxt; 28058 pctxt->xsiAssemble = 1; 28059 /* 28060 * Create the schema. 28061 */ 28062 vctxt->schema = xmlSchemaNewSchema(pctxt); 28063 if (vctxt->schema == NULL) 28064 return (-1); 28065 /* 28066 * Create the schema construction context. 28067 */ 28068 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 28069 if (pctxt->constructor == NULL) 28070 return(-1); 28071 pctxt->constructor->mainSchema = vctxt->schema; 28072 /* 28073 * Take ownership of the constructor to be able to free it. 28074 */ 28075 pctxt->ownsConstructor = 1; 28076 } 28077 /* 28078 * Augment the IDC definitions for the main schema and all imported ones 28079 * NOTE: main schema if the first in the imported list 28080 */ 28081 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 28082 28083 return(0); 28084} 28085 28086static void 28087xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28088 if (vctxt->xsiAssemble) { 28089 if (vctxt->schema != NULL) { 28090 xmlSchemaFree(vctxt->schema); 28091 vctxt->schema = NULL; 28092 } 28093 } 28094 xmlSchemaClearValidCtxt(vctxt); 28095} 28096 28097static int 28098xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28099{ 28100 int ret = 0; 28101 28102 if (xmlSchemaPreRun(vctxt) < 0) 28103 return(-1); 28104 28105 if (vctxt->doc != NULL) { 28106 /* 28107 * Tree validation. 28108 */ 28109 ret = xmlSchemaVDocWalk(vctxt); 28110#ifdef LIBXML_READER_ENABLED 28111 } else if (vctxt->reader != NULL) { 28112 /* 28113 * XML Reader validation. 28114 */ 28115#ifdef XML_SCHEMA_READER_ENABLED 28116 ret = xmlSchemaVReaderWalk(vctxt); 28117#endif 28118#endif 28119 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28120 /* 28121 * SAX validation. 28122 */ 28123 ret = xmlParseDocument(vctxt->parserCtxt); 28124 } else { 28125 VERROR_INT("xmlSchemaVStart", 28126 "no instance to validate"); 28127 ret = -1; 28128 } 28129 28130 xmlSchemaPostRun(vctxt); 28131 if (ret == 0) 28132 ret = vctxt->err; 28133 return (ret); 28134} 28135 28136/** 28137 * xmlSchemaValidateOneElement: 28138 * @ctxt: a schema validation context 28139 * @elem: an element node 28140 * 28141 * Validate a branch of a tree, starting with the given @elem. 28142 * 28143 * Returns 0 if the element and its subtree is valid, a positive error 28144 * code number otherwise and -1 in case of an internal or API error. 28145 */ 28146int 28147xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28148{ 28149 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28150 return (-1); 28151 28152 if (ctxt->schema == NULL) 28153 return (-1); 28154 28155 ctxt->doc = elem->doc; 28156 ctxt->node = elem; 28157 ctxt->validationRoot = elem; 28158 return(xmlSchemaVStart(ctxt)); 28159} 28160 28161/** 28162 * xmlSchemaValidateDoc: 28163 * @ctxt: a schema validation context 28164 * @doc: a parsed document tree 28165 * 28166 * Validate a document tree in memory. 28167 * 28168 * Returns 0 if the document is schemas valid, a positive error code 28169 * number otherwise and -1 in case of internal or API error. 28170 */ 28171int 28172xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28173{ 28174 if ((ctxt == NULL) || (doc == NULL)) 28175 return (-1); 28176 28177 ctxt->doc = doc; 28178 ctxt->node = xmlDocGetRootElement(doc); 28179 if (ctxt->node == NULL) { 28180 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28181 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28182 (xmlNodePtr) doc, NULL, 28183 "The document has no document element", NULL, NULL); 28184 return (ctxt->err); 28185 } 28186 ctxt->validationRoot = ctxt->node; 28187 return (xmlSchemaVStart(ctxt)); 28188} 28189 28190 28191/************************************************************************ 28192 * * 28193 * Function and data for SAX streaming API * 28194 * * 28195 ************************************************************************/ 28196typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28197typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28198 28199struct _xmlSchemaSplitSAXData { 28200 xmlSAXHandlerPtr user_sax; 28201 void *user_data; 28202 xmlSchemaValidCtxtPtr ctxt; 28203 xmlSAXHandlerPtr schemas_sax; 28204}; 28205 28206#define XML_SAX_PLUG_MAGIC 0xdc43ba21 28207 28208struct _xmlSchemaSAXPlug { 28209 unsigned int magic; 28210 28211 /* the original callbacks informations */ 28212 xmlSAXHandlerPtr *user_sax_ptr; 28213 xmlSAXHandlerPtr user_sax; 28214 void **user_data_ptr; 28215 void *user_data; 28216 28217 /* the block plugged back and validation informations */ 28218 xmlSAXHandler schemas_sax; 28219 xmlSchemaValidCtxtPtr ctxt; 28220}; 28221 28222/* All those functions just bounces to the user provided SAX handlers */ 28223static void 28224internalSubsetSplit(void *ctx, const xmlChar *name, 28225 const xmlChar *ExternalID, const xmlChar *SystemID) 28226{ 28227 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28228 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28229 (ctxt->user_sax->internalSubset != NULL)) 28230 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28231 SystemID); 28232} 28233 28234static int 28235isStandaloneSplit(void *ctx) 28236{ 28237 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28238 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28239 (ctxt->user_sax->isStandalone != NULL)) 28240 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28241 return(0); 28242} 28243 28244static int 28245hasInternalSubsetSplit(void *ctx) 28246{ 28247 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28248 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28249 (ctxt->user_sax->hasInternalSubset != NULL)) 28250 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28251 return(0); 28252} 28253 28254static int 28255hasExternalSubsetSplit(void *ctx) 28256{ 28257 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28258 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28259 (ctxt->user_sax->hasExternalSubset != NULL)) 28260 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28261 return(0); 28262} 28263 28264static void 28265externalSubsetSplit(void *ctx, const xmlChar *name, 28266 const xmlChar *ExternalID, const xmlChar *SystemID) 28267{ 28268 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28269 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28270 (ctxt->user_sax->externalSubset != NULL)) 28271 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28272 SystemID); 28273} 28274 28275static xmlParserInputPtr 28276resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28277{ 28278 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28279 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28280 (ctxt->user_sax->resolveEntity != NULL)) 28281 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28282 systemId)); 28283 return(NULL); 28284} 28285 28286static xmlEntityPtr 28287getEntitySplit(void *ctx, const xmlChar *name) 28288{ 28289 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28290 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28291 (ctxt->user_sax->getEntity != NULL)) 28292 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28293 return(NULL); 28294} 28295 28296static xmlEntityPtr 28297getParameterEntitySplit(void *ctx, const xmlChar *name) 28298{ 28299 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28300 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28301 (ctxt->user_sax->getParameterEntity != NULL)) 28302 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28303 return(NULL); 28304} 28305 28306 28307static void 28308entityDeclSplit(void *ctx, const xmlChar *name, int type, 28309 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28310{ 28311 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28312 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28313 (ctxt->user_sax->entityDecl != NULL)) 28314 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28315 systemId, content); 28316} 28317 28318static void 28319attributeDeclSplit(void *ctx, const xmlChar * elem, 28320 const xmlChar * name, int type, int def, 28321 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28322{ 28323 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28324 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28325 (ctxt->user_sax->attributeDecl != NULL)) { 28326 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28327 def, defaultValue, tree); 28328 } else { 28329 xmlFreeEnumeration(tree); 28330 } 28331} 28332 28333static void 28334elementDeclSplit(void *ctx, const xmlChar *name, int type, 28335 xmlElementContentPtr content) 28336{ 28337 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28338 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28339 (ctxt->user_sax->elementDecl != NULL)) 28340 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28341} 28342 28343static void 28344notationDeclSplit(void *ctx, const xmlChar *name, 28345 const xmlChar *publicId, const xmlChar *systemId) 28346{ 28347 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28348 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28349 (ctxt->user_sax->notationDecl != NULL)) 28350 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28351 systemId); 28352} 28353 28354static void 28355unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28356 const xmlChar *publicId, const xmlChar *systemId, 28357 const xmlChar *notationName) 28358{ 28359 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28360 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28361 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28362 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28363 systemId, notationName); 28364} 28365 28366static void 28367setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28368{ 28369 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28370 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28371 (ctxt->user_sax->setDocumentLocator != NULL)) 28372 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28373} 28374 28375static void 28376startDocumentSplit(void *ctx) 28377{ 28378 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28379 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28380 (ctxt->user_sax->startDocument != NULL)) 28381 ctxt->user_sax->startDocument(ctxt->user_data); 28382} 28383 28384static void 28385endDocumentSplit(void *ctx) 28386{ 28387 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28388 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28389 (ctxt->user_sax->endDocument != NULL)) 28390 ctxt->user_sax->endDocument(ctxt->user_data); 28391} 28392 28393static void 28394processingInstructionSplit(void *ctx, const xmlChar *target, 28395 const xmlChar *data) 28396{ 28397 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28398 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28399 (ctxt->user_sax->processingInstruction != NULL)) 28400 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28401} 28402 28403static void 28404commentSplit(void *ctx, const xmlChar *value) 28405{ 28406 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28407 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28408 (ctxt->user_sax->comment != NULL)) 28409 ctxt->user_sax->comment(ctxt->user_data, value); 28410} 28411 28412/* 28413 * Varargs error callbacks to the user application, harder ... 28414 */ 28415 28416static void XMLCDECL 28417warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28418 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28419 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28420 (ctxt->user_sax->warning != NULL)) { 28421 TODO 28422 } 28423} 28424static void XMLCDECL 28425errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28426 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28427 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28428 (ctxt->user_sax->error != NULL)) { 28429 TODO 28430 } 28431} 28432static void XMLCDECL 28433fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28434 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28435 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28436 (ctxt->user_sax->fatalError != NULL)) { 28437 TODO 28438 } 28439} 28440 28441/* 28442 * Those are function where both the user handler and the schemas handler 28443 * need to be called. 28444 */ 28445static void 28446charactersSplit(void *ctx, const xmlChar *ch, int len) 28447{ 28448 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28449 if (ctxt == NULL) 28450 return; 28451 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28452 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28453 if (ctxt->ctxt != NULL) 28454 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28455} 28456 28457static void 28458ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28459{ 28460 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28461 if (ctxt == NULL) 28462 return; 28463 if ((ctxt->user_sax != NULL) && 28464 (ctxt->user_sax->ignorableWhitespace != NULL)) 28465 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28466 if (ctxt->ctxt != NULL) 28467 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28468} 28469 28470static void 28471cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28472{ 28473 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28474 if (ctxt == NULL) 28475 return; 28476 if ((ctxt->user_sax != NULL) && 28477 (ctxt->user_sax->cdataBlock != NULL)) 28478 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28479 if (ctxt->ctxt != NULL) 28480 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28481} 28482 28483static void 28484referenceSplit(void *ctx, const xmlChar *name) 28485{ 28486 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28487 if (ctxt == NULL) 28488 return; 28489 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28490 (ctxt->user_sax->reference != NULL)) 28491 ctxt->user_sax->reference(ctxt->user_data, name); 28492 if (ctxt->ctxt != NULL) 28493 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28494} 28495 28496static void 28497startElementNsSplit(void *ctx, const xmlChar * localname, 28498 const xmlChar * prefix, const xmlChar * URI, 28499 int nb_namespaces, const xmlChar ** namespaces, 28500 int nb_attributes, int nb_defaulted, 28501 const xmlChar ** attributes) { 28502 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28503 if (ctxt == NULL) 28504 return; 28505 if ((ctxt->user_sax != NULL) && 28506 (ctxt->user_sax->startElementNs != NULL)) 28507 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28508 URI, nb_namespaces, namespaces, 28509 nb_attributes, nb_defaulted, 28510 attributes); 28511 if (ctxt->ctxt != NULL) 28512 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28513 URI, nb_namespaces, namespaces, 28514 nb_attributes, nb_defaulted, 28515 attributes); 28516} 28517 28518static void 28519endElementNsSplit(void *ctx, const xmlChar * localname, 28520 const xmlChar * prefix, const xmlChar * URI) { 28521 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28522 if (ctxt == NULL) 28523 return; 28524 if ((ctxt->user_sax != NULL) && 28525 (ctxt->user_sax->endElementNs != NULL)) 28526 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28527 if (ctxt->ctxt != NULL) 28528 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28529} 28530 28531/** 28532 * xmlSchemaSAXPlug: 28533 * @ctxt: a schema validation context 28534 * @sax: a pointer to the original xmlSAXHandlerPtr 28535 * @user_data: a pointer to the original SAX user data pointer 28536 * 28537 * Plug a SAX based validation layer in a SAX parsing event flow. 28538 * The original @saxptr and @dataptr data are replaced by new pointers 28539 * but the calls to the original will be maintained. 28540 * 28541 * Returns a pointer to a data structure needed to unplug the validation layer 28542 * or NULL in case of errors. 28543 */ 28544xmlSchemaSAXPlugPtr 28545xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28546 xmlSAXHandlerPtr *sax, void **user_data) 28547{ 28548 xmlSchemaSAXPlugPtr ret; 28549 xmlSAXHandlerPtr old_sax; 28550 28551 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28552 return(NULL); 28553 28554 /* 28555 * We only allow to plug into SAX2 event streams 28556 */ 28557 old_sax = *sax; 28558 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28559 return(NULL); 28560 if ((old_sax != NULL) && 28561 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28562 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28563 return(NULL); 28564 28565 /* 28566 * everything seems right allocate the local data needed for that layer 28567 */ 28568 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28569 if (ret == NULL) { 28570 return(NULL); 28571 } 28572 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28573 ret->magic = XML_SAX_PLUG_MAGIC; 28574 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28575 ret->ctxt = ctxt; 28576 ret->user_sax_ptr = sax; 28577 ret->user_sax = old_sax; 28578 if (old_sax == NULL) { 28579 /* 28580 * go direct, no need for the split block and functions. 28581 */ 28582 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28583 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28584 /* 28585 * Note that we use the same text-function for both, to prevent 28586 * the parser from testing for ignorable whitespace. 28587 */ 28588 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28589 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28590 28591 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28592 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28593 28594 ret->user_data = ctxt; 28595 *user_data = ctxt; 28596 } else { 28597 /* 28598 * for each callback unused by Schemas initialize it to the Split 28599 * routine only if non NULL in the user block, this can speed up 28600 * things at the SAX level. 28601 */ 28602 if (old_sax->internalSubset != NULL) 28603 ret->schemas_sax.internalSubset = internalSubsetSplit; 28604 if (old_sax->isStandalone != NULL) 28605 ret->schemas_sax.isStandalone = isStandaloneSplit; 28606 if (old_sax->hasInternalSubset != NULL) 28607 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28608 if (old_sax->hasExternalSubset != NULL) 28609 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28610 if (old_sax->resolveEntity != NULL) 28611 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28612 if (old_sax->getEntity != NULL) 28613 ret->schemas_sax.getEntity = getEntitySplit; 28614 if (old_sax->entityDecl != NULL) 28615 ret->schemas_sax.entityDecl = entityDeclSplit; 28616 if (old_sax->notationDecl != NULL) 28617 ret->schemas_sax.notationDecl = notationDeclSplit; 28618 if (old_sax->attributeDecl != NULL) 28619 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28620 if (old_sax->elementDecl != NULL) 28621 ret->schemas_sax.elementDecl = elementDeclSplit; 28622 if (old_sax->unparsedEntityDecl != NULL) 28623 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28624 if (old_sax->setDocumentLocator != NULL) 28625 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28626 if (old_sax->startDocument != NULL) 28627 ret->schemas_sax.startDocument = startDocumentSplit; 28628 if (old_sax->endDocument != NULL) 28629 ret->schemas_sax.endDocument = endDocumentSplit; 28630 if (old_sax->processingInstruction != NULL) 28631 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28632 if (old_sax->comment != NULL) 28633 ret->schemas_sax.comment = commentSplit; 28634 if (old_sax->warning != NULL) 28635 ret->schemas_sax.warning = warningSplit; 28636 if (old_sax->error != NULL) 28637 ret->schemas_sax.error = errorSplit; 28638 if (old_sax->fatalError != NULL) 28639 ret->schemas_sax.fatalError = fatalErrorSplit; 28640 if (old_sax->getParameterEntity != NULL) 28641 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28642 if (old_sax->externalSubset != NULL) 28643 ret->schemas_sax.externalSubset = externalSubsetSplit; 28644 28645 /* 28646 * the 6 schemas callback have to go to the splitter functions 28647 * Note that we use the same text-function for ignorableWhitespace 28648 * if possible, to prevent the parser from testing for ignorable 28649 * whitespace. 28650 */ 28651 ret->schemas_sax.characters = charactersSplit; 28652 if ((old_sax->ignorableWhitespace != NULL) && 28653 (old_sax->ignorableWhitespace != old_sax->characters)) 28654 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28655 else 28656 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28657 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28658 ret->schemas_sax.reference = referenceSplit; 28659 ret->schemas_sax.startElementNs = startElementNsSplit; 28660 ret->schemas_sax.endElementNs = endElementNsSplit; 28661 28662 ret->user_data_ptr = user_data; 28663 ret->user_data = *user_data; 28664 *user_data = ret; 28665 } 28666 28667 /* 28668 * plug the pointers back. 28669 */ 28670 *sax = &(ret->schemas_sax); 28671 ctxt->sax = *sax; 28672 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28673 xmlSchemaPreRun(ctxt); 28674 return(ret); 28675} 28676 28677/** 28678 * xmlSchemaSAXUnplug: 28679 * @plug: a data structure returned by xmlSchemaSAXPlug 28680 * 28681 * Unplug a SAX based validation layer in a SAX parsing event flow. 28682 * The original pointers used in the call are restored. 28683 * 28684 * Returns 0 in case of success and -1 in case of failure. 28685 */ 28686int 28687xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28688{ 28689 xmlSAXHandlerPtr *sax; 28690 void **user_data; 28691 28692 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28693 return(-1); 28694 plug->magic = 0; 28695 28696 xmlSchemaPostRun(plug->ctxt); 28697 /* restore the data */ 28698 sax = plug->user_sax_ptr; 28699 *sax = plug->user_sax; 28700 if (plug->user_sax != NULL) { 28701 user_data = plug->user_data_ptr; 28702 *user_data = plug->user_data; 28703 } 28704 28705 /* free and return */ 28706 xmlFree(plug); 28707 return(0); 28708} 28709 28710/** 28711 * xmlSchemaValidateSetLocator: 28712 * @vctxt: a schema validation context 28713 * @f: the locator function pointer 28714 * @ctxt: the locator context 28715 * 28716 * Allows to set a locator function to the validation context, 28717 * which will be used to provide file and line information since 28718 * those are not provided as part of the SAX validation flow 28719 * Setting @f to NULL disable the locator. 28720 */ 28721 28722void 28723xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt, 28724 xmlSchemaValidityLocatorFunc f, 28725 void *ctxt) 28726{ 28727 if (vctxt == NULL) return; 28728 vctxt->locFunc = f; 28729 vctxt->locCtxt = ctxt; 28730} 28731 28732/** 28733 * xmlSchemaValidateStreamLocator: 28734 * @ctx: the xmlTextReaderPtr used 28735 * @file: returned file information 28736 * @line: returned line information 28737 * 28738 * Internal locator function for the readers 28739 * 28740 * Returns 0 in case the Schema validation could be (des)activated and 28741 * -1 in case of error. 28742 */ 28743static int 28744xmlSchemaValidateStreamLocator(void *ctx, const char **file, 28745 unsigned long *line) { 28746 xmlParserCtxtPtr ctxt; 28747 28748 if ((ctx == NULL) || ((file == NULL) && (line == NULL))) 28749 return(-1); 28750 28751 if (file != NULL) 28752 *file = NULL; 28753 if (line != NULL) 28754 *line = 0; 28755 28756 ctxt = (xmlParserCtxtPtr) ctx; 28757 if (ctxt->input != NULL) { 28758 if (file != NULL) 28759 *file = ctxt->input->filename; 28760 if (line != NULL) 28761 *line = ctxt->input->line; 28762 return(0); 28763 } 28764 return(-1); 28765} 28766 28767/** 28768 * xmlSchemaValidateStream: 28769 * @ctxt: a schema validation context 28770 * @input: the input to use for reading the data 28771 * @enc: an optional encoding information 28772 * @sax: a SAX handler for the resulting events 28773 * @user_data: the context to provide to the SAX handler. 28774 * 28775 * Validate an input based on a flow of SAX event from the parser 28776 * and forward the events to the @sax handler with the provided @user_data 28777 * the user provided @sax handler must be a SAX2 one. 28778 * 28779 * Returns 0 if the document is schemas valid, a positive error code 28780 * number otherwise and -1 in case of internal or API error. 28781 */ 28782int 28783xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28784 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28785 xmlSAXHandlerPtr sax, void *user_data) 28786{ 28787 xmlSchemaSAXPlugPtr plug = NULL; 28788 xmlSAXHandlerPtr old_sax = NULL; 28789 xmlParserCtxtPtr pctxt = NULL; 28790 xmlParserInputPtr inputStream = NULL; 28791 int ret; 28792 28793 if ((ctxt == NULL) || (input == NULL)) 28794 return (-1); 28795 28796 /* 28797 * prepare the parser 28798 */ 28799 pctxt = xmlNewParserCtxt(); 28800 if (pctxt == NULL) 28801 return (-1); 28802 old_sax = pctxt->sax; 28803 pctxt->sax = sax; 28804 pctxt->userData = user_data; 28805#if 0 28806 if (options) 28807 xmlCtxtUseOptions(pctxt, options); 28808#endif 28809 pctxt->linenumbers = 1; 28810 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt); 28811 28812 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28813 if (inputStream == NULL) { 28814 ret = -1; 28815 goto done; 28816 } 28817 inputPush(pctxt, inputStream); 28818 ctxt->parserCtxt = pctxt; 28819 ctxt->input = input; 28820 28821 /* 28822 * Plug the validation and launch the parsing 28823 */ 28824 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28825 if (plug == NULL) { 28826 ret = -1; 28827 goto done; 28828 } 28829 ctxt->input = input; 28830 ctxt->enc = enc; 28831 ctxt->sax = pctxt->sax; 28832 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28833 ret = xmlSchemaVStart(ctxt); 28834 28835 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28836 ret = ctxt->parserCtxt->errNo; 28837 if (ret == 0) 28838 ret = 1; 28839 } 28840 28841done: 28842 ctxt->parserCtxt = NULL; 28843 ctxt->sax = NULL; 28844 ctxt->input = NULL; 28845 if (plug != NULL) { 28846 xmlSchemaSAXUnplug(plug); 28847 } 28848 /* cleanup */ 28849 if (pctxt != NULL) { 28850 pctxt->sax = old_sax; 28851 xmlFreeParserCtxt(pctxt); 28852 } 28853 return (ret); 28854} 28855 28856/** 28857 * xmlSchemaValidateFile: 28858 * @ctxt: a schema validation context 28859 * @filename: the URI of the instance 28860 * @options: a future set of options, currently unused 28861 * 28862 * Do a schemas validation of the given resource, it will use the 28863 * SAX streamable validation internally. 28864 * 28865 * Returns 0 if the document is valid, a positive error code 28866 * number otherwise and -1 in case of an internal or API error. 28867 */ 28868int 28869xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28870 const char * filename, 28871 int options ATTRIBUTE_UNUSED) 28872{ 28873 int ret; 28874 xmlParserInputBufferPtr input; 28875 28876 if ((ctxt == NULL) || (filename == NULL)) 28877 return (-1); 28878 28879 input = xmlParserInputBufferCreateFilename(filename, 28880 XML_CHAR_ENCODING_NONE); 28881 if (input == NULL) 28882 return (-1); 28883 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28884 NULL, NULL); 28885 return (ret); 28886} 28887 28888/** 28889 * xmlSchemaValidCtxtGetParserCtxt: 28890 * @ctxt: a schema validation context 28891 * 28892 * allow access to the parser context of the schema validation context 28893 * 28894 * Returns the parser context of the schema validation context or NULL 28895 * in case of error. 28896 */ 28897xmlParserCtxtPtr 28898xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28899{ 28900 if (ctxt == NULL) 28901 return(NULL); 28902 return (ctxt->parserCtxt); 28903} 28904 28905#define bottom_xmlschemas 28906#include "elfgcchack.h" 28907#endif /* LIBXML_SCHEMAS_ENABLED */ 28908