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 * - Eliminated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 48 /* To avoid EBCDIC trouble when parsing on zOS */ 49 #if defined(__MVS__) 50 #pragma convert("ISO8859-1") 51 #endif 52 53 #define IN_LIBXML 54 #include "libxml.h" 55 56 #ifdef LIBXML_SCHEMAS_ENABLED 57 58 #include <string.h> 59 #include <libxml/xmlmemory.h> 60 #include <libxml/parser.h> 61 #include <libxml/parserInternals.h> 62 #include <libxml/hash.h> 63 #include <libxml/uri.h> 64 #include <libxml/xmlschemas.h> 65 #include <libxml/schemasInternals.h> 66 #include <libxml/xmlschemastypes.h> 67 #include <libxml/xmlautomata.h> 68 #include <libxml/xmlregexp.h> 69 #include <libxml/dict.h> 70 #include <libxml/encoding.h> 71 #include <libxml/xmlIO.h> 72 #ifdef LIBXML_PATTERN_ENABLED 73 #include <libxml/pattern.h> 74 #endif 75 #ifdef LIBXML_READER_ENABLED 76 #include <libxml/xmlreader.h> 77 #endif 78 79 /* #define DEBUG 1 */ 80 81 /* #define DEBUG_CONTENT 1 */ 82 83 /* #define DEBUG_TYPE 1 */ 84 85 /* #define DEBUG_CONTENT_REGEXP 1 */ 86 87 /* #define DEBUG_AUTOMATA 1 */ 88 89 /* #define DEBUG_IDC */ 90 91 /* #define DEBUG_IDC_NODE_TABLE */ 92 93 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 94 95 #ifdef DEBUG_IDC 96 #ifndef DEBUG_IDC_NODE_TABLE 97 #define DEBUG_IDC_NODE_TABLE 98 #endif 99 #endif 100 101 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 102 103 #define ENABLE_REDEFINE 104 105 /* #define ENABLE_NAMED_LOCALS */ 106 107 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 108 109 #define DUMP_CONTENT_MODEL 110 111 #ifdef LIBXML_READER_ENABLED 112 /* #define XML_SCHEMA_READER_ENABLED */ 113 #endif 114 115 #define UNBOUNDED (1 << 30) 116 #define TODO \ 117 xmlGenericError(xmlGenericErrorContext, \ 118 "Unimplemented block at %s:%d\n", \ 119 __FILE__, __LINE__); 120 121 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 122 123 /* 124 * The XML Schemas namespaces 125 */ 126 static const xmlChar *xmlSchemaNs = (const xmlChar *) 127 "http://www.w3.org/2001/XMLSchema"; 128 129 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 130 "http://www.w3.org/2001/XMLSchema-instance"; 131 132 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 133 "http://www.w3.org/2000/xmlns/"; 134 135 /* 136 * Come casting macros. 137 */ 138 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 139 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 140 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 141 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 142 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 143 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 144 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 145 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 146 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 147 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 148 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 149 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 150 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 151 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 152 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 153 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 154 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 155 156 /* 157 * Macros to query common properties of components. 158 */ 159 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 160 161 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 162 /* 163 * Macros for element declarations. 164 */ 165 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 166 167 #define WXS_SUBST_HEAD(item) (item)->refDecl 168 /* 169 * Macros for attribute declarations. 170 */ 171 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 172 /* 173 * Macros for attribute uses. 174 */ 175 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl 176 177 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 178 179 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 180 181 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 182 /* 183 * Macros for attribute groups. 184 */ 185 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 186 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 187 /* 188 * Macros for particles. 189 */ 190 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 191 192 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 193 194 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 195 196 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 197 /* 198 * Macros for model groups definitions. 199 */ 200 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 201 /* 202 * Macros for model groups. 203 */ 204 #define WXS_IS_MODEL_GROUP(i) \ 205 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 206 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 207 ((i)->type == XML_SCHEMA_TYPE_ALL)) 208 209 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 210 /* 211 * Macros for schema buckets. 212 */ 213 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 214 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 215 216 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 217 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 218 219 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 220 221 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 222 /* 223 * Macros for complex/simple types. 224 */ 225 #define WXS_IS_ANYTYPE(i) \ 226 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 227 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 228 229 #define WXS_IS_COMPLEX(i) \ 230 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 231 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 232 233 #define WXS_IS_SIMPLE(item) \ 234 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 235 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 236 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 237 238 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 239 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 240 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 241 242 #define WXS_IS_RESTRICTION(t) \ 243 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 244 245 #define WXS_IS_EXTENSION(t) \ 246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 247 248 #define WXS_IS_TYPE_NOT_FIXED(i) \ 249 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 250 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 251 252 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 253 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 254 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 255 256 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 257 258 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 259 /* 260 * Macros for exclusively for complex types. 261 */ 262 #define WXS_HAS_COMPLEX_CONTENT(item) \ 263 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 264 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 265 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 266 267 #define WXS_HAS_SIMPLE_CONTENT(item) \ 268 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 269 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 270 271 #define WXS_HAS_MIXED_CONTENT(item) \ 272 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 273 274 #define WXS_EMPTIABLE(t) \ 275 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 276 277 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 278 279 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 280 281 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 282 /* 283 * Macros for exclusively for simple types. 284 */ 285 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 286 287 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 288 289 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 290 291 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 292 /* 293 * Misc parser context macros. 294 */ 295 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 296 297 #define WXS_HAS_BUCKETS(ctx) \ 298 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 299 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 300 301 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 302 303 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 304 305 #define WXS_SCHEMA(ctx) (ctx)->schema 306 307 #define WXS_ADD_LOCAL(ctx, item) \ 308 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 309 310 #define WXS_ADD_GLOBAL(ctx, item) \ 311 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 312 313 #define WXS_ADD_PENDING(ctx, item) \ 314 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 315 /* 316 * xmlSchemaItemList macros. 317 */ 318 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 319 /* 320 * Misc macros. 321 */ 322 #define IS_SCHEMA(node, type) \ 323 ((node != NULL) && (node->ns != NULL) && \ 324 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 325 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 326 327 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 328 329 /* 330 * Since we put the default/fixed values into the dict, we can 331 * use pointer comparison for those values. 332 * REMOVED: (xmlStrEqual((v1), (v2))) 333 */ 334 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 335 336 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 337 338 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 339 340 #define HFAILURE if (res == -1) goto exit_failure; 341 342 #define HERROR if (res != 0) goto exit_error; 343 344 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 345 /* 346 * Some flags used for various schema constraints. 347 */ 348 #define SUBSET_RESTRICTION 1<<0 349 #define SUBSET_EXTENSION 1<<1 350 #define SUBSET_SUBSTITUTION 1<<2 351 #define SUBSET_LIST 1<<3 352 #define SUBSET_UNION 1<<4 353 354 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 355 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 356 357 typedef struct _xmlSchemaItemList xmlSchemaItemList; 358 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 359 struct _xmlSchemaItemList { 360 void **items; /* used for dynamic addition of schemata */ 361 int nbItems; /* used for dynamic addition of schemata */ 362 int sizeItems; /* used for dynamic addition of schemata */ 363 }; 364 365 #define XML_SCHEMA_CTXT_PARSER 1 366 #define XML_SCHEMA_CTXT_VALIDATOR 2 367 368 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 369 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 370 struct _xmlSchemaAbstractCtxt { 371 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 372 void *dummy; /* Fix alignment issues */ 373 }; 374 375 typedef struct _xmlSchemaBucket xmlSchemaBucket; 376 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 377 378 #define XML_SCHEMA_SCHEMA_MAIN 0 379 #define XML_SCHEMA_SCHEMA_IMPORT 1 380 #define XML_SCHEMA_SCHEMA_INCLUDE 2 381 #define XML_SCHEMA_SCHEMA_REDEFINE 3 382 383 /** 384 * xmlSchemaSchemaRelation: 385 * 386 * Used to create a graph of schema relationships. 387 */ 388 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 389 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 390 struct _xmlSchemaSchemaRelation { 391 xmlSchemaSchemaRelationPtr next; 392 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 393 const xmlChar *importNamespace; 394 xmlSchemaBucketPtr bucket; 395 }; 396 397 #define XML_SCHEMA_BUCKET_MARKED 1<<0 398 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 399 400 struct _xmlSchemaBucket { 401 int type; 402 int flags; 403 const xmlChar *schemaLocation; 404 const xmlChar *origTargetNamespace; 405 const xmlChar *targetNamespace; 406 xmlDocPtr doc; 407 xmlSchemaSchemaRelationPtr relations; 408 int located; 409 int parsed; 410 int imported; 411 int preserveDoc; 412 xmlSchemaItemListPtr globals; /* Global components. */ 413 xmlSchemaItemListPtr locals; /* Local components. */ 414 }; 415 416 /** 417 * xmlSchemaImport: 418 * (extends xmlSchemaBucket) 419 * 420 * Reflects a schema. Holds some information 421 * about the schema and its toplevel components. Duplicate 422 * toplevel components are not checked at this level. 423 */ 424 typedef struct _xmlSchemaImport xmlSchemaImport; 425 typedef xmlSchemaImport *xmlSchemaImportPtr; 426 struct _xmlSchemaImport { 427 int type; /* Main OR import OR include. */ 428 int flags; 429 const xmlChar *schemaLocation; /* The URI of the schema document. */ 430 /* For chameleon includes, @origTargetNamespace will be NULL */ 431 const xmlChar *origTargetNamespace; 432 /* 433 * For chameleon includes, @targetNamespace will be the 434 * targetNamespace of the including schema. 435 */ 436 const xmlChar *targetNamespace; 437 xmlDocPtr doc; /* The schema node-tree. */ 438 /* @relations will hold any included/imported/redefined schemas. */ 439 xmlSchemaSchemaRelationPtr relations; 440 int located; 441 int parsed; 442 int imported; 443 int preserveDoc; 444 xmlSchemaItemListPtr globals; 445 xmlSchemaItemListPtr locals; 446 /* The imported schema. */ 447 xmlSchemaPtr schema; 448 }; 449 450 /* 451 * (extends xmlSchemaBucket) 452 */ 453 typedef struct _xmlSchemaInclude xmlSchemaInclude; 454 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 455 struct _xmlSchemaInclude { 456 int type; 457 int flags; 458 const xmlChar *schemaLocation; 459 const xmlChar *origTargetNamespace; 460 const xmlChar *targetNamespace; 461 xmlDocPtr doc; 462 xmlSchemaSchemaRelationPtr relations; 463 int located; 464 int parsed; 465 int imported; 466 int preserveDoc; 467 xmlSchemaItemListPtr globals; /* Global components. */ 468 xmlSchemaItemListPtr locals; /* Local components. */ 469 470 /* The owning main or import schema bucket. */ 471 xmlSchemaImportPtr ownerImport; 472 }; 473 474 /** 475 * xmlSchemaBasicItem: 476 * 477 * The abstract base type for schema components. 478 */ 479 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 480 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 481 struct _xmlSchemaBasicItem { 482 xmlSchemaTypeType type; 483 void *dummy; /* Fix alignment issues */ 484 }; 485 486 /** 487 * xmlSchemaAnnotItem: 488 * 489 * The abstract base type for annotated schema components. 490 * (Extends xmlSchemaBasicItem) 491 */ 492 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 493 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 494 struct _xmlSchemaAnnotItem { 495 xmlSchemaTypeType type; 496 xmlSchemaAnnotPtr annot; 497 }; 498 499 /** 500 * xmlSchemaTreeItem: 501 * 502 * The abstract base type for tree-like structured schema components. 503 * (Extends xmlSchemaAnnotItem) 504 */ 505 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 506 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 507 struct _xmlSchemaTreeItem { 508 xmlSchemaTypeType type; 509 xmlSchemaAnnotPtr annot; 510 xmlSchemaTreeItemPtr next; 511 xmlSchemaTreeItemPtr children; 512 }; 513 514 515 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 516 /** 517 * xmlSchemaAttributeUsePtr: 518 * 519 * The abstract base type for tree-like structured schema components. 520 * (Extends xmlSchemaTreeItem) 521 */ 522 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 523 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 524 struct _xmlSchemaAttributeUse { 525 xmlSchemaTypeType type; 526 xmlSchemaAnnotPtr annot; 527 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 528 /* 529 * The attr. decl. OR a QName-ref. to an attr. decl. OR 530 * a QName-ref. to an attribute group definition. 531 */ 532 xmlSchemaAttributePtr attrDecl; 533 534 int flags; 535 xmlNodePtr node; 536 int occurs; /* required, optional */ 537 const xmlChar * defValue; 538 xmlSchemaValPtr defVal; 539 }; 540 541 /** 542 * xmlSchemaAttributeUseProhibPtr: 543 * 544 * A helper component to reflect attribute prohibitions. 545 * (Extends xmlSchemaBasicItem) 546 */ 547 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 548 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 549 struct _xmlSchemaAttributeUseProhib { 550 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 551 xmlNodePtr node; 552 const xmlChar *name; 553 const xmlChar *targetNamespace; 554 int isRef; 555 }; 556 557 /** 558 * xmlSchemaRedef: 559 */ 560 typedef struct _xmlSchemaRedef xmlSchemaRedef; 561 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 562 struct _xmlSchemaRedef { 563 xmlSchemaRedefPtr next; 564 xmlSchemaBasicItemPtr item; /* The redefining component. */ 565 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 566 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 567 const xmlChar *refName; /* The name of the to-be-redefined component. */ 568 const xmlChar *refTargetNs; /* The target namespace of the 569 to-be-redefined comp. */ 570 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 571 }; 572 573 /** 574 * xmlSchemaConstructionCtxt: 575 */ 576 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 577 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 578 struct _xmlSchemaConstructionCtxt { 579 xmlSchemaPtr mainSchema; /* The main schema. */ 580 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 581 xmlDictPtr dict; 582 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 583 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 584 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 585 xmlSchemaItemListPtr pending; /* All Components of all schemas that 586 need to be fixed. */ 587 xmlHashTablePtr substGroups; 588 xmlSchemaRedefPtr redefs; 589 xmlSchemaRedefPtr lastRedef; 590 }; 591 592 #define XML_SCHEMAS_PARSE_ERROR 1 593 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 594 595 struct _xmlSchemaParserCtxt { 596 int type; 597 void *errCtxt; /* user specific error context */ 598 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 599 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 600 int err; 601 int nberrors; 602 xmlStructuredErrorFunc serror; 603 604 xmlSchemaConstructionCtxtPtr constructor; 605 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 606 607 /* xmlSchemaPtr topschema; */ 608 /* xmlHashTablePtr namespaces; */ 609 610 xmlSchemaPtr schema; /* The main schema in use */ 611 int counter; 612 613 const xmlChar *URL; 614 xmlDocPtr doc; 615 int preserve; /* Whether the doc should be freed */ 616 617 const char *buffer; 618 int size; 619 620 /* 621 * Used to build complex element content models 622 */ 623 xmlAutomataPtr am; 624 xmlAutomataStatePtr start; 625 xmlAutomataStatePtr end; 626 xmlAutomataStatePtr state; 627 628 xmlDictPtr dict; /* dictionary for interned string names */ 629 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 630 int options; 631 xmlSchemaValidCtxtPtr vctxt; 632 int isS4S; 633 int isRedefine; 634 int xsiAssemble; 635 int stop; /* If the parser should stop; i.e. a critical error. */ 636 const xmlChar *targetNamespace; 637 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 638 639 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 640 int redefCounter; /* Used for redefinitions. */ 641 xmlSchemaItemListPtr attrProhibs; 642 }; 643 644 /** 645 * xmlSchemaQNameRef: 646 * 647 * A component reference item (not a schema component) 648 * (Extends xmlSchemaBasicItem) 649 */ 650 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 651 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 652 struct _xmlSchemaQNameRef { 653 xmlSchemaTypeType type; 654 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 655 xmlSchemaTypeType itemType; 656 const xmlChar *name; 657 const xmlChar *targetNamespace; 658 xmlNodePtr node; 659 }; 660 661 /** 662 * xmlSchemaParticle: 663 * 664 * A particle component. 665 * (Extends xmlSchemaTreeItem) 666 */ 667 typedef struct _xmlSchemaParticle xmlSchemaParticle; 668 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 669 struct _xmlSchemaParticle { 670 xmlSchemaTypeType type; 671 xmlSchemaAnnotPtr annot; 672 xmlSchemaTreeItemPtr next; /* next particle */ 673 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 674 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 675 etc.) */ 676 int minOccurs; 677 int maxOccurs; 678 xmlNodePtr node; 679 }; 680 681 /** 682 * xmlSchemaModelGroup: 683 * 684 * A model group component. 685 * (Extends xmlSchemaTreeItem) 686 */ 687 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 688 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 689 struct _xmlSchemaModelGroup { 690 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 691 xmlSchemaAnnotPtr annot; 692 xmlSchemaTreeItemPtr next; /* not used */ 693 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 694 xmlNodePtr node; 695 }; 696 697 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 698 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 699 /** 700 * xmlSchemaModelGroupDef: 701 * 702 * A model group definition component. 703 * (Extends xmlSchemaTreeItem) 704 */ 705 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 706 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 707 struct _xmlSchemaModelGroupDef { 708 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 709 xmlSchemaAnnotPtr annot; 710 xmlSchemaTreeItemPtr next; /* not used */ 711 xmlSchemaTreeItemPtr children; /* the "model group" */ 712 const xmlChar *name; 713 const xmlChar *targetNamespace; 714 xmlNodePtr node; 715 int flags; 716 }; 717 718 typedef struct _xmlSchemaIDC xmlSchemaIDC; 719 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 720 721 /** 722 * xmlSchemaIDCSelect: 723 * 724 * The identity-constraint "field" and "selector" item, holding the 725 * XPath expression. 726 */ 727 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 728 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 729 struct _xmlSchemaIDCSelect { 730 xmlSchemaIDCSelectPtr next; 731 xmlSchemaIDCPtr idc; 732 int index; /* an index position if significant for IDC key-sequences */ 733 const xmlChar *xpath; /* the XPath expression */ 734 void *xpathComp; /* the compiled XPath expression */ 735 }; 736 737 /** 738 * xmlSchemaIDC: 739 * 740 * The identity-constraint definition component. 741 * (Extends xmlSchemaAnnotItem) 742 */ 743 744 struct _xmlSchemaIDC { 745 xmlSchemaTypeType type; 746 xmlSchemaAnnotPtr annot; 747 xmlSchemaIDCPtr next; 748 xmlNodePtr node; 749 const xmlChar *name; 750 const xmlChar *targetNamespace; 751 xmlSchemaIDCSelectPtr selector; 752 xmlSchemaIDCSelectPtr fields; 753 int nbFields; 754 xmlSchemaQNameRefPtr ref; 755 }; 756 757 /** 758 * xmlSchemaIDCAug: 759 * 760 * The augmented IDC information used for validation. 761 */ 762 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 763 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 764 struct _xmlSchemaIDCAug { 765 xmlSchemaIDCAugPtr next; /* next in a list */ 766 xmlSchemaIDCPtr def; /* the IDC definition */ 767 int keyrefDepth; /* the lowest tree level to which IDC 768 tables need to be bubbled upwards */ 769 }; 770 771 /** 772 * xmlSchemaPSVIIDCKeySequence: 773 * 774 * The key sequence of a node table item. 775 */ 776 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 777 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 778 struct _xmlSchemaPSVIIDCKey { 779 xmlSchemaTypePtr type; 780 xmlSchemaValPtr val; 781 }; 782 783 /** 784 * xmlSchemaPSVIIDCNode: 785 * 786 * The node table item of a node table. 787 */ 788 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 789 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 790 struct _xmlSchemaPSVIIDCNode { 791 xmlNodePtr node; 792 xmlSchemaPSVIIDCKeyPtr *keys; 793 int nodeLine; 794 int nodeQNameID; 795 796 }; 797 798 /** 799 * xmlSchemaPSVIIDCBinding: 800 * 801 * The identity-constraint binding item of the [identity-constraint table]. 802 */ 803 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 804 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 805 struct _xmlSchemaPSVIIDCBinding { 806 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 807 xmlSchemaIDCPtr definition; /* the IDC definition */ 808 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 809 int nbNodes; /* number of entries in the node table */ 810 int sizeNodes; /* size of the node table */ 811 xmlSchemaItemListPtr dupls; 812 }; 813 814 815 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 816 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 817 818 #define XPATH_STATE_OBJ_MATCHES -2 819 #define XPATH_STATE_OBJ_BLOCKED -3 820 821 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 822 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 823 824 /** 825 * xmlSchemaIDCStateObj: 826 * 827 * The state object used to evaluate XPath expressions. 828 */ 829 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 830 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 831 struct _xmlSchemaIDCStateObj { 832 int type; 833 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 834 int depth; /* depth of creation */ 835 int *history; /* list of (depth, state-id) tuples */ 836 int nbHistory; 837 int sizeHistory; 838 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 839 matcher */ 840 xmlSchemaIDCSelectPtr sel; 841 void *xpathCtxt; 842 }; 843 844 #define IDC_MATCHER 0 845 846 /** 847 * xmlSchemaIDCMatcher: 848 * 849 * Used to evaluate IDC selectors (and fields). 850 */ 851 struct _xmlSchemaIDCMatcher { 852 int type; 853 int depth; /* the tree depth at creation time */ 854 xmlSchemaIDCMatcherPtr next; /* next in the list */ 855 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 856 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 857 int idcType; 858 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 859 elements */ 860 int sizeKeySeqs; 861 xmlSchemaItemListPtr targets; /* list of target-node 862 (xmlSchemaPSVIIDCNodePtr) entries */ 863 }; 864 865 /* 866 * Element info flags. 867 */ 868 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 869 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 870 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 871 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 872 873 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 874 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 875 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 876 877 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 878 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 879 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 880 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 881 882 /** 883 * xmlSchemaNodeInfo: 884 * 885 * Holds information of an element node. 886 */ 887 struct _xmlSchemaNodeInfo { 888 int nodeType; 889 xmlNodePtr node; 890 int nodeLine; 891 const xmlChar *localName; 892 const xmlChar *nsName; 893 const xmlChar *value; 894 xmlSchemaValPtr val; /* the pre-computed value if any */ 895 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 896 897 int flags; /* combination of node info flags */ 898 899 int valNeeded; 900 int normVal; 901 902 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 903 int depth; 904 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 905 for the scope element*/ 906 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 907 element */ 908 xmlRegExecCtxtPtr regexCtxt; 909 910 const xmlChar **nsBindings; /* Namespace bindings on this element */ 911 int nbNsBindings; 912 int sizeNsBindings; 913 914 int hasKeyrefs; 915 int appliedXPath; /* Indicates that an XPath has been applied. */ 916 }; 917 918 #define XML_SCHEMAS_ATTR_UNKNOWN 1 919 #define XML_SCHEMAS_ATTR_ASSESSED 2 920 #define XML_SCHEMAS_ATTR_PROHIBITED 3 921 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 922 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 923 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 924 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 925 #define XML_SCHEMAS_ATTR_DEFAULT 8 926 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 927 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 928 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 929 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 930 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 931 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 932 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 933 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 934 #define XML_SCHEMAS_ATTR_META 17 935 /* 936 * @metaType values of xmlSchemaAttrInfo. 937 */ 938 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 939 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 940 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 941 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 942 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 943 944 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 945 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 946 struct _xmlSchemaAttrInfo { 947 int nodeType; 948 xmlNodePtr node; 949 int nodeLine; 950 const xmlChar *localName; 951 const xmlChar *nsName; 952 const xmlChar *value; 953 xmlSchemaValPtr val; /* the pre-computed value if any */ 954 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 955 int flags; /* combination of node info flags */ 956 957 xmlSchemaAttributePtr decl; /* the attribute declaration */ 958 xmlSchemaAttributeUsePtr use; /* the attribute use */ 959 int state; 960 int metaType; 961 const xmlChar *vcValue; /* the value constraint value */ 962 xmlSchemaNodeInfoPtr parent; 963 }; 964 965 966 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 967 /** 968 * xmlSchemaValidCtxt: 969 * 970 * A Schemas validation context 971 */ 972 struct _xmlSchemaValidCtxt { 973 int type; 974 void *errCtxt; /* user specific data block */ 975 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 976 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 977 xmlStructuredErrorFunc serror; 978 979 xmlSchemaPtr schema; /* The schema in use */ 980 xmlDocPtr doc; 981 xmlParserInputBufferPtr input; 982 xmlCharEncoding enc; 983 xmlSAXHandlerPtr sax; 984 xmlParserCtxtPtr parserCtxt; 985 void *user_data; /* TODO: What is this for? */ 986 char *filename; 987 988 int err; 989 int nberrors; 990 991 xmlNodePtr node; 992 xmlNodePtr cur; 993 /* xmlSchemaTypePtr type; */ 994 995 xmlRegExecCtxtPtr regexp; 996 xmlSchemaValPtr value; 997 998 int valueWS; 999 int options; 1000 xmlNodePtr validationRoot; 1001 xmlSchemaParserCtxtPtr pctxt; 1002 int xsiAssemble; 1003 1004 int depth; 1005 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 1006 int sizeElemInfos; 1007 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1008 1009 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1010 1011 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1012 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1013 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1014 1015 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1016 int nbIdcNodes; 1017 int sizeIdcNodes; 1018 1019 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1020 int nbIdcKeys; 1021 int sizeIdcKeys; 1022 1023 int flags; 1024 1025 xmlDictPtr dict; 1026 1027 #ifdef LIBXML_READER_ENABLED 1028 xmlTextReaderPtr reader; 1029 #endif 1030 1031 xmlSchemaAttrInfoPtr *attrInfos; 1032 int nbAttrInfos; 1033 int sizeAttrInfos; 1034 1035 int skipDepth; 1036 xmlSchemaItemListPtr nodeQNames; 1037 int hasKeyrefs; 1038 int createIDCNodeTables; 1039 int psviExposeIDCNodeTables; 1040 1041 /* Locator for error reporting in streaming mode */ 1042 xmlSchemaValidityLocatorFunc locFunc; 1043 void *locCtxt; 1044 }; 1045 1046 /** 1047 * xmlSchemaSubstGroup: 1048 * 1049 * 1050 */ 1051 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1052 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1053 struct _xmlSchemaSubstGroup { 1054 xmlSchemaElementPtr head; 1055 xmlSchemaItemListPtr members; 1056 }; 1057 1058 /************************************************************************ 1059 * * 1060 * Some predeclarations * 1061 * * 1062 ************************************************************************/ 1063 1064 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1065 xmlSchemaPtr schema, 1066 xmlNodePtr node); 1067 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1068 xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070 static int 1071 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1072 xmlSchemaAbstractCtxtPtr ctxt); 1073 static const xmlChar * 1074 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1075 static int 1076 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1077 xmlNodePtr node); 1078 static int 1079 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1080 xmlSchemaParserCtxtPtr ctxt); 1081 static void 1082 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1083 static xmlSchemaWhitespaceValueType 1084 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1085 static xmlSchemaTreeItemPtr 1086 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1087 xmlNodePtr node, xmlSchemaTypeType type, 1088 int withParticle); 1089 static const xmlChar * 1090 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1091 static xmlSchemaTypeLinkPtr 1092 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1093 static void 1094 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1095 const char *funcName, 1096 const char *message) LIBXML_ATTR_FORMAT(3,0); 1097 static int 1098 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1099 xmlSchemaTypePtr type, 1100 xmlSchemaTypePtr baseType, 1101 int subset); 1102 static void 1103 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1104 xmlSchemaParserCtxtPtr ctxt); 1105 static void 1106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1107 static xmlSchemaQNameRefPtr 1108 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1109 xmlSchemaPtr schema, 1110 xmlNodePtr node); 1111 1112 /************************************************************************ 1113 * * 1114 * Helper functions * 1115 * * 1116 ************************************************************************/ 1117 1118 /** 1119 * xmlSchemaItemTypeToStr: 1120 * @type: the type of the schema item 1121 * 1122 * Returns the component name of a schema item. 1123 */ 1124 static const xmlChar * 1125 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1126 { 1127 switch (type) { 1128 case XML_SCHEMA_TYPE_BASIC: 1129 return(BAD_CAST "simple type definition"); 1130 case XML_SCHEMA_TYPE_SIMPLE: 1131 return(BAD_CAST "simple type definition"); 1132 case XML_SCHEMA_TYPE_COMPLEX: 1133 return(BAD_CAST "complex type definition"); 1134 case XML_SCHEMA_TYPE_ELEMENT: 1135 return(BAD_CAST "element declaration"); 1136 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1137 return(BAD_CAST "attribute use"); 1138 case XML_SCHEMA_TYPE_ATTRIBUTE: 1139 return(BAD_CAST "attribute declaration"); 1140 case XML_SCHEMA_TYPE_GROUP: 1141 return(BAD_CAST "model group definition"); 1142 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1143 return(BAD_CAST "attribute group definition"); 1144 case XML_SCHEMA_TYPE_NOTATION: 1145 return(BAD_CAST "notation declaration"); 1146 case XML_SCHEMA_TYPE_SEQUENCE: 1147 return(BAD_CAST "model group (sequence)"); 1148 case XML_SCHEMA_TYPE_CHOICE: 1149 return(BAD_CAST "model group (choice)"); 1150 case XML_SCHEMA_TYPE_ALL: 1151 return(BAD_CAST "model group (all)"); 1152 case XML_SCHEMA_TYPE_PARTICLE: 1153 return(BAD_CAST "particle"); 1154 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1155 return(BAD_CAST "unique identity-constraint"); 1156 /* return(BAD_CAST "IDC (unique)"); */ 1157 case XML_SCHEMA_TYPE_IDC_KEY: 1158 return(BAD_CAST "key identity-constraint"); 1159 /* return(BAD_CAST "IDC (key)"); */ 1160 case XML_SCHEMA_TYPE_IDC_KEYREF: 1161 return(BAD_CAST "keyref identity-constraint"); 1162 /* return(BAD_CAST "IDC (keyref)"); */ 1163 case XML_SCHEMA_TYPE_ANY: 1164 return(BAD_CAST "wildcard (any)"); 1165 case XML_SCHEMA_EXTRA_QNAMEREF: 1166 return(BAD_CAST "[helper component] QName reference"); 1167 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1168 return(BAD_CAST "[helper component] attribute use prohibition"); 1169 default: 1170 return(BAD_CAST "Not a schema component"); 1171 } 1172 } 1173 1174 /** 1175 * xmlSchemaGetComponentTypeStr: 1176 * @type: the type of the schema item 1177 * 1178 * Returns the component name of a schema item. 1179 */ 1180 static const xmlChar * 1181 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1182 { 1183 switch (item->type) { 1184 case XML_SCHEMA_TYPE_BASIC: 1185 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1186 return(BAD_CAST "complex type definition"); 1187 else 1188 return(BAD_CAST "simple type definition"); 1189 default: 1190 return(xmlSchemaItemTypeToStr(item->type)); 1191 } 1192 } 1193 1194 /** 1195 * xmlSchemaGetComponentNode: 1196 * @item: a schema component 1197 * 1198 * Returns node associated with the schema component. 1199 * NOTE that such a node need not be available; plus, a component's 1200 * node need not to reflect the component directly, since there is no 1201 * one-to-one relationship between the XML Schema representation and 1202 * the component representation. 1203 */ 1204 static xmlNodePtr 1205 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1206 { 1207 switch (item->type) { 1208 case XML_SCHEMA_TYPE_ELEMENT: 1209 return (((xmlSchemaElementPtr) item)->node); 1210 case XML_SCHEMA_TYPE_ATTRIBUTE: 1211 return (((xmlSchemaAttributePtr) item)->node); 1212 case XML_SCHEMA_TYPE_COMPLEX: 1213 case XML_SCHEMA_TYPE_SIMPLE: 1214 return (((xmlSchemaTypePtr) item)->node); 1215 case XML_SCHEMA_TYPE_ANY: 1216 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1217 return (((xmlSchemaWildcardPtr) item)->node); 1218 case XML_SCHEMA_TYPE_PARTICLE: 1219 return (((xmlSchemaParticlePtr) item)->node); 1220 case XML_SCHEMA_TYPE_SEQUENCE: 1221 case XML_SCHEMA_TYPE_CHOICE: 1222 case XML_SCHEMA_TYPE_ALL: 1223 return (((xmlSchemaModelGroupPtr) item)->node); 1224 case XML_SCHEMA_TYPE_GROUP: 1225 return (((xmlSchemaModelGroupDefPtr) item)->node); 1226 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1227 return (((xmlSchemaAttributeGroupPtr) item)->node); 1228 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1229 case XML_SCHEMA_TYPE_IDC_KEY: 1230 case XML_SCHEMA_TYPE_IDC_KEYREF: 1231 return (((xmlSchemaIDCPtr) item)->node); 1232 case XML_SCHEMA_EXTRA_QNAMEREF: 1233 return(((xmlSchemaQNameRefPtr) item)->node); 1234 /* TODO: What to do with NOTATIONs? 1235 case XML_SCHEMA_TYPE_NOTATION: 1236 return (((xmlSchemaNotationPtr) item)->node); 1237 */ 1238 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1239 return (((xmlSchemaAttributeUsePtr) item)->node); 1240 default: 1241 return (NULL); 1242 } 1243 } 1244 1245 #if 0 1246 /** 1247 * xmlSchemaGetNextComponent: 1248 * @item: a schema component 1249 * 1250 * Returns the next sibling of the schema component. 1251 */ 1252 static xmlSchemaBasicItemPtr 1253 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1254 { 1255 switch (item->type) { 1256 case XML_SCHEMA_TYPE_ELEMENT: 1257 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1258 case XML_SCHEMA_TYPE_ATTRIBUTE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1260 case XML_SCHEMA_TYPE_COMPLEX: 1261 case XML_SCHEMA_TYPE_SIMPLE: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1263 case XML_SCHEMA_TYPE_ANY: 1264 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_PARTICLE: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1268 case XML_SCHEMA_TYPE_SEQUENCE: 1269 case XML_SCHEMA_TYPE_CHOICE: 1270 case XML_SCHEMA_TYPE_ALL: 1271 return (NULL); 1272 case XML_SCHEMA_TYPE_GROUP: 1273 return (NULL); 1274 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1275 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1276 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1277 case XML_SCHEMA_TYPE_IDC_KEY: 1278 case XML_SCHEMA_TYPE_IDC_KEYREF: 1279 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1280 default: 1281 return (NULL); 1282 } 1283 } 1284 #endif 1285 1286 1287 /** 1288 * xmlSchemaFormatQName: 1289 * @buf: the string buffer 1290 * @namespaceName: the namespace name 1291 * @localName: the local name 1292 * 1293 * Returns the given QName in the format "{namespaceName}localName" or 1294 * just "localName" if @namespaceName is NULL. 1295 * 1296 * Returns the localName if @namespaceName is NULL, a formatted 1297 * string otherwise. 1298 */ 1299 static const xmlChar* 1300 xmlSchemaFormatQName(xmlChar **buf, 1301 const xmlChar *namespaceName, 1302 const xmlChar *localName) 1303 { 1304 FREE_AND_NULL(*buf) 1305 if (namespaceName != NULL) { 1306 *buf = xmlStrdup(BAD_CAST "{"); 1307 *buf = xmlStrcat(*buf, namespaceName); 1308 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1309 } 1310 if (localName != NULL) { 1311 if (namespaceName == NULL) 1312 return(localName); 1313 *buf = xmlStrcat(*buf, localName); 1314 } else { 1315 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1316 } 1317 return ((const xmlChar *) *buf); 1318 } 1319 1320 static const xmlChar* 1321 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1322 { 1323 if (ns != NULL) 1324 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1325 else 1326 return (xmlSchemaFormatQName(buf, NULL, localName)); 1327 } 1328 1329 static const xmlChar * 1330 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1331 { 1332 switch (item->type) { 1333 case XML_SCHEMA_TYPE_ELEMENT: 1334 return (((xmlSchemaElementPtr) item)->name); 1335 case XML_SCHEMA_TYPE_ATTRIBUTE: 1336 return (((xmlSchemaAttributePtr) item)->name); 1337 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1338 return (((xmlSchemaAttributeGroupPtr) item)->name); 1339 case XML_SCHEMA_TYPE_BASIC: 1340 case XML_SCHEMA_TYPE_SIMPLE: 1341 case XML_SCHEMA_TYPE_COMPLEX: 1342 return (((xmlSchemaTypePtr) item)->name); 1343 case XML_SCHEMA_TYPE_GROUP: 1344 return (((xmlSchemaModelGroupDefPtr) item)->name); 1345 case XML_SCHEMA_TYPE_IDC_KEY: 1346 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1347 case XML_SCHEMA_TYPE_IDC_KEYREF: 1348 return (((xmlSchemaIDCPtr) item)->name); 1349 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1350 if (WXS_ATTRUSE_DECL(item) != NULL) { 1351 return(xmlSchemaGetComponentName( 1352 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1353 } else 1354 return(NULL); 1355 case XML_SCHEMA_EXTRA_QNAMEREF: 1356 return (((xmlSchemaQNameRefPtr) item)->name); 1357 case XML_SCHEMA_TYPE_NOTATION: 1358 return (((xmlSchemaNotationPtr) item)->name); 1359 default: 1360 /* 1361 * Other components cannot have names. 1362 */ 1363 break; 1364 } 1365 return (NULL); 1366 } 1367 1368 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1369 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1370 /* 1371 static const xmlChar * 1372 xmlSchemaGetQNameRefName(void *ref) 1373 { 1374 return(((xmlSchemaQNameRefPtr) ref)->name); 1375 } 1376 1377 static const xmlChar * 1378 xmlSchemaGetQNameRefTargetNs(void *ref) 1379 { 1380 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1381 } 1382 */ 1383 1384 static const xmlChar * 1385 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1386 { 1387 switch (item->type) { 1388 case XML_SCHEMA_TYPE_ELEMENT: 1389 return (((xmlSchemaElementPtr) item)->targetNamespace); 1390 case XML_SCHEMA_TYPE_ATTRIBUTE: 1391 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1393 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1394 case XML_SCHEMA_TYPE_BASIC: 1395 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1396 case XML_SCHEMA_TYPE_SIMPLE: 1397 case XML_SCHEMA_TYPE_COMPLEX: 1398 return (((xmlSchemaTypePtr) item)->targetNamespace); 1399 case XML_SCHEMA_TYPE_GROUP: 1400 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_IDC_KEY: 1402 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1403 case XML_SCHEMA_TYPE_IDC_KEYREF: 1404 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1405 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1406 if (WXS_ATTRUSE_DECL(item) != NULL) { 1407 return(xmlSchemaGetComponentTargetNs( 1408 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1409 } 1410 /* TODO: Will returning NULL break something? */ 1411 break; 1412 case XML_SCHEMA_EXTRA_QNAMEREF: 1413 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1414 case XML_SCHEMA_TYPE_NOTATION: 1415 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1416 default: 1417 /* 1418 * Other components cannot have names. 1419 */ 1420 break; 1421 } 1422 return (NULL); 1423 } 1424 1425 static const xmlChar* 1426 xmlSchemaGetComponentQName(xmlChar **buf, 1427 void *item) 1428 { 1429 return (xmlSchemaFormatQName(buf, 1430 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1431 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1432 } 1433 1434 static const xmlChar* 1435 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1436 { 1437 xmlChar *str = NULL; 1438 1439 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1440 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1441 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1442 (xmlSchemaBasicItemPtr) item)); 1443 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1444 FREE_AND_NULL(str); 1445 return(*buf); 1446 } 1447 1448 static const xmlChar* 1449 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1450 { 1451 return(xmlSchemaGetComponentDesignation(buf, idc)); 1452 } 1453 1454 /** 1455 * xmlSchemaWildcardPCToString: 1456 * @pc: the type of processContents 1457 * 1458 * Returns a string representation of the type of 1459 * processContents. 1460 */ 1461 static const xmlChar * 1462 xmlSchemaWildcardPCToString(int pc) 1463 { 1464 switch (pc) { 1465 case XML_SCHEMAS_ANY_SKIP: 1466 return (BAD_CAST "skip"); 1467 case XML_SCHEMAS_ANY_LAX: 1468 return (BAD_CAST "lax"); 1469 case XML_SCHEMAS_ANY_STRICT: 1470 return (BAD_CAST "strict"); 1471 default: 1472 return (BAD_CAST "invalid process contents"); 1473 } 1474 } 1475 1476 /** 1477 * xmlSchemaGetCanonValueWhtspExt: 1478 * @val: the precomputed value 1479 * @retValue: the returned value 1480 * @ws: the whitespace type of the value 1481 * 1482 * Get a the canonical representation of the value. 1483 * The caller has to free the returned retValue. 1484 * 1485 * Returns 0 if the value could be built and -1 in case of 1486 * API errors or if the value type is not supported yet. 1487 */ 1488 static int 1489 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1490 xmlSchemaWhitespaceValueType ws, 1491 xmlChar **retValue) 1492 { 1493 int list; 1494 xmlSchemaValType valType; 1495 const xmlChar *value, *value2 = NULL; 1496 1497 1498 if ((retValue == NULL) || (val == NULL)) 1499 return (-1); 1500 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1501 *retValue = NULL; 1502 do { 1503 value = NULL; 1504 valType = xmlSchemaGetValType(val); 1505 switch (valType) { 1506 case XML_SCHEMAS_STRING: 1507 case XML_SCHEMAS_NORMSTRING: 1508 case XML_SCHEMAS_ANYSIMPLETYPE: 1509 value = xmlSchemaValueGetAsString(val); 1510 if (value != NULL) { 1511 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1512 value2 = xmlSchemaCollapseString(value); 1513 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1514 value2 = xmlSchemaWhiteSpaceReplace(value); 1515 if (value2 != NULL) 1516 value = value2; 1517 } 1518 break; 1519 default: 1520 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1521 if (value2 != NULL) 1522 xmlFree((xmlChar *) value2); 1523 goto internal_error; 1524 } 1525 value = value2; 1526 } 1527 if (*retValue == NULL) 1528 if (value == NULL) { 1529 if (! list) 1530 *retValue = xmlStrdup(BAD_CAST ""); 1531 } else 1532 *retValue = xmlStrdup(value); 1533 else if (value != NULL) { 1534 /* List. */ 1535 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1536 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1537 } 1538 FREE_AND_NULL(value2) 1539 val = xmlSchemaValueGetNext(val); 1540 } while (val != NULL); 1541 1542 return (0); 1543 internal_error: 1544 if (*retValue != NULL) 1545 xmlFree((xmlChar *) (*retValue)); 1546 if (value2 != NULL) 1547 xmlFree((xmlChar *) value2); 1548 return (-1); 1549 } 1550 1551 /** 1552 * xmlSchemaFormatItemForReport: 1553 * @buf: the string buffer 1554 * @itemDes: the designation of the item 1555 * @itemName: the name of the item 1556 * @item: the item as an object 1557 * @itemNode: the node of the item 1558 * @local: the local name 1559 * @parsing: if the function is used during the parse 1560 * 1561 * Returns a representation of the given item used 1562 * for error reports. 1563 * 1564 * The following order is used to build the resulting 1565 * designation if the arguments are not NULL: 1566 * 1a. If itemDes not NULL -> itemDes 1567 * 1b. If (itemDes not NULL) and (itemName not NULL) 1568 * -> itemDes + itemName 1569 * 2. If the preceding was NULL and (item not NULL) -> item 1570 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1571 * 1572 * If the itemNode is an attribute node, the name of the attribute 1573 * will be appended to the result. 1574 * 1575 * Returns the formatted string and sets @buf to the resulting value. 1576 */ 1577 static xmlChar* 1578 xmlSchemaFormatItemForReport(xmlChar **buf, 1579 const xmlChar *itemDes, 1580 xmlSchemaBasicItemPtr item, 1581 xmlNodePtr itemNode) 1582 { 1583 xmlChar *str = NULL; 1584 int named = 1; 1585 1586 if (*buf != NULL) { 1587 xmlFree(*buf); 1588 *buf = NULL; 1589 } 1590 1591 if (itemDes != NULL) { 1592 *buf = xmlStrdup(itemDes); 1593 } else if (item != NULL) { 1594 switch (item->type) { 1595 case XML_SCHEMA_TYPE_BASIC: { 1596 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1597 1598 if (WXS_IS_ATOMIC(type)) 1599 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1600 else if (WXS_IS_LIST(type)) 1601 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1602 else if (WXS_IS_UNION(type)) 1603 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1604 else 1605 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1606 *buf = xmlStrcat(*buf, type->name); 1607 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1608 } 1609 break; 1610 case XML_SCHEMA_TYPE_SIMPLE: { 1611 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1612 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrdup(BAD_CAST""); 1615 } else { 1616 *buf = xmlStrdup(BAD_CAST "local "); 1617 } 1618 if (WXS_IS_ATOMIC(type)) 1619 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1620 else if (WXS_IS_LIST(type)) 1621 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1622 else if (WXS_IS_UNION(type)) 1623 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1624 else 1625 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1626 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1627 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1628 *buf = xmlStrcat(*buf, type->name); 1629 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1630 } 1631 } 1632 break; 1633 case XML_SCHEMA_TYPE_COMPLEX: { 1634 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1635 1636 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1637 *buf = xmlStrdup(BAD_CAST ""); 1638 else 1639 *buf = xmlStrdup(BAD_CAST "local "); 1640 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1641 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1642 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1643 *buf = xmlStrcat(*buf, type->name); 1644 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1645 } 1646 } 1647 break; 1648 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1649 xmlSchemaAttributeUsePtr ause; 1650 1651 ause = WXS_ATTR_USE_CAST item; 1652 *buf = xmlStrdup(BAD_CAST "attribute use "); 1653 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1654 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1655 *buf = xmlStrcat(*buf, 1656 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1657 FREE_AND_NULL(str) 1658 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1659 } else { 1660 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1661 } 1662 } 1663 break; 1664 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1665 xmlSchemaAttributePtr attr; 1666 1667 attr = (xmlSchemaAttributePtr) item; 1668 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1669 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1670 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1671 attr->targetNamespace, attr->name)); 1672 FREE_AND_NULL(str) 1673 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1674 } 1675 break; 1676 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1677 xmlSchemaGetComponentDesignation(buf, item); 1678 break; 1679 case XML_SCHEMA_TYPE_ELEMENT: { 1680 xmlSchemaElementPtr elem; 1681 1682 elem = (xmlSchemaElementPtr) item; 1683 *buf = xmlStrdup(BAD_CAST "element decl."); 1684 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1685 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1686 elem->targetNamespace, elem->name)); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 } 1689 break; 1690 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1691 case XML_SCHEMA_TYPE_IDC_KEY: 1692 case XML_SCHEMA_TYPE_IDC_KEYREF: 1693 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1694 *buf = xmlStrdup(BAD_CAST "unique '"); 1695 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1696 *buf = xmlStrdup(BAD_CAST "key '"); 1697 else 1698 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1699 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1700 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1701 break; 1702 case XML_SCHEMA_TYPE_ANY: 1703 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1704 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1705 ((xmlSchemaWildcardPtr) item)->processContents)); 1706 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1707 break; 1708 case XML_SCHEMA_FACET_MININCLUSIVE: 1709 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1710 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1711 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1712 case XML_SCHEMA_FACET_TOTALDIGITS: 1713 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1714 case XML_SCHEMA_FACET_PATTERN: 1715 case XML_SCHEMA_FACET_ENUMERATION: 1716 case XML_SCHEMA_FACET_WHITESPACE: 1717 case XML_SCHEMA_FACET_LENGTH: 1718 case XML_SCHEMA_FACET_MAXLENGTH: 1719 case XML_SCHEMA_FACET_MINLENGTH: 1720 *buf = xmlStrdup(BAD_CAST "facet '"); 1721 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1722 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1723 break; 1724 case XML_SCHEMA_TYPE_GROUP: { 1725 *buf = xmlStrdup(BAD_CAST "model group def."); 1726 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1727 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1728 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1729 FREE_AND_NULL(str) 1730 } 1731 break; 1732 case XML_SCHEMA_TYPE_SEQUENCE: 1733 case XML_SCHEMA_TYPE_CHOICE: 1734 case XML_SCHEMA_TYPE_ALL: 1735 case XML_SCHEMA_TYPE_PARTICLE: 1736 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1737 break; 1738 case XML_SCHEMA_TYPE_NOTATION: { 1739 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1740 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1741 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1742 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1743 FREE_AND_NULL(str); 1744 } 1745 /* Falls through. */ 1746 default: 1747 named = 0; 1748 } 1749 } else 1750 named = 0; 1751 1752 if ((named == 0) && (itemNode != NULL)) { 1753 xmlNodePtr elem; 1754 1755 if (itemNode->type == XML_ATTRIBUTE_NODE) 1756 elem = itemNode->parent; 1757 else 1758 elem = itemNode; 1759 *buf = xmlStrdup(BAD_CAST "Element '"); 1760 if (elem->ns != NULL) { 1761 *buf = xmlStrcat(*buf, 1762 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1763 FREE_AND_NULL(str) 1764 } else 1765 *buf = xmlStrcat(*buf, elem->name); 1766 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1767 1768 } 1769 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1770 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1771 if (itemNode->ns != NULL) { 1772 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1773 itemNode->ns->href, itemNode->name)); 1774 FREE_AND_NULL(str) 1775 } else 1776 *buf = xmlStrcat(*buf, itemNode->name); 1777 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1778 } 1779 FREE_AND_NULL(str) 1780 1781 return (xmlEscapeFormatString(buf)); 1782 } 1783 1784 /** 1785 * xmlSchemaFormatFacetEnumSet: 1786 * @buf: the string buffer 1787 * @type: the type holding the enumeration facets 1788 * 1789 * Builds a string consisting of all enumeration elements. 1790 * 1791 * Returns a string of all enumeration elements. 1792 */ 1793 static const xmlChar * 1794 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1795 xmlChar **buf, xmlSchemaTypePtr type) 1796 { 1797 xmlSchemaFacetPtr facet; 1798 xmlSchemaWhitespaceValueType ws; 1799 xmlChar *value = NULL; 1800 int res, found = 0; 1801 1802 if (*buf != NULL) 1803 xmlFree(*buf); 1804 *buf = NULL; 1805 1806 do { 1807 /* 1808 * Use the whitespace type of the base type. 1809 */ 1810 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1811 for (facet = type->facets; facet != NULL; facet = facet->next) { 1812 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1813 continue; 1814 found = 1; 1815 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1816 ws, &value); 1817 if (res == -1) { 1818 xmlSchemaInternalErr(actxt, 1819 "xmlSchemaFormatFacetEnumSet", 1820 "compute the canonical lexical representation"); 1821 if (*buf != NULL) 1822 xmlFree(*buf); 1823 *buf = NULL; 1824 return (NULL); 1825 } 1826 if (*buf == NULL) 1827 *buf = xmlStrdup(BAD_CAST "'"); 1828 else 1829 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1830 *buf = xmlStrcat(*buf, BAD_CAST value); 1831 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1832 if (value != NULL) { 1833 xmlFree((xmlChar *)value); 1834 value = NULL; 1835 } 1836 } 1837 /* 1838 * The enumeration facet of a type restricts the enumeration 1839 * facet of the ancestor type; i.e., such restricted enumerations 1840 * do not belong to the set of the given type. Thus we break 1841 * on the first found enumeration. 1842 */ 1843 if (found) 1844 break; 1845 type = type->baseType; 1846 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1847 1848 return ((const xmlChar *) *buf); 1849 } 1850 1851 /************************************************************************ 1852 * * 1853 * Error functions * 1854 * * 1855 ************************************************************************/ 1856 1857 #if 0 1858 static void 1859 xmlSchemaErrMemory(const char *msg) 1860 { 1861 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1862 msg); 1863 } 1864 #endif 1865 1866 static void 1867 xmlSchemaPSimpleErr(const char *msg) 1868 { 1869 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1870 msg); 1871 } 1872 1873 /** 1874 * xmlSchemaPErrMemory: 1875 * @node: a context node 1876 * @extra: extra informations 1877 * 1878 * Handle an out of memory condition 1879 */ 1880 static void 1881 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1882 const char *extra, xmlNodePtr node) 1883 { 1884 if (ctxt != NULL) 1885 ctxt->nberrors++; 1886 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1887 extra); 1888 } 1889 1890 /** 1891 * xmlSchemaPErr: 1892 * @ctxt: the parsing context 1893 * @node: the context node 1894 * @error: the error code 1895 * @msg: the error message 1896 * @str1: extra data 1897 * @str2: extra data 1898 * 1899 * Handle a parser error 1900 */ 1901 static void LIBXML_ATTR_FORMAT(4,0) 1902 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1903 const char *msg, const xmlChar * str1, const xmlChar * str2) 1904 { 1905 xmlGenericErrorFunc channel = NULL; 1906 xmlStructuredErrorFunc schannel = NULL; 1907 void *data = NULL; 1908 1909 if (ctxt != NULL) { 1910 ctxt->nberrors++; 1911 ctxt->err = error; 1912 channel = ctxt->error; 1913 data = ctxt->errCtxt; 1914 schannel = ctxt->serror; 1915 } 1916 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1917 error, XML_ERR_ERROR, NULL, 0, 1918 (const char *) str1, (const char *) str2, NULL, 0, 0, 1919 msg, str1, str2); 1920 } 1921 1922 /** 1923 * xmlSchemaPErr2: 1924 * @ctxt: the parsing context 1925 * @node: the context node 1926 * @node: the current child 1927 * @error: the error code 1928 * @msg: the error message 1929 * @str1: extra data 1930 * @str2: extra data 1931 * 1932 * Handle a parser error 1933 */ 1934 static void LIBXML_ATTR_FORMAT(5,0) 1935 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1936 xmlNodePtr child, int error, 1937 const char *msg, const xmlChar * str1, const xmlChar * str2) 1938 { 1939 if (child != NULL) 1940 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1941 else 1942 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1943 } 1944 1945 1946 /** 1947 * xmlSchemaPErrExt: 1948 * @ctxt: the parsing context 1949 * @node: the context node 1950 * @error: the error code 1951 * @strData1: extra data 1952 * @strData2: extra data 1953 * @strData3: extra data 1954 * @msg: the message 1955 * @str1: extra parameter for the message display 1956 * @str2: extra parameter for the message display 1957 * @str3: extra parameter for the message display 1958 * @str4: extra parameter for the message display 1959 * @str5: extra parameter for the message display 1960 * 1961 * Handle a parser error 1962 */ 1963 static void LIBXML_ATTR_FORMAT(7,0) 1964 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1965 const xmlChar * strData1, const xmlChar * strData2, 1966 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1967 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1968 const xmlChar * str5) 1969 { 1970 1971 xmlGenericErrorFunc channel = NULL; 1972 xmlStructuredErrorFunc schannel = NULL; 1973 void *data = NULL; 1974 1975 if (ctxt != NULL) { 1976 ctxt->nberrors++; 1977 ctxt->err = error; 1978 channel = ctxt->error; 1979 data = ctxt->errCtxt; 1980 schannel = ctxt->serror; 1981 } 1982 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1983 error, XML_ERR_ERROR, NULL, 0, 1984 (const char *) strData1, (const char *) strData2, 1985 (const char *) strData3, 0, 0, msg, str1, str2, 1986 str3, str4, str5); 1987 } 1988 1989 /************************************************************************ 1990 * * 1991 * Allround error functions * 1992 * * 1993 ************************************************************************/ 1994 1995 /** 1996 * xmlSchemaVTypeErrMemory: 1997 * @node: a context node 1998 * @extra: extra informations 1999 * 2000 * Handle an out of memory condition 2001 */ 2002 static void 2003 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 2004 const char *extra, xmlNodePtr node) 2005 { 2006 if (ctxt != NULL) { 2007 ctxt->nberrors++; 2008 ctxt->err = XML_SCHEMAV_INTERNAL; 2009 } 2010 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2011 extra); 2012 } 2013 2014 static void LIBXML_ATTR_FORMAT(2,0) 2015 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2016 const char *msg, const xmlChar *str) 2017 { 2018 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2019 msg, (const char *) str); 2020 } 2021 2022 #define WXS_ERROR_TYPE_ERROR 1 2023 #define WXS_ERROR_TYPE_WARNING 2 2024 /** 2025 * xmlSchemaErr4Line: 2026 * @ctxt: the validation context 2027 * @errorLevel: the error level 2028 * @error: the error code 2029 * @node: the context node 2030 * @line: the line number 2031 * @msg: the error message 2032 * @str1: extra data 2033 * @str2: extra data 2034 * @str3: extra data 2035 * @str4: extra data 2036 * 2037 * Handle a validation error 2038 */ 2039 static void LIBXML_ATTR_FORMAT(6,0) 2040 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2041 xmlErrorLevel errorLevel, 2042 int error, xmlNodePtr node, int line, const char *msg, 2043 const xmlChar *str1, const xmlChar *str2, 2044 const xmlChar *str3, const xmlChar *str4) 2045 { 2046 xmlStructuredErrorFunc schannel = NULL; 2047 xmlGenericErrorFunc channel = NULL; 2048 void *data = NULL; 2049 2050 if (ctxt != NULL) { 2051 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2052 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2053 const char *file = NULL; 2054 int col = 0; 2055 if (errorLevel != XML_ERR_WARNING) { 2056 vctxt->nberrors++; 2057 vctxt->err = error; 2058 channel = vctxt->error; 2059 } else { 2060 channel = vctxt->warning; 2061 } 2062 schannel = vctxt->serror; 2063 data = vctxt->errCtxt; 2064 2065 /* 2066 * Error node. If we specify a line number, then 2067 * do not channel any node to the error function. 2068 */ 2069 if (line == 0) { 2070 if ((node == NULL) && 2071 (vctxt->depth >= 0) && 2072 (vctxt->inode != NULL)) { 2073 node = vctxt->inode->node; 2074 } 2075 /* 2076 * Get filename and line if no node-tree. 2077 */ 2078 if ((node == NULL) && 2079 (vctxt->parserCtxt != NULL) && 2080 (vctxt->parserCtxt->input != NULL)) { 2081 file = vctxt->parserCtxt->input->filename; 2082 line = vctxt->parserCtxt->input->line; 2083 col = vctxt->parserCtxt->input->col; 2084 } 2085 } else { 2086 /* 2087 * Override the given node's (if any) position 2088 * and channel only the given line number. 2089 */ 2090 node = NULL; 2091 /* 2092 * Get filename. 2093 */ 2094 if (vctxt->doc != NULL) 2095 file = (const char *) vctxt->doc->URL; 2096 else if ((vctxt->parserCtxt != NULL) && 2097 (vctxt->parserCtxt->input != NULL)) 2098 file = vctxt->parserCtxt->input->filename; 2099 } 2100 if (vctxt->locFunc != NULL) { 2101 if ((file == NULL) || (line == 0)) { 2102 unsigned long l; 2103 const char *f; 2104 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2105 if (file == NULL) 2106 file = f; 2107 if (line == 0) 2108 line = (int) l; 2109 } 2110 } 2111 if ((file == NULL) && (vctxt->filename != NULL)) 2112 file = vctxt->filename; 2113 2114 __xmlRaiseError(schannel, channel, data, ctxt, 2115 node, XML_FROM_SCHEMASV, 2116 error, errorLevel, file, line, 2117 (const char *) str1, (const char *) str2, 2118 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2119 2120 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2121 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2122 if (errorLevel != XML_ERR_WARNING) { 2123 pctxt->nberrors++; 2124 pctxt->err = error; 2125 channel = pctxt->error; 2126 } else { 2127 channel = pctxt->warning; 2128 } 2129 schannel = pctxt->serror; 2130 data = pctxt->errCtxt; 2131 __xmlRaiseError(schannel, channel, data, ctxt, 2132 node, XML_FROM_SCHEMASP, error, 2133 errorLevel, NULL, 0, 2134 (const char *) str1, (const char *) str2, 2135 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2136 } else { 2137 TODO 2138 } 2139 } 2140 } 2141 2142 /** 2143 * xmlSchemaErr3: 2144 * @ctxt: the validation context 2145 * @node: the context node 2146 * @error: the error code 2147 * @msg: the error message 2148 * @str1: extra data 2149 * @str2: extra data 2150 * @str3: extra data 2151 * 2152 * Handle a validation error 2153 */ 2154 static void LIBXML_ATTR_FORMAT(4,0) 2155 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2156 int error, xmlNodePtr node, const char *msg, 2157 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2158 { 2159 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2160 msg, str1, str2, str3, NULL); 2161 } 2162 2163 static void LIBXML_ATTR_FORMAT(4,0) 2164 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2165 int error, xmlNodePtr node, const char *msg, 2166 const xmlChar *str1, const xmlChar *str2, 2167 const xmlChar *str3, const xmlChar *str4) 2168 { 2169 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2170 msg, str1, str2, str3, str4); 2171 } 2172 2173 static void LIBXML_ATTR_FORMAT(4,0) 2174 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2175 int error, xmlNodePtr node, const char *msg, 2176 const xmlChar *str1, const xmlChar *str2) 2177 { 2178 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2179 } 2180 2181 static xmlChar * 2182 xmlSchemaFormatNodeForError(xmlChar ** msg, 2183 xmlSchemaAbstractCtxtPtr actxt, 2184 xmlNodePtr node) 2185 { 2186 xmlChar *str = NULL; 2187 2188 *msg = NULL; 2189 if ((node != NULL) && 2190 (node->type != XML_ELEMENT_NODE) && 2191 (node->type != XML_ATTRIBUTE_NODE)) 2192 { 2193 /* 2194 * Don't try to format other nodes than element and 2195 * attribute nodes. 2196 * Play safe and return an empty string. 2197 */ 2198 *msg = xmlStrdup(BAD_CAST ""); 2199 return(*msg); 2200 } 2201 if (node != NULL) { 2202 /* 2203 * Work on tree nodes. 2204 */ 2205 if (node->type == XML_ATTRIBUTE_NODE) { 2206 xmlNodePtr elem = node->parent; 2207 2208 *msg = xmlStrdup(BAD_CAST "Element '"); 2209 if (elem->ns != NULL) 2210 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2211 elem->ns->href, elem->name)); 2212 else 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 NULL, elem->name)); 2215 FREE_AND_NULL(str); 2216 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2217 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2218 } else { 2219 *msg = xmlStrdup(BAD_CAST "Element '"); 2220 } 2221 if (node->ns != NULL) 2222 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2223 node->ns->href, node->name)); 2224 else 2225 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2226 NULL, node->name)); 2227 FREE_AND_NULL(str); 2228 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2229 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2230 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2231 /* 2232 * Work on node infos. 2233 */ 2234 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2235 xmlSchemaNodeInfoPtr ielem = 2236 vctxt->elemInfos[vctxt->depth]; 2237 2238 *msg = xmlStrdup(BAD_CAST "Element '"); 2239 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2240 ielem->nsName, ielem->localName)); 2241 FREE_AND_NULL(str); 2242 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2243 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2244 } else { 2245 *msg = xmlStrdup(BAD_CAST "Element '"); 2246 } 2247 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2248 vctxt->inode->nsName, vctxt->inode->localName)); 2249 FREE_AND_NULL(str); 2250 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2251 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2252 /* 2253 * Hmm, no node while parsing? 2254 * Return an empty string, in case NULL will break something. 2255 */ 2256 *msg = xmlStrdup(BAD_CAST ""); 2257 } else { 2258 TODO 2259 return (NULL); 2260 } 2261 2262 /* 2263 * xmlSchemaFormatItemForReport() also returns an escaped format 2264 * string, so do this before calling it below (in the future). 2265 */ 2266 xmlEscapeFormatString(msg); 2267 2268 /* 2269 * VAL TODO: The output of the given schema component is currently 2270 * disabled. 2271 */ 2272 #if 0 2273 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2274 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2275 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2276 NULL, type, NULL, 0)); 2277 FREE_AND_NULL(str) 2278 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2279 } 2280 #endif 2281 return (*msg); 2282 } 2283 2284 static void LIBXML_ATTR_FORMAT(3,0) 2285 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2286 const char *funcName, 2287 const char *message, 2288 const xmlChar *str1, 2289 const xmlChar *str2) 2290 { 2291 xmlChar *msg = NULL; 2292 2293 if (actxt == NULL) 2294 return; 2295 msg = xmlStrdup(BAD_CAST "Internal error: %s, "); 2296 msg = xmlStrcat(msg, BAD_CAST message); 2297 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2298 2299 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2300 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, 2301 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2302 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2303 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, 2304 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2305 2306 FREE_AND_NULL(msg) 2307 } 2308 2309 static void LIBXML_ATTR_FORMAT(3,0) 2310 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2311 const char *funcName, 2312 const char *message) 2313 { 2314 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2315 } 2316 2317 #if 0 2318 static void LIBXML_ATTR_FORMAT(3,0) 2319 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2320 const char *funcName, 2321 const char *message, 2322 const xmlChar *str1, 2323 const xmlChar *str2) 2324 { 2325 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2326 str1, str2); 2327 } 2328 #endif 2329 2330 static void LIBXML_ATTR_FORMAT(5,0) 2331 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2332 xmlParserErrors error, 2333 xmlNodePtr node, 2334 xmlSchemaBasicItemPtr item, 2335 const char *message, 2336 const xmlChar *str1, const xmlChar *str2, 2337 const xmlChar *str3, const xmlChar *str4) 2338 { 2339 xmlChar *msg = NULL; 2340 2341 if ((node == NULL) && (item != NULL) && 2342 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2343 node = WXS_ITEM_NODE(item); 2344 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2345 msg = xmlStrcat(msg, BAD_CAST ": "); 2346 } else 2347 xmlSchemaFormatNodeForError(&msg, actxt, node); 2348 msg = xmlStrcat(msg, (const xmlChar *) message); 2349 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2350 xmlSchemaErr4(actxt, error, node, 2351 (const char *) msg, str1, str2, str3, str4); 2352 FREE_AND_NULL(msg) 2353 } 2354 2355 static void LIBXML_ATTR_FORMAT(5,0) 2356 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2357 xmlParserErrors error, 2358 xmlNodePtr node, 2359 xmlSchemaBasicItemPtr item, 2360 const char *message, 2361 const xmlChar *str1, 2362 const xmlChar *str2) 2363 { 2364 xmlSchemaCustomErr4(actxt, error, node, item, 2365 message, str1, str2, NULL, NULL); 2366 } 2367 2368 2369 2370 static void LIBXML_ATTR_FORMAT(5,0) 2371 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2372 xmlParserErrors error, 2373 xmlNodePtr node, 2374 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2375 const char *message, 2376 const xmlChar *str1, 2377 const xmlChar *str2, 2378 const xmlChar *str3) 2379 { 2380 xmlChar *msg = NULL; 2381 2382 xmlSchemaFormatNodeForError(&msg, actxt, node); 2383 msg = xmlStrcat(msg, (const xmlChar *) message); 2384 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2385 2386 /* URGENT TODO: Set the error code to something sane. */ 2387 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2388 (const char *) msg, str1, str2, str3, NULL); 2389 2390 FREE_AND_NULL(msg) 2391 } 2392 2393 2394 2395 static void LIBXML_ATTR_FORMAT(5,0) 2396 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2397 xmlParserErrors error, 2398 xmlSchemaPSVIIDCNodePtr idcNode, 2399 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2400 const char *message, 2401 const xmlChar *str1, 2402 const xmlChar *str2) 2403 { 2404 xmlChar *msg = NULL, *qname = NULL; 2405 2406 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2407 msg = xmlStrcat(msg, (const xmlChar *) message); 2408 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2409 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2410 error, NULL, idcNode->nodeLine, (const char *) msg, 2411 xmlSchemaFormatQName(&qname, 2412 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2413 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2414 str1, str2, NULL); 2415 FREE_AND_NULL(qname); 2416 FREE_AND_NULL(msg); 2417 } 2418 2419 static int 2420 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2421 xmlNodePtr node) 2422 { 2423 if (node != NULL) 2424 return (node->type); 2425 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2426 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2427 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2428 return (-1); 2429 } 2430 2431 static int 2432 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2433 { 2434 switch (item->type) { 2435 case XML_SCHEMA_TYPE_COMPLEX: 2436 case XML_SCHEMA_TYPE_SIMPLE: 2437 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2438 return(1); 2439 break; 2440 case XML_SCHEMA_TYPE_GROUP: 2441 return (1); 2442 case XML_SCHEMA_TYPE_ELEMENT: 2443 if ( ((xmlSchemaElementPtr) item)->flags & 2444 XML_SCHEMAS_ELEM_GLOBAL) 2445 return(1); 2446 break; 2447 case XML_SCHEMA_TYPE_ATTRIBUTE: 2448 if ( ((xmlSchemaAttributePtr) item)->flags & 2449 XML_SCHEMAS_ATTR_GLOBAL) 2450 return(1); 2451 break; 2452 /* Note that attribute groups are always global. */ 2453 default: 2454 return(1); 2455 } 2456 return (0); 2457 } 2458 2459 static void 2460 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2461 xmlParserErrors error, 2462 xmlNodePtr node, 2463 const xmlChar *value, 2464 xmlSchemaTypePtr type, 2465 int displayValue) 2466 { 2467 xmlChar *msg = NULL; 2468 2469 xmlSchemaFormatNodeForError(&msg, actxt, node); 2470 2471 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2472 XML_ATTRIBUTE_NODE)) 2473 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2474 else 2475 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2476 "value of "); 2477 2478 if (! xmlSchemaIsGlobalItem(type)) 2479 msg = xmlStrcat(msg, BAD_CAST "the local "); 2480 else 2481 msg = xmlStrcat(msg, BAD_CAST "the "); 2482 2483 if (WXS_IS_ATOMIC(type)) 2484 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2485 else if (WXS_IS_LIST(type)) 2486 msg = xmlStrcat(msg, BAD_CAST "list type"); 2487 else if (WXS_IS_UNION(type)) 2488 msg = xmlStrcat(msg, BAD_CAST "union type"); 2489 2490 if (xmlSchemaIsGlobalItem(type)) { 2491 xmlChar *str = NULL; 2492 msg = xmlStrcat(msg, BAD_CAST " '"); 2493 if (type->builtInType != 0) { 2494 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2495 str = xmlStrdup(type->name); 2496 } else { 2497 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 2498 if (!str) 2499 str = xmlStrdup(qName); 2500 } 2501 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2502 msg = xmlStrcat(msg, BAD_CAST "'"); 2503 FREE_AND_NULL(str); 2504 } 2505 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2506 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2507 XML_ATTRIBUTE_NODE)) 2508 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2509 else 2510 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2511 FREE_AND_NULL(msg) 2512 } 2513 2514 static const xmlChar * 2515 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2516 xmlSchemaNodeInfoPtr ni, 2517 xmlNodePtr node) 2518 { 2519 if (node != NULL) { 2520 if (node->ns != NULL) 2521 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2522 else 2523 return (xmlSchemaFormatQName(str, NULL, node->name)); 2524 } else if (ni != NULL) 2525 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2526 return (NULL); 2527 } 2528 2529 static void 2530 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2531 xmlParserErrors error, 2532 xmlSchemaAttrInfoPtr ni, 2533 xmlNodePtr node) 2534 { 2535 xmlChar *msg = NULL, *str = NULL; 2536 2537 xmlSchemaFormatNodeForError(&msg, actxt, node); 2538 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2539 xmlSchemaErr(actxt, error, node, (const char *) msg, 2540 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2541 NULL); 2542 FREE_AND_NULL(str) 2543 FREE_AND_NULL(msg) 2544 } 2545 2546 static void LIBXML_ATTR_FORMAT(5,0) 2547 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2548 xmlParserErrors error, 2549 xmlNodePtr node, 2550 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2551 const char *message, 2552 int nbval, 2553 int nbneg, 2554 xmlChar **values) 2555 { 2556 xmlChar *str = NULL, *msg = NULL; 2557 xmlChar *localName, *nsName; 2558 const xmlChar *cur, *end; 2559 int i; 2560 2561 xmlSchemaFormatNodeForError(&msg, actxt, node); 2562 msg = xmlStrcat(msg, (const xmlChar *) message); 2563 msg = xmlStrcat(msg, BAD_CAST "."); 2564 /* 2565 * Note that is does not make sense to report that we have a 2566 * wildcard here, since the wildcard might be unfolded into 2567 * multiple transitions. 2568 */ 2569 if (nbval + nbneg > 0) { 2570 if (nbval + nbneg > 1) { 2571 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2572 } else 2573 str = xmlStrdup(BAD_CAST " Expected is ( "); 2574 nsName = NULL; 2575 2576 for (i = 0; i < nbval + nbneg; i++) { 2577 cur = values[i]; 2578 if (cur == NULL) 2579 continue; 2580 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2581 (cur[3] == ' ')) { 2582 cur += 4; 2583 str = xmlStrcat(str, BAD_CAST "##other"); 2584 } 2585 /* 2586 * Get the local name. 2587 */ 2588 localName = NULL; 2589 2590 end = cur; 2591 if (*end == '*') { 2592 localName = xmlStrdup(BAD_CAST "*"); 2593 end++; 2594 } else { 2595 while ((*end != 0) && (*end != '|')) 2596 end++; 2597 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2598 } 2599 if (*end != 0) { 2600 end++; 2601 /* 2602 * Skip "*|*" if they come with negated expressions, since 2603 * they represent the same negated wildcard. 2604 */ 2605 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2606 /* 2607 * Get the namespace name. 2608 */ 2609 cur = end; 2610 if (*end == '*') { 2611 nsName = xmlStrdup(BAD_CAST "{*}"); 2612 } else { 2613 while (*end != 0) 2614 end++; 2615 2616 if (i >= nbval) 2617 nsName = xmlStrdup(BAD_CAST "{##other:"); 2618 else 2619 nsName = xmlStrdup(BAD_CAST "{"); 2620 2621 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2622 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2623 } 2624 str = xmlStrcat(str, BAD_CAST nsName); 2625 FREE_AND_NULL(nsName) 2626 } else { 2627 FREE_AND_NULL(localName); 2628 continue; 2629 } 2630 } 2631 str = xmlStrcat(str, BAD_CAST localName); 2632 FREE_AND_NULL(localName); 2633 2634 if (i < nbval + nbneg -1) 2635 str = xmlStrcat(str, BAD_CAST ", "); 2636 } 2637 str = xmlStrcat(str, BAD_CAST " ).\n"); 2638 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2639 FREE_AND_NULL(str) 2640 } else 2641 msg = xmlStrcat(msg, BAD_CAST "\n"); 2642 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2643 xmlFree(msg); 2644 } 2645 2646 static void LIBXML_ATTR_FORMAT(8,0) 2647 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2648 xmlParserErrors error, 2649 xmlNodePtr node, 2650 const xmlChar *value, 2651 unsigned long length, 2652 xmlSchemaTypePtr type, 2653 xmlSchemaFacetPtr facet, 2654 const char *message, 2655 const xmlChar *str1, 2656 const xmlChar *str2) 2657 { 2658 xmlChar *str = NULL, *msg = NULL; 2659 xmlSchemaTypeType facetType; 2660 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2661 2662 xmlSchemaFormatNodeForError(&msg, actxt, node); 2663 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2664 facetType = XML_SCHEMA_FACET_ENUMERATION; 2665 /* 2666 * If enumerations are validated, one must not expect the 2667 * facet to be given. 2668 */ 2669 } else 2670 facetType = facet->type; 2671 msg = xmlStrcat(msg, BAD_CAST "["); 2672 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2673 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2674 msg = xmlStrcat(msg, BAD_CAST "'] "); 2675 if (message == NULL) { 2676 /* 2677 * Use a default message. 2678 */ 2679 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2680 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2681 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2682 2683 char len[25], actLen[25]; 2684 2685 /* FIXME, TODO: What is the max expected string length of the 2686 * this value? 2687 */ 2688 if (nodeType == XML_ATTRIBUTE_NODE) 2689 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2690 else 2691 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2692 2693 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2694 snprintf(actLen, 24, "%lu", length); 2695 2696 if (facetType == XML_SCHEMA_FACET_LENGTH) 2697 msg = xmlStrcat(msg, 2698 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2699 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2700 msg = xmlStrcat(msg, 2701 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2702 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2703 msg = xmlStrcat(msg, 2704 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2705 2706 if (nodeType == XML_ATTRIBUTE_NODE) 2707 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2708 value, (const xmlChar *) actLen, (const xmlChar *) len); 2709 else 2710 xmlSchemaErr(actxt, error, node, (const char *) msg, 2711 (const xmlChar *) actLen, (const xmlChar *) len); 2712 2713 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2714 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2715 "of the set {%s}.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2717 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2718 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2719 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2720 "by the pattern '%s'.\n"); 2721 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2722 facet->value); 2723 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2724 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2725 "minimum value allowed ('%s').\n"); 2726 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2727 facet->value); 2728 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2729 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2730 "maximum value allowed ('%s').\n"); 2731 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2732 facet->value); 2733 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2734 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2735 "'%s'.\n"); 2736 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2737 facet->value); 2738 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2739 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2740 "'%s'.\n"); 2741 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2742 facet->value); 2743 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2744 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2745 "digits than are allowed ('%s').\n"); 2746 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2747 facet->value); 2748 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2749 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2750 "digits than are allowed ('%s').\n"); 2751 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2752 facet->value); 2753 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2754 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2755 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2756 } else { 2757 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2758 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2759 } 2760 } else { 2761 msg = xmlStrcat(msg, (const xmlChar *) message); 2762 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2763 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2764 } 2765 FREE_AND_NULL(str) 2766 xmlFree(msg); 2767 } 2768 2769 #define VERROR(err, type, msg) \ 2770 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2771 2772 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2773 2774 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2775 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2776 2777 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2778 2779 2780 /** 2781 * xmlSchemaPMissingAttrErr: 2782 * @ctxt: the schema validation context 2783 * @ownerItem: the owner as a schema object 2784 * @ownerElem: the owner as an element node 2785 * @node: the parent element node of the missing attribute node 2786 * @type: the corresponding type of the attribute node 2787 * 2788 * Reports an illegal attribute. 2789 */ 2790 static void 2791 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2792 xmlParserErrors error, 2793 xmlSchemaBasicItemPtr ownerItem, 2794 xmlNodePtr ownerElem, 2795 const char *name, 2796 const char *message) 2797 { 2798 xmlChar *des = NULL; 2799 2800 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2801 2802 if (message != NULL) 2803 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2804 else 2805 xmlSchemaPErr(ctxt, ownerElem, error, 2806 "%s: The attribute '%s' is required but missing.\n", 2807 BAD_CAST des, BAD_CAST name); 2808 FREE_AND_NULL(des); 2809 } 2810 2811 2812 /** 2813 * xmlSchemaPResCompAttrErr: 2814 * @ctxt: the schema validation context 2815 * @error: the error code 2816 * @ownerItem: the owner as a schema object 2817 * @ownerElem: the owner as an element node 2818 * @name: the name of the attribute holding the QName 2819 * @refName: the referenced local name 2820 * @refURI: the referenced namespace URI 2821 * @message: optional message 2822 * 2823 * Used to report QName attribute values that failed to resolve 2824 * to schema components. 2825 */ 2826 static void 2827 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2828 xmlParserErrors error, 2829 xmlSchemaBasicItemPtr ownerItem, 2830 xmlNodePtr ownerElem, 2831 const char *name, 2832 const xmlChar *refName, 2833 const xmlChar *refURI, 2834 xmlSchemaTypeType refType, 2835 const char *refTypeStr) 2836 { 2837 xmlChar *des = NULL, *strA = NULL; 2838 2839 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2840 if (refTypeStr == NULL) 2841 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2842 xmlSchemaPErrExt(ctxt, ownerElem, error, 2843 NULL, NULL, NULL, 2844 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2845 "%s.\n", BAD_CAST des, BAD_CAST name, 2846 xmlSchemaFormatQName(&strA, refURI, refName), 2847 BAD_CAST refTypeStr, NULL); 2848 FREE_AND_NULL(des) 2849 FREE_AND_NULL(strA) 2850 } 2851 2852 /** 2853 * xmlSchemaPCustomAttrErr: 2854 * @ctxt: the schema parser context 2855 * @error: the error code 2856 * @ownerDes: the designation of the owner 2857 * @ownerItem: the owner as a schema object 2858 * @attr: the illegal attribute node 2859 * 2860 * Reports an illegal attribute during the parse. 2861 */ 2862 static void 2863 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2864 xmlParserErrors error, 2865 xmlChar **ownerDes, 2866 xmlSchemaBasicItemPtr ownerItem, 2867 xmlAttrPtr attr, 2868 const char *msg) 2869 { 2870 xmlChar *des = NULL; 2871 2872 if (ownerDes == NULL) 2873 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2874 else if (*ownerDes == NULL) { 2875 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2876 des = *ownerDes; 2877 } else 2878 des = *ownerDes; 2879 if (attr == NULL) { 2880 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2881 "%s, attribute '%s': %s.\n", 2882 BAD_CAST des, (const xmlChar *) "Unknown", 2883 (const xmlChar *) msg, NULL, NULL); 2884 } else { 2885 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2886 "%s, attribute '%s': %s.\n", 2887 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2888 } 2889 if (ownerDes == NULL) 2890 FREE_AND_NULL(des); 2891 } 2892 2893 /** 2894 * xmlSchemaPIllegalAttrErr: 2895 * @ctxt: the schema parser context 2896 * @error: the error code 2897 * @ownerItem: the attribute's owner item 2898 * @attr: the illegal attribute node 2899 * 2900 * Reports an illegal attribute during the parse. 2901 */ 2902 static void 2903 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2904 xmlParserErrors error, 2905 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2906 xmlAttrPtr attr) 2907 { 2908 xmlChar *strA = NULL, *strB = NULL; 2909 2910 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2911 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2912 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2913 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2914 NULL, NULL); 2915 FREE_AND_NULL(strA); 2916 FREE_AND_NULL(strB); 2917 } 2918 2919 /** 2920 * xmlSchemaPCustomErr: 2921 * @ctxt: the schema parser context 2922 * @error: the error code 2923 * @itemDes: the designation of the schema item 2924 * @item: the schema item 2925 * @itemElem: the node of the schema item 2926 * @message: the error message 2927 * @str1: an optional param for the error message 2928 * @str2: an optional param for the error message 2929 * @str3: an optional param for the error message 2930 * 2931 * Reports an error during parsing. 2932 */ 2933 static void LIBXML_ATTR_FORMAT(5,0) 2934 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2935 xmlParserErrors error, 2936 xmlSchemaBasicItemPtr item, 2937 xmlNodePtr itemElem, 2938 const char *message, 2939 const xmlChar *str1, 2940 const xmlChar *str2, 2941 const xmlChar *str3) 2942 { 2943 xmlChar *des = NULL, *msg = NULL; 2944 2945 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2946 msg = xmlStrdup(BAD_CAST "%s: "); 2947 msg = xmlStrcat(msg, (const xmlChar *) message); 2948 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2949 if ((itemElem == NULL) && (item != NULL)) 2950 itemElem = WXS_ITEM_NODE(item); 2951 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2952 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2953 FREE_AND_NULL(des); 2954 FREE_AND_NULL(msg); 2955 } 2956 2957 /** 2958 * xmlSchemaPCustomErr: 2959 * @ctxt: the schema parser context 2960 * @error: the error code 2961 * @itemDes: the designation of the schema item 2962 * @item: the schema item 2963 * @itemElem: the node of the schema item 2964 * @message: the error message 2965 * @str1: the optional param for the error message 2966 * 2967 * Reports an error during parsing. 2968 */ 2969 static void LIBXML_ATTR_FORMAT(5,0) 2970 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2971 xmlParserErrors error, 2972 xmlSchemaBasicItemPtr item, 2973 xmlNodePtr itemElem, 2974 const char *message, 2975 const xmlChar *str1) 2976 { 2977 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2978 str1, NULL, NULL); 2979 } 2980 2981 /** 2982 * xmlSchemaPAttrUseErr: 2983 * @ctxt: the schema parser context 2984 * @error: the error code 2985 * @itemDes: the designation of the schema type 2986 * @item: the schema type 2987 * @itemElem: the node of the schema type 2988 * @attr: the invalid schema attribute 2989 * @message: the error message 2990 * @str1: the optional param for the error message 2991 * 2992 * Reports an attribute use error during parsing. 2993 */ 2994 static void LIBXML_ATTR_FORMAT(6,0) 2995 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2996 xmlParserErrors error, 2997 xmlNodePtr node, 2998 xmlSchemaBasicItemPtr ownerItem, 2999 const xmlSchemaAttributeUsePtr attruse, 3000 const char *message, 3001 const xmlChar *str1, const xmlChar *str2, 3002 const xmlChar *str3,const xmlChar *str4) 3003 { 3004 xmlChar *str = NULL, *msg = NULL; 3005 3006 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 3007 msg = xmlStrcat(msg, BAD_CAST ", "); 3008 msg = xmlStrcat(msg, 3009 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 3010 WXS_BASIC_CAST attruse, NULL)); 3011 FREE_AND_NULL(str); 3012 msg = xmlStrcat(msg, BAD_CAST ": "); 3013 msg = xmlStrcat(msg, (const xmlChar *) message); 3014 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3015 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3016 (const char *) msg, str1, str2, str3, str4); 3017 xmlFree(msg); 3018 } 3019 3020 /** 3021 * xmlSchemaPIllegalFacetAtomicErr: 3022 * @ctxt: the schema parser context 3023 * @error: the error code 3024 * @type: the schema type 3025 * @baseType: the base type of type 3026 * @facet: the illegal facet 3027 * 3028 * Reports an illegal facet for atomic simple types. 3029 */ 3030 static void 3031 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3032 xmlParserErrors error, 3033 xmlSchemaTypePtr type, 3034 xmlSchemaTypePtr baseType, 3035 xmlSchemaFacetPtr facet) 3036 { 3037 xmlChar *des = NULL, *strT = NULL; 3038 3039 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3040 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3041 "%s: The facet '%s' is not allowed on types derived from the " 3042 "type %s.\n", 3043 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3044 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3045 NULL, NULL); 3046 FREE_AND_NULL(des); 3047 FREE_AND_NULL(strT); 3048 } 3049 3050 /** 3051 * xmlSchemaPIllegalFacetListUnionErr: 3052 * @ctxt: the schema parser context 3053 * @error: the error code 3054 * @itemDes: the designation of the schema item involved 3055 * @item: the schema item involved 3056 * @facet: the illegal facet 3057 * 3058 * Reports an illegal facet for <list> and <union>. 3059 */ 3060 static void 3061 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3062 xmlParserErrors error, 3063 xmlSchemaTypePtr type, 3064 xmlSchemaFacetPtr facet) 3065 { 3066 xmlChar *des = NULL; 3067 3068 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3069 type->node); 3070 xmlSchemaPErr(ctxt, type->node, error, 3071 "%s: The facet '%s' is not allowed.\n", 3072 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3073 FREE_AND_NULL(des); 3074 } 3075 3076 /** 3077 * xmlSchemaPMutualExclAttrErr: 3078 * @ctxt: the schema validation context 3079 * @error: the error code 3080 * @elemDes: the designation of the parent element node 3081 * @attr: the bad attribute node 3082 * @type: the corresponding type of the attribute node 3083 * 3084 * Reports an illegal attribute. 3085 */ 3086 static void 3087 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3088 xmlParserErrors error, 3089 xmlSchemaBasicItemPtr ownerItem, 3090 xmlAttrPtr attr, 3091 const char *name1, 3092 const char *name2) 3093 { 3094 xmlChar *des = NULL; 3095 3096 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3097 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3098 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3099 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3100 FREE_AND_NULL(des); 3101 } 3102 3103 /** 3104 * xmlSchemaPSimpleTypeErr: 3105 * @ctxt: the schema validation context 3106 * @error: the error code 3107 * @type: the type specifier 3108 * @ownerItem: the schema object if existent 3109 * @node: the validated node 3110 * @value: the validated value 3111 * 3112 * Reports a simple type validation error. 3113 * TODO: Should this report the value of an element as well? 3114 */ 3115 static void LIBXML_ATTR_FORMAT(8,0) 3116 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3117 xmlParserErrors error, 3118 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3119 xmlNodePtr node, 3120 xmlSchemaTypePtr type, 3121 const char *expected, 3122 const xmlChar *value, 3123 const char *message, 3124 const xmlChar *str1, 3125 const xmlChar *str2) 3126 { 3127 xmlChar *msg = NULL; 3128 3129 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3130 if (message == NULL) { 3131 /* 3132 * Use default messages. 3133 */ 3134 if (type != NULL) { 3135 if (node->type == XML_ATTRIBUTE_NODE) 3136 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3137 else 3138 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3139 "valid value of "); 3140 if (! xmlSchemaIsGlobalItem(type)) 3141 msg = xmlStrcat(msg, BAD_CAST "the local "); 3142 else 3143 msg = xmlStrcat(msg, BAD_CAST "the "); 3144 3145 if (WXS_IS_ATOMIC(type)) 3146 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3147 else if (WXS_IS_LIST(type)) 3148 msg = xmlStrcat(msg, BAD_CAST "list type"); 3149 else if (WXS_IS_UNION(type)) 3150 msg = xmlStrcat(msg, BAD_CAST "union type"); 3151 3152 if (xmlSchemaIsGlobalItem(type)) { 3153 xmlChar *str = NULL; 3154 msg = xmlStrcat(msg, BAD_CAST " '"); 3155 if (type->builtInType != 0) { 3156 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3157 str = xmlStrdup(type->name); 3158 } else { 3159 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 3160 if (!str) 3161 str = xmlStrdup(qName); 3162 } 3163 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 3164 msg = xmlStrcat(msg, BAD_CAST "'."); 3165 FREE_AND_NULL(str); 3166 } 3167 } else { 3168 if (node->type == XML_ATTRIBUTE_NODE) 3169 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3170 else 3171 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3172 "valid."); 3173 } 3174 if (expected) { 3175 xmlChar *expectedEscaped = xmlCharStrdup(expected); 3176 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3177 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); 3178 FREE_AND_NULL(expectedEscaped); 3179 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3180 } else 3181 msg = xmlStrcat(msg, BAD_CAST "\n"); 3182 if (node->type == XML_ATTRIBUTE_NODE) 3183 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3184 else 3185 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3186 } else { 3187 msg = xmlStrcat(msg, BAD_CAST message); 3188 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3189 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3190 (const char*) msg, str1, str2, NULL, NULL, NULL); 3191 } 3192 /* Cleanup. */ 3193 FREE_AND_NULL(msg) 3194 } 3195 3196 /** 3197 * xmlSchemaPContentErr: 3198 * @ctxt: the schema parser context 3199 * @error: the error code 3200 * @ownerItem: the owner item of the holder of the content 3201 * @ownerElem: the node of the holder of the content 3202 * @child: the invalid child node 3203 * @message: the optional error message 3204 * @content: the optional string describing the correct content 3205 * 3206 * Reports an error concerning the content of a schema element. 3207 */ 3208 static void 3209 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3210 xmlParserErrors error, 3211 xmlSchemaBasicItemPtr ownerItem, 3212 xmlNodePtr ownerElem, 3213 xmlNodePtr child, 3214 const char *message, 3215 const char *content) 3216 { 3217 xmlChar *des = NULL; 3218 3219 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3220 if (message != NULL) 3221 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3222 "%s: %s.\n", 3223 BAD_CAST des, BAD_CAST message); 3224 else { 3225 if (content != NULL) { 3226 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3227 "%s: The content is not valid. Expected is %s.\n", 3228 BAD_CAST des, BAD_CAST content); 3229 } else { 3230 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3231 "%s: The content is not valid.\n", 3232 BAD_CAST des, NULL); 3233 } 3234 } 3235 FREE_AND_NULL(des) 3236 } 3237 3238 /************************************************************************ 3239 * * 3240 * Streamable error functions * 3241 * * 3242 ************************************************************************/ 3243 3244 3245 3246 3247 /************************************************************************ 3248 * * 3249 * Validation helper functions * 3250 * * 3251 ************************************************************************/ 3252 3253 3254 /************************************************************************ 3255 * * 3256 * Allocation functions * 3257 * * 3258 ************************************************************************/ 3259 3260 /** 3261 * xmlSchemaNewSchemaForParserCtxt: 3262 * @ctxt: a schema validation context 3263 * 3264 * Allocate a new Schema structure. 3265 * 3266 * Returns the newly allocated structure or NULL in case or error 3267 */ 3268 static xmlSchemaPtr 3269 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3270 { 3271 xmlSchemaPtr ret; 3272 3273 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3274 if (ret == NULL) { 3275 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3276 return (NULL); 3277 } 3278 memset(ret, 0, sizeof(xmlSchema)); 3279 ret->dict = ctxt->dict; 3280 xmlDictReference(ret->dict); 3281 3282 return (ret); 3283 } 3284 3285 /** 3286 * xmlSchemaNewFacet: 3287 * 3288 * Allocate a new Facet structure. 3289 * 3290 * Returns the newly allocated structure or NULL in case or error 3291 */ 3292 xmlSchemaFacetPtr 3293 xmlSchemaNewFacet(void) 3294 { 3295 xmlSchemaFacetPtr ret; 3296 3297 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3298 if (ret == NULL) { 3299 return (NULL); 3300 } 3301 memset(ret, 0, sizeof(xmlSchemaFacet)); 3302 3303 return (ret); 3304 } 3305 3306 /** 3307 * xmlSchemaNewAnnot: 3308 * @ctxt: a schema validation context 3309 * @node: a node 3310 * 3311 * Allocate a new annotation structure. 3312 * 3313 * Returns the newly allocated structure or NULL in case or error 3314 */ 3315 static xmlSchemaAnnotPtr 3316 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3317 { 3318 xmlSchemaAnnotPtr ret; 3319 3320 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3321 if (ret == NULL) { 3322 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3323 return (NULL); 3324 } 3325 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3326 ret->content = node; 3327 return (ret); 3328 } 3329 3330 static xmlSchemaItemListPtr 3331 xmlSchemaItemListCreate(void) 3332 { 3333 xmlSchemaItemListPtr ret; 3334 3335 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3336 if (ret == NULL) { 3337 xmlSchemaPErrMemory(NULL, 3338 "allocating an item list structure", NULL); 3339 return (NULL); 3340 } 3341 memset(ret, 0, sizeof(xmlSchemaItemList)); 3342 return (ret); 3343 } 3344 3345 static void 3346 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3347 { 3348 if (list->items != NULL) { 3349 xmlFree(list->items); 3350 list->items = NULL; 3351 } 3352 list->nbItems = 0; 3353 list->sizeItems = 0; 3354 } 3355 3356 static int 3357 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3358 { 3359 if (list->items == NULL) { 3360 list->items = (void **) xmlMalloc( 3361 20 * sizeof(void *)); 3362 if (list->items == NULL) { 3363 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3364 return(-1); 3365 } 3366 list->sizeItems = 20; 3367 } else if (list->sizeItems <= list->nbItems) { 3368 list->sizeItems *= 2; 3369 list->items = (void **) xmlRealloc(list->items, 3370 list->sizeItems * sizeof(void *)); 3371 if (list->items == NULL) { 3372 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3373 list->sizeItems = 0; 3374 return(-1); 3375 } 3376 } 3377 list->items[list->nbItems++] = item; 3378 return(0); 3379 } 3380 3381 static int 3382 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3383 int initialSize, 3384 void *item) 3385 { 3386 if (list->items == NULL) { 3387 if (initialSize <= 0) 3388 initialSize = 1; 3389 list->items = (void **) xmlMalloc( 3390 initialSize * sizeof(void *)); 3391 if (list->items == NULL) { 3392 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3393 return(-1); 3394 } 3395 list->sizeItems = initialSize; 3396 } else if (list->sizeItems <= list->nbItems) { 3397 list->sizeItems *= 2; 3398 list->items = (void **) xmlRealloc(list->items, 3399 list->sizeItems * sizeof(void *)); 3400 if (list->items == NULL) { 3401 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3402 list->sizeItems = 0; 3403 return(-1); 3404 } 3405 } 3406 list->items[list->nbItems++] = item; 3407 return(0); 3408 } 3409 3410 static int 3411 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3412 { 3413 if (list->items == NULL) { 3414 list->items = (void **) xmlMalloc( 3415 20 * sizeof(void *)); 3416 if (list->items == NULL) { 3417 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3418 return(-1); 3419 } 3420 list->sizeItems = 20; 3421 } else if (list->sizeItems <= list->nbItems) { 3422 list->sizeItems *= 2; 3423 list->items = (void **) xmlRealloc(list->items, 3424 list->sizeItems * sizeof(void *)); 3425 if (list->items == NULL) { 3426 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3427 list->sizeItems = 0; 3428 return(-1); 3429 } 3430 } 3431 /* 3432 * Just append if the index is greater/equal than the item count. 3433 */ 3434 if (idx >= list->nbItems) { 3435 list->items[list->nbItems++] = item; 3436 } else { 3437 int i; 3438 for (i = list->nbItems; i > idx; i--) 3439 list->items[i] = list->items[i-1]; 3440 list->items[idx] = item; 3441 list->nbItems++; 3442 } 3443 return(0); 3444 } 3445 3446 #if 0 /* enable if ever needed */ 3447 static int 3448 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3449 int initialSize, 3450 void *item, 3451 int idx) 3452 { 3453 if (list->items == NULL) { 3454 if (initialSize <= 0) 3455 initialSize = 1; 3456 list->items = (void **) xmlMalloc( 3457 initialSize * sizeof(void *)); 3458 if (list->items == NULL) { 3459 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3460 return(-1); 3461 } 3462 list->sizeItems = initialSize; 3463 } else if (list->sizeItems <= list->nbItems) { 3464 list->sizeItems *= 2; 3465 list->items = (void **) xmlRealloc(list->items, 3466 list->sizeItems * sizeof(void *)); 3467 if (list->items == NULL) { 3468 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3469 list->sizeItems = 0; 3470 return(-1); 3471 } 3472 } 3473 /* 3474 * Just append if the index is greater/equal than the item count. 3475 */ 3476 if (idx >= list->nbItems) { 3477 list->items[list->nbItems++] = item; 3478 } else { 3479 int i; 3480 for (i = list->nbItems; i > idx; i--) 3481 list->items[i] = list->items[i-1]; 3482 list->items[idx] = item; 3483 list->nbItems++; 3484 } 3485 return(0); 3486 } 3487 #endif 3488 3489 static int 3490 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3491 { 3492 int i; 3493 if ((list->items == NULL) || (idx >= list->nbItems)) { 3494 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3495 "index error.\n"); 3496 return(-1); 3497 } 3498 3499 if (list->nbItems == 1) { 3500 /* TODO: Really free the list? */ 3501 xmlFree(list->items); 3502 list->items = NULL; 3503 list->nbItems = 0; 3504 list->sizeItems = 0; 3505 } else if (list->nbItems -1 == idx) { 3506 list->nbItems--; 3507 } else { 3508 for (i = idx; i < list->nbItems -1; i++) 3509 list->items[i] = list->items[i+1]; 3510 list->nbItems--; 3511 } 3512 return(0); 3513 } 3514 3515 /** 3516 * xmlSchemaItemListFree: 3517 * @annot: a schema type structure 3518 * 3519 * Deallocate a annotation structure 3520 */ 3521 static void 3522 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3523 { 3524 if (list == NULL) 3525 return; 3526 if (list->items != NULL) 3527 xmlFree(list->items); 3528 xmlFree(list); 3529 } 3530 3531 static void 3532 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3533 { 3534 if (bucket == NULL) 3535 return; 3536 if (bucket->globals != NULL) { 3537 xmlSchemaComponentListFree(bucket->globals); 3538 xmlSchemaItemListFree(bucket->globals); 3539 } 3540 if (bucket->locals != NULL) { 3541 xmlSchemaComponentListFree(bucket->locals); 3542 xmlSchemaItemListFree(bucket->locals); 3543 } 3544 if (bucket->relations != NULL) { 3545 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3546 do { 3547 prev = cur; 3548 cur = cur->next; 3549 xmlFree(prev); 3550 } while (cur != NULL); 3551 } 3552 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3553 xmlFreeDoc(bucket->doc); 3554 } 3555 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3556 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3557 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3558 } 3559 xmlFree(bucket); 3560 } 3561 3562 static void 3563 xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED) 3564 { 3565 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket); 3566 } 3567 3568 static xmlSchemaBucketPtr 3569 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3570 int type, const xmlChar *targetNamespace) 3571 { 3572 xmlSchemaBucketPtr ret; 3573 int size; 3574 xmlSchemaPtr mainSchema; 3575 3576 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3577 PERROR_INT("xmlSchemaBucketCreate", 3578 "no main schema on constructor"); 3579 return(NULL); 3580 } 3581 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3582 /* Create the schema bucket. */ 3583 if (WXS_IS_BUCKET_INCREDEF(type)) 3584 size = sizeof(xmlSchemaInclude); 3585 else 3586 size = sizeof(xmlSchemaImport); 3587 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3588 if (ret == NULL) { 3589 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3590 return(NULL); 3591 } 3592 memset(ret, 0, size); 3593 ret->targetNamespace = targetNamespace; 3594 ret->type = type; 3595 ret->globals = xmlSchemaItemListCreate(); 3596 if (ret->globals == NULL) { 3597 xmlFree(ret); 3598 return(NULL); 3599 } 3600 ret->locals = xmlSchemaItemListCreate(); 3601 if (ret->locals == NULL) { 3602 xmlFree(ret); 3603 return(NULL); 3604 } 3605 /* 3606 * The following will assure that only the first bucket is marked as 3607 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3608 * For each following import buckets an xmlSchema will be created. 3609 * An xmlSchema will be created for every distinct targetNamespace. 3610 * We assign the targetNamespace to the schemata here. 3611 */ 3612 if (! WXS_HAS_BUCKETS(pctxt)) { 3613 if (WXS_IS_BUCKET_INCREDEF(type)) { 3614 PERROR_INT("xmlSchemaBucketCreate", 3615 "first bucket but it's an include or redefine"); 3616 xmlSchemaBucketFree(ret); 3617 return(NULL); 3618 } 3619 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3620 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3621 /* Point to the *main* schema. */ 3622 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3623 WXS_IMPBUCKET(ret)->schema = mainSchema; 3624 /* 3625 * Ensure that the main schema gets a targetNamespace. 3626 */ 3627 mainSchema->targetNamespace = targetNamespace; 3628 } else { 3629 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3630 PERROR_INT("xmlSchemaBucketCreate", 3631 "main bucket but it's not the first one"); 3632 xmlSchemaBucketFree(ret); 3633 return(NULL); 3634 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3635 /* 3636 * Create a schema for imports and assign the 3637 * targetNamespace. 3638 */ 3639 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3640 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3641 xmlSchemaBucketFree(ret); 3642 return(NULL); 3643 } 3644 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3645 } 3646 } 3647 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3648 int res; 3649 /* 3650 * Imports go into the "schemasImports" slot of the main *schema*. 3651 * Note that we create an import entry for the main schema as well; i.e., 3652 * even if there's only one schema, we'll get an import. 3653 */ 3654 if (mainSchema->schemasImports == NULL) { 3655 mainSchema->schemasImports = xmlHashCreateDict(5, 3656 WXS_CONSTRUCTOR(pctxt)->dict); 3657 if (mainSchema->schemasImports == NULL) { 3658 xmlSchemaBucketFree(ret); 3659 return(NULL); 3660 } 3661 } 3662 if (targetNamespace == NULL) 3663 res = xmlHashAddEntry(mainSchema->schemasImports, 3664 XML_SCHEMAS_NO_NAMESPACE, ret); 3665 else 3666 res = xmlHashAddEntry(mainSchema->schemasImports, 3667 targetNamespace, ret); 3668 if (res != 0) { 3669 PERROR_INT("xmlSchemaBucketCreate", 3670 "failed to add the schema bucket to the hash"); 3671 xmlSchemaBucketFree(ret); 3672 return(NULL); 3673 } 3674 } else { 3675 /* Set the @ownerImport of an include bucket. */ 3676 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3677 WXS_INCBUCKET(ret)->ownerImport = 3678 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3679 else 3680 WXS_INCBUCKET(ret)->ownerImport = 3681 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3682 3683 /* Includes got into the "includes" slot of the *main* schema. */ 3684 if (mainSchema->includes == NULL) { 3685 mainSchema->includes = xmlSchemaItemListCreate(); 3686 if (mainSchema->includes == NULL) { 3687 xmlSchemaBucketFree(ret); 3688 return(NULL); 3689 } 3690 } 3691 xmlSchemaItemListAdd(mainSchema->includes, ret); 3692 } 3693 /* 3694 * Add to list of all buckets; this is used for lookup 3695 * during schema construction time only. 3696 */ 3697 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3698 return(NULL); 3699 return(ret); 3700 } 3701 3702 static int 3703 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3704 { 3705 if (*list == NULL) { 3706 *list = xmlSchemaItemListCreate(); 3707 if (*list == NULL) 3708 return(-1); 3709 } 3710 xmlSchemaItemListAddSize(*list, initialSize, item); 3711 return(0); 3712 } 3713 3714 /** 3715 * xmlSchemaFreeAnnot: 3716 * @annot: a schema type structure 3717 * 3718 * Deallocate a annotation structure 3719 */ 3720 static void 3721 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3722 { 3723 if (annot == NULL) 3724 return; 3725 if (annot->next == NULL) { 3726 xmlFree(annot); 3727 } else { 3728 xmlSchemaAnnotPtr prev; 3729 3730 do { 3731 prev = annot; 3732 annot = annot->next; 3733 xmlFree(prev); 3734 } while (annot != NULL); 3735 } 3736 } 3737 3738 /** 3739 * xmlSchemaFreeNotation: 3740 * @schema: a schema notation structure 3741 * 3742 * Deallocate a Schema Notation structure. 3743 */ 3744 static void 3745 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3746 { 3747 if (nota == NULL) 3748 return; 3749 xmlFree(nota); 3750 } 3751 3752 /** 3753 * xmlSchemaFreeAttribute: 3754 * @attr: an attribute declaration 3755 * 3756 * Deallocates an attribute declaration structure. 3757 */ 3758 static void 3759 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3760 { 3761 if (attr == NULL) 3762 return; 3763 if (attr->annot != NULL) 3764 xmlSchemaFreeAnnot(attr->annot); 3765 if (attr->defVal != NULL) 3766 xmlSchemaFreeValue(attr->defVal); 3767 xmlFree(attr); 3768 } 3769 3770 /** 3771 * xmlSchemaFreeAttributeUse: 3772 * @use: an attribute use 3773 * 3774 * Deallocates an attribute use structure. 3775 */ 3776 static void 3777 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3778 { 3779 if (use == NULL) 3780 return; 3781 if (use->annot != NULL) 3782 xmlSchemaFreeAnnot(use->annot); 3783 if (use->defVal != NULL) 3784 xmlSchemaFreeValue(use->defVal); 3785 xmlFree(use); 3786 } 3787 3788 /** 3789 * xmlSchemaFreeAttributeUseProhib: 3790 * @prohib: an attribute use prohibition 3791 * 3792 * Deallocates an attribute use structure. 3793 */ 3794 static void 3795 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3796 { 3797 if (prohib == NULL) 3798 return; 3799 xmlFree(prohib); 3800 } 3801 3802 /** 3803 * xmlSchemaFreeWildcardNsSet: 3804 * set: a schema wildcard namespace 3805 * 3806 * Deallocates a list of wildcard constraint structures. 3807 */ 3808 static void 3809 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3810 { 3811 xmlSchemaWildcardNsPtr next; 3812 3813 while (set != NULL) { 3814 next = set->next; 3815 xmlFree(set); 3816 set = next; 3817 } 3818 } 3819 3820 /** 3821 * xmlSchemaFreeWildcard: 3822 * @wildcard: a wildcard structure 3823 * 3824 * Deallocates a wildcard structure. 3825 */ 3826 void 3827 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3828 { 3829 if (wildcard == NULL) 3830 return; 3831 if (wildcard->annot != NULL) 3832 xmlSchemaFreeAnnot(wildcard->annot); 3833 if (wildcard->nsSet != NULL) 3834 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3835 if (wildcard->negNsSet != NULL) 3836 xmlFree(wildcard->negNsSet); 3837 xmlFree(wildcard); 3838 } 3839 3840 /** 3841 * xmlSchemaFreeAttributeGroup: 3842 * @schema: a schema attribute group structure 3843 * 3844 * Deallocate a Schema Attribute Group structure. 3845 */ 3846 static void 3847 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3848 { 3849 if (attrGr == NULL) 3850 return; 3851 if (attrGr->annot != NULL) 3852 xmlSchemaFreeAnnot(attrGr->annot); 3853 if (attrGr->attrUses != NULL) 3854 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3855 xmlFree(attrGr); 3856 } 3857 3858 /** 3859 * xmlSchemaFreeQNameRef: 3860 * @item: a QName reference structure 3861 * 3862 * Deallocatea a QName reference structure. 3863 */ 3864 static void 3865 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3866 { 3867 xmlFree(item); 3868 } 3869 3870 /** 3871 * xmlSchemaFreeTypeLinkList: 3872 * @alink: a type link 3873 * 3874 * Deallocate a list of types. 3875 */ 3876 static void 3877 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3878 { 3879 xmlSchemaTypeLinkPtr next; 3880 3881 while (link != NULL) { 3882 next = link->next; 3883 xmlFree(link); 3884 link = next; 3885 } 3886 } 3887 3888 static void 3889 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3890 { 3891 xmlSchemaIDCStateObjPtr next; 3892 while (sto != NULL) { 3893 next = sto->next; 3894 if (sto->history != NULL) 3895 xmlFree(sto->history); 3896 if (sto->xpathCtxt != NULL) 3897 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3898 xmlFree(sto); 3899 sto = next; 3900 } 3901 } 3902 3903 /** 3904 * xmlSchemaFreeIDC: 3905 * @idc: a identity-constraint definition 3906 * 3907 * Deallocates an identity-constraint definition. 3908 */ 3909 static void 3910 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3911 { 3912 xmlSchemaIDCSelectPtr cur, prev; 3913 3914 if (idcDef == NULL) 3915 return; 3916 if (idcDef->annot != NULL) 3917 xmlSchemaFreeAnnot(idcDef->annot); 3918 /* Selector */ 3919 if (idcDef->selector != NULL) { 3920 if (idcDef->selector->xpathComp != NULL) 3921 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3922 xmlFree(idcDef->selector); 3923 } 3924 /* Fields */ 3925 if (idcDef->fields != NULL) { 3926 cur = idcDef->fields; 3927 do { 3928 prev = cur; 3929 cur = cur->next; 3930 if (prev->xpathComp != NULL) 3931 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3932 xmlFree(prev); 3933 } while (cur != NULL); 3934 } 3935 xmlFree(idcDef); 3936 } 3937 3938 /** 3939 * xmlSchemaFreeElement: 3940 * @schema: a schema element structure 3941 * 3942 * Deallocate a Schema Element structure. 3943 */ 3944 static void 3945 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3946 { 3947 if (elem == NULL) 3948 return; 3949 if (elem->annot != NULL) 3950 xmlSchemaFreeAnnot(elem->annot); 3951 if (elem->contModel != NULL) 3952 xmlRegFreeRegexp(elem->contModel); 3953 if (elem->defVal != NULL) 3954 xmlSchemaFreeValue(elem->defVal); 3955 xmlFree(elem); 3956 } 3957 3958 /** 3959 * xmlSchemaFreeFacet: 3960 * @facet: a schema facet structure 3961 * 3962 * Deallocate a Schema Facet structure. 3963 */ 3964 void 3965 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3966 { 3967 if (facet == NULL) 3968 return; 3969 if (facet->val != NULL) 3970 xmlSchemaFreeValue(facet->val); 3971 if (facet->regexp != NULL) 3972 xmlRegFreeRegexp(facet->regexp); 3973 if (facet->annot != NULL) 3974 xmlSchemaFreeAnnot(facet->annot); 3975 xmlFree(facet); 3976 } 3977 3978 /** 3979 * xmlSchemaFreeType: 3980 * @type: a schema type structure 3981 * 3982 * Deallocate a Schema Type structure. 3983 */ 3984 void 3985 xmlSchemaFreeType(xmlSchemaTypePtr type) 3986 { 3987 if (type == NULL) 3988 return; 3989 if (type->annot != NULL) 3990 xmlSchemaFreeAnnot(type->annot); 3991 if (type->facets != NULL) { 3992 xmlSchemaFacetPtr facet, next; 3993 3994 facet = type->facets; 3995 while (facet != NULL) { 3996 next = facet->next; 3997 xmlSchemaFreeFacet(facet); 3998 facet = next; 3999 } 4000 } 4001 if (type->attrUses != NULL) 4002 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 4003 if (type->memberTypes != NULL) 4004 xmlSchemaFreeTypeLinkList(type->memberTypes); 4005 if (type->facetSet != NULL) { 4006 xmlSchemaFacetLinkPtr next, link; 4007 4008 link = type->facetSet; 4009 do { 4010 next = link->next; 4011 xmlFree(link); 4012 link = next; 4013 } while (link != NULL); 4014 } 4015 if (type->contModel != NULL) 4016 xmlRegFreeRegexp(type->contModel); 4017 xmlFree(type); 4018 } 4019 4020 /** 4021 * xmlSchemaFreeModelGroupDef: 4022 * @item: a schema model group definition 4023 * 4024 * Deallocates a schema model group definition. 4025 */ 4026 static void 4027 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4028 { 4029 if (item->annot != NULL) 4030 xmlSchemaFreeAnnot(item->annot); 4031 xmlFree(item); 4032 } 4033 4034 /** 4035 * xmlSchemaFreeModelGroup: 4036 * @item: a schema model group 4037 * 4038 * Deallocates a schema model group structure. 4039 */ 4040 static void 4041 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4042 { 4043 if (item->annot != NULL) 4044 xmlSchemaFreeAnnot(item->annot); 4045 xmlFree(item); 4046 } 4047 4048 static void 4049 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4050 { 4051 if ((list == NULL) || (list->nbItems == 0)) 4052 return; 4053 { 4054 xmlSchemaTreeItemPtr item; 4055 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4056 int i; 4057 4058 for (i = 0; i < list->nbItems; i++) { 4059 item = items[i]; 4060 if (item == NULL) 4061 continue; 4062 switch (item->type) { 4063 case XML_SCHEMA_TYPE_SIMPLE: 4064 case XML_SCHEMA_TYPE_COMPLEX: 4065 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4066 break; 4067 case XML_SCHEMA_TYPE_ATTRIBUTE: 4068 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4069 break; 4070 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4071 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4072 break; 4073 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4074 xmlSchemaFreeAttributeUseProhib( 4075 (xmlSchemaAttributeUseProhibPtr) item); 4076 break; 4077 case XML_SCHEMA_TYPE_ELEMENT: 4078 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4079 break; 4080 case XML_SCHEMA_TYPE_PARTICLE: 4081 if (item->annot != NULL) 4082 xmlSchemaFreeAnnot(item->annot); 4083 xmlFree(item); 4084 break; 4085 case XML_SCHEMA_TYPE_SEQUENCE: 4086 case XML_SCHEMA_TYPE_CHOICE: 4087 case XML_SCHEMA_TYPE_ALL: 4088 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4089 break; 4090 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4091 xmlSchemaFreeAttributeGroup( 4092 (xmlSchemaAttributeGroupPtr) item); 4093 break; 4094 case XML_SCHEMA_TYPE_GROUP: 4095 xmlSchemaFreeModelGroupDef( 4096 (xmlSchemaModelGroupDefPtr) item); 4097 break; 4098 case XML_SCHEMA_TYPE_ANY: 4099 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4100 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4101 break; 4102 case XML_SCHEMA_TYPE_IDC_KEY: 4103 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4104 case XML_SCHEMA_TYPE_IDC_KEYREF: 4105 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4106 break; 4107 case XML_SCHEMA_TYPE_NOTATION: 4108 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4109 break; 4110 case XML_SCHEMA_EXTRA_QNAMEREF: 4111 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4112 break; 4113 default: { 4114 /* TODO: This should never be hit. */ 4115 xmlSchemaPSimpleInternalErr(NULL, 4116 "Internal error: xmlSchemaComponentListFree, " 4117 "unexpected component type '%s'\n", 4118 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4119 } 4120 break; 4121 } 4122 } 4123 list->nbItems = 0; 4124 } 4125 } 4126 4127 /** 4128 * xmlSchemaFree: 4129 * @schema: a schema structure 4130 * 4131 * Deallocate a Schema structure. 4132 */ 4133 void 4134 xmlSchemaFree(xmlSchemaPtr schema) 4135 { 4136 if (schema == NULL) 4137 return; 4138 /* @volatiles is not used anymore :-/ */ 4139 if (schema->volatiles != NULL) 4140 TODO 4141 /* 4142 * Note that those slots are not responsible for freeing 4143 * schema components anymore; this will now be done by 4144 * the schema buckets. 4145 */ 4146 if (schema->notaDecl != NULL) 4147 xmlHashFree(schema->notaDecl, NULL); 4148 if (schema->attrDecl != NULL) 4149 xmlHashFree(schema->attrDecl, NULL); 4150 if (schema->attrgrpDecl != NULL) 4151 xmlHashFree(schema->attrgrpDecl, NULL); 4152 if (schema->elemDecl != NULL) 4153 xmlHashFree(schema->elemDecl, NULL); 4154 if (schema->typeDecl != NULL) 4155 xmlHashFree(schema->typeDecl, NULL); 4156 if (schema->groupDecl != NULL) 4157 xmlHashFree(schema->groupDecl, NULL); 4158 if (schema->idcDef != NULL) 4159 xmlHashFree(schema->idcDef, NULL); 4160 4161 if (schema->schemasImports != NULL) 4162 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry); 4163 if (schema->includes != NULL) { 4164 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4165 int i; 4166 for (i = 0; i < list->nbItems; i++) { 4167 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4168 } 4169 xmlSchemaItemListFree(list); 4170 } 4171 if (schema->annot != NULL) 4172 xmlSchemaFreeAnnot(schema->annot); 4173 /* Never free the doc here, since this will be done by the buckets. */ 4174 4175 xmlDictFree(schema->dict); 4176 xmlFree(schema); 4177 } 4178 4179 /************************************************************************ 4180 * * 4181 * Debug functions * 4182 * * 4183 ************************************************************************/ 4184 4185 #ifdef LIBXML_OUTPUT_ENABLED 4186 4187 static void 4188 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4189 4190 /** 4191 * xmlSchemaElementDump: 4192 * @elem: an element 4193 * @output: the file output 4194 * 4195 * Dump the element 4196 */ 4197 static void 4198 xmlSchemaElementDump(void *payload, void *data, 4199 const xmlChar * name ATTRIBUTE_UNUSED, 4200 const xmlChar * namespace ATTRIBUTE_UNUSED, 4201 const xmlChar * context ATTRIBUTE_UNUSED) 4202 { 4203 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload; 4204 FILE *output = (FILE *) data; 4205 if (elem == NULL) 4206 return; 4207 4208 4209 fprintf(output, "Element"); 4210 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4211 fprintf(output, " (global)"); 4212 fprintf(output, ": '%s' ", elem->name); 4213 if (namespace != NULL) 4214 fprintf(output, "ns '%s'", namespace); 4215 fprintf(output, "\n"); 4216 #if 0 4217 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4218 fprintf(output, " min %d ", elem->minOccurs); 4219 if (elem->maxOccurs >= UNBOUNDED) 4220 fprintf(output, "max: unbounded\n"); 4221 else if (elem->maxOccurs != 1) 4222 fprintf(output, "max: %d\n", elem->maxOccurs); 4223 else 4224 fprintf(output, "\n"); 4225 } 4226 #endif 4227 /* 4228 * Misc other properties. 4229 */ 4230 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4231 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4232 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4233 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4234 fprintf(output, " props: "); 4235 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4236 fprintf(output, "[fixed] "); 4237 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4238 fprintf(output, "[default] "); 4239 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4240 fprintf(output, "[abstract] "); 4241 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4242 fprintf(output, "[nillable] "); 4243 fprintf(output, "\n"); 4244 } 4245 /* 4246 * Default/fixed value. 4247 */ 4248 if (elem->value != NULL) 4249 fprintf(output, " value: '%s'\n", elem->value); 4250 /* 4251 * Type. 4252 */ 4253 if (elem->namedType != NULL) { 4254 fprintf(output, " type: '%s' ", elem->namedType); 4255 if (elem->namedTypeNs != NULL) 4256 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4257 else 4258 fprintf(output, "\n"); 4259 } else if (elem->subtypes != NULL) { 4260 /* 4261 * Dump local types. 4262 */ 4263 xmlSchemaTypeDump(elem->subtypes, output); 4264 } 4265 /* 4266 * Substitution group. 4267 */ 4268 if (elem->substGroup != NULL) { 4269 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4270 if (elem->substGroupNs != NULL) 4271 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4272 else 4273 fprintf(output, "\n"); 4274 } 4275 } 4276 4277 /** 4278 * xmlSchemaAnnotDump: 4279 * @output: the file output 4280 * @annot: a annotation 4281 * 4282 * Dump the annotation 4283 */ 4284 static void 4285 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4286 { 4287 xmlChar *content; 4288 4289 if (annot == NULL) 4290 return; 4291 4292 content = xmlNodeGetContent(annot->content); 4293 if (content != NULL) { 4294 fprintf(output, " Annot: %s\n", content); 4295 xmlFree(content); 4296 } else 4297 fprintf(output, " Annot: empty\n"); 4298 } 4299 4300 /** 4301 * xmlSchemaContentModelDump: 4302 * @particle: the schema particle 4303 * @output: the file output 4304 * @depth: the depth used for indentation 4305 * 4306 * Dump a SchemaType structure 4307 */ 4308 static void 4309 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4310 { 4311 xmlChar *str = NULL; 4312 xmlSchemaTreeItemPtr term; 4313 char shift[100]; 4314 int i; 4315 4316 if (particle == NULL) 4317 return; 4318 for (i = 0;((i < depth) && (i < 25));i++) 4319 shift[2 * i] = shift[2 * i + 1] = ' '; 4320 shift[2 * i] = shift[2 * i + 1] = 0; 4321 fprintf(output, "%s", shift); 4322 if (particle->children == NULL) { 4323 fprintf(output, "MISSING particle term\n"); 4324 return; 4325 } 4326 term = particle->children; 4327 if (term == NULL) { 4328 fprintf(output, "(NULL)"); 4329 } else { 4330 switch (term->type) { 4331 case XML_SCHEMA_TYPE_ELEMENT: 4332 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4333 ((xmlSchemaElementPtr)term)->targetNamespace, 4334 ((xmlSchemaElementPtr)term)->name)); 4335 FREE_AND_NULL(str); 4336 break; 4337 case XML_SCHEMA_TYPE_SEQUENCE: 4338 fprintf(output, "SEQUENCE"); 4339 break; 4340 case XML_SCHEMA_TYPE_CHOICE: 4341 fprintf(output, "CHOICE"); 4342 break; 4343 case XML_SCHEMA_TYPE_ALL: 4344 fprintf(output, "ALL"); 4345 break; 4346 case XML_SCHEMA_TYPE_ANY: 4347 fprintf(output, "ANY"); 4348 break; 4349 default: 4350 fprintf(output, "UNKNOWN\n"); 4351 return; 4352 } 4353 } 4354 if (particle->minOccurs != 1) 4355 fprintf(output, " min: %d", particle->minOccurs); 4356 if (particle->maxOccurs >= UNBOUNDED) 4357 fprintf(output, " max: unbounded"); 4358 else if (particle->maxOccurs != 1) 4359 fprintf(output, " max: %d", particle->maxOccurs); 4360 fprintf(output, "\n"); 4361 if (term && 4362 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4363 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4364 (term->type == XML_SCHEMA_TYPE_ALL)) && 4365 (term->children != NULL)) { 4366 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4367 output, depth +1); 4368 } 4369 if (particle->next != NULL) 4370 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4371 output, depth); 4372 } 4373 4374 /** 4375 * xmlSchemaAttrUsesDump: 4376 * @uses: attribute uses list 4377 * @output: the file output 4378 * 4379 * Dumps a list of attribute use components. 4380 */ 4381 static void 4382 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4383 { 4384 xmlSchemaAttributeUsePtr use; 4385 xmlSchemaAttributeUseProhibPtr prohib; 4386 xmlSchemaQNameRefPtr ref; 4387 const xmlChar *name, *tns; 4388 xmlChar *str = NULL; 4389 int i; 4390 4391 if ((uses == NULL) || (uses->nbItems == 0)) 4392 return; 4393 4394 fprintf(output, " attributes:\n"); 4395 for (i = 0; i < uses->nbItems; i++) { 4396 use = uses->items[i]; 4397 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4398 fprintf(output, " [prohibition] "); 4399 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4400 name = prohib->name; 4401 tns = prohib->targetNamespace; 4402 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4403 fprintf(output, " [reference] "); 4404 ref = (xmlSchemaQNameRefPtr) use; 4405 name = ref->name; 4406 tns = ref->targetNamespace; 4407 } else { 4408 fprintf(output, " [use] "); 4409 name = WXS_ATTRUSE_DECL_NAME(use); 4410 tns = WXS_ATTRUSE_DECL_TNS(use); 4411 } 4412 fprintf(output, "'%s'\n", 4413 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4414 FREE_AND_NULL(str); 4415 } 4416 } 4417 4418 /** 4419 * xmlSchemaTypeDump: 4420 * @output: the file output 4421 * @type: a type structure 4422 * 4423 * Dump a SchemaType structure 4424 */ 4425 static void 4426 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4427 { 4428 if (type == NULL) { 4429 fprintf(output, "Type: NULL\n"); 4430 return; 4431 } 4432 fprintf(output, "Type: "); 4433 if (type->name != NULL) 4434 fprintf(output, "'%s' ", type->name); 4435 else 4436 fprintf(output, "(no name) "); 4437 if (type->targetNamespace != NULL) 4438 fprintf(output, "ns '%s' ", type->targetNamespace); 4439 switch (type->type) { 4440 case XML_SCHEMA_TYPE_BASIC: 4441 fprintf(output, "[basic] "); 4442 break; 4443 case XML_SCHEMA_TYPE_SIMPLE: 4444 fprintf(output, "[simple] "); 4445 break; 4446 case XML_SCHEMA_TYPE_COMPLEX: 4447 fprintf(output, "[complex] "); 4448 break; 4449 case XML_SCHEMA_TYPE_SEQUENCE: 4450 fprintf(output, "[sequence] "); 4451 break; 4452 case XML_SCHEMA_TYPE_CHOICE: 4453 fprintf(output, "[choice] "); 4454 break; 4455 case XML_SCHEMA_TYPE_ALL: 4456 fprintf(output, "[all] "); 4457 break; 4458 case XML_SCHEMA_TYPE_UR: 4459 fprintf(output, "[ur] "); 4460 break; 4461 case XML_SCHEMA_TYPE_RESTRICTION: 4462 fprintf(output, "[restriction] "); 4463 break; 4464 case XML_SCHEMA_TYPE_EXTENSION: 4465 fprintf(output, "[extension] "); 4466 break; 4467 default: 4468 fprintf(output, "[unknown type %d] ", type->type); 4469 break; 4470 } 4471 fprintf(output, "content: "); 4472 switch (type->contentType) { 4473 case XML_SCHEMA_CONTENT_UNKNOWN: 4474 fprintf(output, "[unknown] "); 4475 break; 4476 case XML_SCHEMA_CONTENT_EMPTY: 4477 fprintf(output, "[empty] "); 4478 break; 4479 case XML_SCHEMA_CONTENT_ELEMENTS: 4480 fprintf(output, "[element] "); 4481 break; 4482 case XML_SCHEMA_CONTENT_MIXED: 4483 fprintf(output, "[mixed] "); 4484 break; 4485 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4486 /* not used. */ 4487 break; 4488 case XML_SCHEMA_CONTENT_BASIC: 4489 fprintf(output, "[basic] "); 4490 break; 4491 case XML_SCHEMA_CONTENT_SIMPLE: 4492 fprintf(output, "[simple] "); 4493 break; 4494 case XML_SCHEMA_CONTENT_ANY: 4495 fprintf(output, "[any] "); 4496 break; 4497 } 4498 fprintf(output, "\n"); 4499 if (type->base != NULL) { 4500 fprintf(output, " base type: '%s'", type->base); 4501 if (type->baseNs != NULL) 4502 fprintf(output, " ns '%s'\n", type->baseNs); 4503 else 4504 fprintf(output, "\n"); 4505 } 4506 if (type->attrUses != NULL) 4507 xmlSchemaAttrUsesDump(type->attrUses, output); 4508 if (type->annot != NULL) 4509 xmlSchemaAnnotDump(output, type->annot); 4510 #ifdef DUMP_CONTENT_MODEL 4511 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4512 (type->subtypes != NULL)) { 4513 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4514 output, 1); 4515 } 4516 #endif 4517 } 4518 4519 static void 4520 xmlSchemaTypeDumpEntry(void *type, void *output, 4521 const xmlChar *name ATTRIBUTE_UNUSED) 4522 { 4523 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output); 4524 } 4525 4526 /** 4527 * xmlSchemaDump: 4528 * @output: the file output 4529 * @schema: a schema structure 4530 * 4531 * Dump a Schema structure. 4532 */ 4533 void 4534 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4535 { 4536 if (output == NULL) 4537 return; 4538 if (schema == NULL) { 4539 fprintf(output, "Schemas: NULL\n"); 4540 return; 4541 } 4542 fprintf(output, "Schemas: "); 4543 if (schema->name != NULL) 4544 fprintf(output, "%s, ", schema->name); 4545 else 4546 fprintf(output, "no name, "); 4547 if (schema->targetNamespace != NULL) 4548 fprintf(output, "%s", (const char *) schema->targetNamespace); 4549 else 4550 fprintf(output, "no target namespace"); 4551 fprintf(output, "\n"); 4552 if (schema->annot != NULL) 4553 xmlSchemaAnnotDump(output, schema->annot); 4554 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output); 4555 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output); 4556 } 4557 4558 #ifdef DEBUG_IDC_NODE_TABLE 4559 /** 4560 * xmlSchemaDebugDumpIDCTable: 4561 * @vctxt: the WXS validation context 4562 * 4563 * Displays the current IDC table for debug purposes. 4564 */ 4565 static void 4566 xmlSchemaDebugDumpIDCTable(FILE * output, 4567 const xmlChar *namespaceName, 4568 const xmlChar *localName, 4569 xmlSchemaPSVIIDCBindingPtr bind) 4570 { 4571 xmlChar *str = NULL; 4572 const xmlChar *value; 4573 xmlSchemaPSVIIDCNodePtr tab; 4574 xmlSchemaPSVIIDCKeyPtr key; 4575 int i, j, res; 4576 4577 fprintf(output, "IDC: TABLES on '%s'\n", 4578 xmlSchemaFormatQName(&str, namespaceName, localName)); 4579 FREE_AND_NULL(str) 4580 4581 if (bind == NULL) 4582 return; 4583 do { 4584 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4585 xmlSchemaGetComponentQName(&str, 4586 bind->definition), bind->nbNodes); 4587 FREE_AND_NULL(str) 4588 for (i = 0; i < bind->nbNodes; i++) { 4589 tab = bind->nodeTable[i]; 4590 fprintf(output, " ( "); 4591 for (j = 0; j < bind->definition->nbFields; j++) { 4592 key = tab->keys[j]; 4593 if ((key != NULL) && (key->val != NULL)) { 4594 res = xmlSchemaGetCanonValue(key->val, &value); 4595 if (res >= 0) 4596 fprintf(output, "'%s' ", value); 4597 else 4598 fprintf(output, "CANON-VALUE-FAILED "); 4599 if (res == 0) 4600 FREE_AND_NULL(value) 4601 } else if (key != NULL) 4602 fprintf(output, "(no val), "); 4603 else 4604 fprintf(output, "(key missing), "); 4605 } 4606 fprintf(output, ")\n"); 4607 } 4608 if (bind->dupls && bind->dupls->nbItems) { 4609 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4610 for (i = 0; i < bind->dupls->nbItems; i++) { 4611 tab = bind->dupls->items[i]; 4612 fprintf(output, " ( "); 4613 for (j = 0; j < bind->definition->nbFields; j++) { 4614 key = tab->keys[j]; 4615 if ((key != NULL) && (key->val != NULL)) { 4616 res = xmlSchemaGetCanonValue(key->val, &value); 4617 if (res >= 0) 4618 fprintf(output, "'%s' ", value); 4619 else 4620 fprintf(output, "CANON-VALUE-FAILED "); 4621 if (res == 0) 4622 FREE_AND_NULL(value) 4623 } else if (key != NULL) 4624 fprintf(output, "(no val), "); 4625 else 4626 fprintf(output, "(key missing), "); 4627 } 4628 fprintf(output, ")\n"); 4629 } 4630 } 4631 bind = bind->next; 4632 } while (bind != NULL); 4633 } 4634 #endif /* DEBUG_IDC */ 4635 #endif /* LIBXML_OUTPUT_ENABLED */ 4636 4637 /************************************************************************ 4638 * * 4639 * Utilities * 4640 * * 4641 ************************************************************************/ 4642 4643 /** 4644 * xmlSchemaGetPropNode: 4645 * @node: the element node 4646 * @name: the name of the attribute 4647 * 4648 * Seeks an attribute with a name of @name in 4649 * no namespace. 4650 * 4651 * Returns the attribute or NULL if not present. 4652 */ 4653 static xmlAttrPtr 4654 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4655 { 4656 xmlAttrPtr prop; 4657 4658 if ((node == NULL) || (name == NULL)) 4659 return(NULL); 4660 prop = node->properties; 4661 while (prop != NULL) { 4662 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4663 return(prop); 4664 prop = prop->next; 4665 } 4666 return (NULL); 4667 } 4668 4669 /** 4670 * xmlSchemaGetPropNodeNs: 4671 * @node: the element node 4672 * @uri: the uri 4673 * @name: the name of the attribute 4674 * 4675 * Seeks an attribute with a local name of @name and 4676 * a namespace URI of @uri. 4677 * 4678 * Returns the attribute or NULL if not present. 4679 */ 4680 static xmlAttrPtr 4681 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4682 { 4683 xmlAttrPtr prop; 4684 4685 if ((node == NULL) || (name == NULL)) 4686 return(NULL); 4687 prop = node->properties; 4688 while (prop != NULL) { 4689 if ((prop->ns != NULL) && 4690 xmlStrEqual(prop->name, BAD_CAST name) && 4691 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4692 return(prop); 4693 prop = prop->next; 4694 } 4695 return (NULL); 4696 } 4697 4698 static const xmlChar * 4699 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4700 { 4701 xmlChar *val; 4702 const xmlChar *ret; 4703 4704 val = xmlNodeGetContent(node); 4705 if (val == NULL) 4706 val = xmlStrdup((xmlChar *)""); 4707 ret = xmlDictLookup(ctxt->dict, val, -1); 4708 xmlFree(val); 4709 return(ret); 4710 } 4711 4712 static const xmlChar * 4713 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4714 { 4715 return((const xmlChar*) xmlNodeGetContent(node)); 4716 } 4717 4718 /** 4719 * xmlSchemaGetProp: 4720 * @ctxt: the parser context 4721 * @node: the node 4722 * @name: the property name 4723 * 4724 * Read a attribute value and internalize the string 4725 * 4726 * Returns the string or NULL if not present. 4727 */ 4728 static const xmlChar * 4729 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4730 const char *name) 4731 { 4732 xmlChar *val; 4733 const xmlChar *ret; 4734 4735 val = xmlGetNoNsProp(node, BAD_CAST name); 4736 if (val == NULL) 4737 return(NULL); 4738 ret = xmlDictLookup(ctxt->dict, val, -1); 4739 xmlFree(val); 4740 return(ret); 4741 } 4742 4743 /************************************************************************ 4744 * * 4745 * Parsing functions * 4746 * * 4747 ************************************************************************/ 4748 4749 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4750 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4751 ret = xmlHashLookup(schema->slot, name); \ 4752 if (ret != NULL) goto exit; \ 4753 } \ 4754 if (xmlHashSize(schema->schemasImports) > 1) { \ 4755 xmlSchemaImportPtr import; \ 4756 if (nsName == NULL) \ 4757 import = xmlHashLookup(schema->schemasImports, \ 4758 XML_SCHEMAS_NO_NAMESPACE); \ 4759 else \ 4760 import = xmlHashLookup(schema->schemasImports, nsName); \ 4761 if (import == NULL) \ 4762 goto exit; \ 4763 ret = xmlHashLookup(import->schema->slot, name); \ 4764 } 4765 4766 /** 4767 * xmlSchemaGetElem: 4768 * @schema: the schema context 4769 * @name: the element name 4770 * @ns: the element namespace 4771 * 4772 * Lookup a global element declaration in the schema. 4773 * 4774 * Returns the element declaration or NULL if not found. 4775 */ 4776 static xmlSchemaElementPtr 4777 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4778 const xmlChar * nsName) 4779 { 4780 xmlSchemaElementPtr ret = NULL; 4781 4782 if ((name == NULL) || (schema == NULL)) 4783 return(NULL); 4784 if (schema != NULL) { 4785 WXS_FIND_GLOBAL_ITEM(elemDecl) 4786 } 4787 exit: 4788 #ifdef DEBUG 4789 if (ret == NULL) { 4790 if (nsName == NULL) 4791 fprintf(stderr, "Unable to lookup element decl. %s", name); 4792 else 4793 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4794 nsName); 4795 } 4796 #endif 4797 return (ret); 4798 } 4799 4800 /** 4801 * xmlSchemaGetType: 4802 * @schema: the main schema 4803 * @name: the type's name 4804 * nsName: the type's namespace 4805 * 4806 * Lookup a type in the schemas or the predefined types 4807 * 4808 * Returns the group definition or NULL if not found. 4809 */ 4810 static xmlSchemaTypePtr 4811 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4812 const xmlChar * nsName) 4813 { 4814 xmlSchemaTypePtr ret = NULL; 4815 4816 if (name == NULL) 4817 return (NULL); 4818 /* First try the built-in types. */ 4819 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4820 ret = xmlSchemaGetPredefinedType(name, nsName); 4821 if (ret != NULL) 4822 goto exit; 4823 /* 4824 * Note that we try the parsed schemas as well here 4825 * since one might have parsed the S4S, which contain more 4826 * than the built-in types. 4827 * TODO: Can we optimize this? 4828 */ 4829 } 4830 if (schema != NULL) { 4831 WXS_FIND_GLOBAL_ITEM(typeDecl) 4832 } 4833 exit: 4834 4835 #ifdef DEBUG 4836 if (ret == NULL) { 4837 if (nsName == NULL) 4838 fprintf(stderr, "Unable to lookup type %s", name); 4839 else 4840 fprintf(stderr, "Unable to lookup type %s:%s", name, 4841 nsName); 4842 } 4843 #endif 4844 return (ret); 4845 } 4846 4847 /** 4848 * xmlSchemaGetAttributeDecl: 4849 * @schema: the context of the schema 4850 * @name: the name of the attribute 4851 * @ns: the target namespace of the attribute 4852 * 4853 * Lookup a an attribute in the schema or imported schemas 4854 * 4855 * Returns the attribute declaration or NULL if not found. 4856 */ 4857 static xmlSchemaAttributePtr 4858 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4859 const xmlChar * nsName) 4860 { 4861 xmlSchemaAttributePtr ret = NULL; 4862 4863 if ((name == NULL) || (schema == NULL)) 4864 return (NULL); 4865 if (schema != NULL) { 4866 WXS_FIND_GLOBAL_ITEM(attrDecl) 4867 } 4868 exit: 4869 #ifdef DEBUG 4870 if (ret == NULL) { 4871 if (nsName == NULL) 4872 fprintf(stderr, "Unable to lookup attribute %s", name); 4873 else 4874 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4875 nsName); 4876 } 4877 #endif 4878 return (ret); 4879 } 4880 4881 /** 4882 * xmlSchemaGetAttributeGroup: 4883 * @schema: the context of the schema 4884 * @name: the name of the attribute group 4885 * @ns: the target namespace of the attribute group 4886 * 4887 * Lookup a an attribute group in the schema or imported schemas 4888 * 4889 * Returns the attribute group definition or NULL if not found. 4890 */ 4891 static xmlSchemaAttributeGroupPtr 4892 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4893 const xmlChar * nsName) 4894 { 4895 xmlSchemaAttributeGroupPtr ret = NULL; 4896 4897 if ((name == NULL) || (schema == NULL)) 4898 return (NULL); 4899 if (schema != NULL) { 4900 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4901 } 4902 exit: 4903 /* TODO: 4904 if ((ret != NULL) && (ret->redef != NULL)) { 4905 * Return the last redefinition. * 4906 ret = ret->redef; 4907 } 4908 */ 4909 #ifdef DEBUG 4910 if (ret == NULL) { 4911 if (nsName == NULL) 4912 fprintf(stderr, "Unable to lookup attribute group %s", name); 4913 else 4914 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4915 nsName); 4916 } 4917 #endif 4918 return (ret); 4919 } 4920 4921 /** 4922 * xmlSchemaGetGroup: 4923 * @schema: the context of the schema 4924 * @name: the name of the group 4925 * @ns: the target namespace of the group 4926 * 4927 * Lookup a group in the schema or imported schemas 4928 * 4929 * Returns the group definition or NULL if not found. 4930 */ 4931 static xmlSchemaModelGroupDefPtr 4932 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4933 const xmlChar * nsName) 4934 { 4935 xmlSchemaModelGroupDefPtr ret = NULL; 4936 4937 if ((name == NULL) || (schema == NULL)) 4938 return (NULL); 4939 if (schema != NULL) { 4940 WXS_FIND_GLOBAL_ITEM(groupDecl) 4941 } 4942 exit: 4943 4944 #ifdef DEBUG 4945 if (ret == NULL) { 4946 if (nsName == NULL) 4947 fprintf(stderr, "Unable to lookup group %s", name); 4948 else 4949 fprintf(stderr, "Unable to lookup group %s:%s", name, 4950 nsName); 4951 } 4952 #endif 4953 return (ret); 4954 } 4955 4956 static xmlSchemaNotationPtr 4957 xmlSchemaGetNotation(xmlSchemaPtr schema, 4958 const xmlChar *name, 4959 const xmlChar *nsName) 4960 { 4961 xmlSchemaNotationPtr ret = NULL; 4962 4963 if ((name == NULL) || (schema == NULL)) 4964 return (NULL); 4965 if (schema != NULL) { 4966 WXS_FIND_GLOBAL_ITEM(notaDecl) 4967 } 4968 exit: 4969 return (ret); 4970 } 4971 4972 static xmlSchemaIDCPtr 4973 xmlSchemaGetIDC(xmlSchemaPtr schema, 4974 const xmlChar *name, 4975 const xmlChar *nsName) 4976 { 4977 xmlSchemaIDCPtr ret = NULL; 4978 4979 if ((name == NULL) || (schema == NULL)) 4980 return (NULL); 4981 if (schema != NULL) { 4982 WXS_FIND_GLOBAL_ITEM(idcDef) 4983 } 4984 exit: 4985 return (ret); 4986 } 4987 4988 /** 4989 * xmlSchemaGetNamedComponent: 4990 * @schema: the schema 4991 * @name: the name of the group 4992 * @ns: the target namespace of the group 4993 * 4994 * Lookup a group in the schema or imported schemas 4995 * 4996 * Returns the group definition or NULL if not found. 4997 */ 4998 static xmlSchemaBasicItemPtr 4999 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 5000 xmlSchemaTypeType itemType, 5001 const xmlChar *name, 5002 const xmlChar *targetNs) 5003 { 5004 switch (itemType) { 5005 case XML_SCHEMA_TYPE_GROUP: 5006 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 5007 name, targetNs)); 5008 case XML_SCHEMA_TYPE_ELEMENT: 5009 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 5010 name, targetNs)); 5011 default: 5012 TODO 5013 return (NULL); 5014 } 5015 } 5016 5017 /************************************************************************ 5018 * * 5019 * Parsing functions * 5020 * * 5021 ************************************************************************/ 5022 5023 #define IS_BLANK_NODE(n) \ 5024 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 5025 5026 /** 5027 * xmlSchemaIsBlank: 5028 * @str: a string 5029 * @len: the length of the string or -1 5030 * 5031 * Check if a string is ignorable 5032 * 5033 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5034 */ 5035 static int 5036 xmlSchemaIsBlank(xmlChar * str, int len) 5037 { 5038 if (str == NULL) 5039 return (1); 5040 if (len < 0) { 5041 while (*str != 0) { 5042 if (!(IS_BLANK_CH(*str))) 5043 return (0); 5044 str++; 5045 } 5046 } else while ((*str != 0) && (len != 0)) { 5047 if (!(IS_BLANK_CH(*str))) 5048 return (0); 5049 str++; 5050 len--; 5051 } 5052 5053 return (1); 5054 } 5055 5056 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5057 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5058 /* 5059 * xmlSchemaFindRedefCompInGraph: 5060 * ATTENTION TODO: This uses pointer comp. for strings. 5061 */ 5062 static xmlSchemaBasicItemPtr 5063 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5064 xmlSchemaTypeType type, 5065 const xmlChar *name, 5066 const xmlChar *nsName) 5067 { 5068 xmlSchemaBasicItemPtr ret; 5069 int i; 5070 5071 if ((bucket == NULL) || (name == NULL)) 5072 return(NULL); 5073 if ((bucket->globals == NULL) || 5074 (bucket->globals->nbItems == 0)) 5075 goto subschemas; 5076 /* 5077 * Search in global components. 5078 */ 5079 for (i = 0; i < bucket->globals->nbItems; i++) { 5080 ret = bucket->globals->items[i]; 5081 if (ret->type == type) { 5082 switch (type) { 5083 case XML_SCHEMA_TYPE_COMPLEX: 5084 case XML_SCHEMA_TYPE_SIMPLE: 5085 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5086 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5087 nsName)) 5088 { 5089 return(ret); 5090 } 5091 break; 5092 case XML_SCHEMA_TYPE_GROUP: 5093 if ((WXS_COMP_NAME(ret, 5094 xmlSchemaModelGroupDefPtr) == name) && 5095 (WXS_COMP_TNS(ret, 5096 xmlSchemaModelGroupDefPtr) == nsName)) 5097 { 5098 return(ret); 5099 } 5100 break; 5101 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5102 if ((WXS_COMP_NAME(ret, 5103 xmlSchemaAttributeGroupPtr) == name) && 5104 (WXS_COMP_TNS(ret, 5105 xmlSchemaAttributeGroupPtr) == nsName)) 5106 { 5107 return(ret); 5108 } 5109 break; 5110 default: 5111 /* Should not be hit. */ 5112 return(NULL); 5113 } 5114 } 5115 } 5116 subschemas: 5117 /* 5118 * Process imported/included schemas. 5119 */ 5120 if (bucket->relations != NULL) { 5121 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5122 5123 /* 5124 * TODO: Marking the bucket will not avoid multiple searches 5125 * in the same schema, but avoids at least circularity. 5126 */ 5127 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5128 do { 5129 if ((rel->bucket != NULL) && 5130 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5131 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5132 type, name, nsName); 5133 if (ret != NULL) 5134 return(ret); 5135 } 5136 rel = rel->next; 5137 } while (rel != NULL); 5138 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5139 } 5140 return(NULL); 5141 } 5142 5143 /** 5144 * xmlSchemaAddNotation: 5145 * @ctxt: a schema parser context 5146 * @schema: the schema being built 5147 * @name: the item name 5148 * 5149 * Add an XML schema annotation declaration 5150 * *WARNING* this interface is highly subject to change 5151 * 5152 * Returns the new structure or NULL in case of error 5153 */ 5154 static xmlSchemaNotationPtr 5155 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5156 const xmlChar *name, const xmlChar *nsName, 5157 xmlNodePtr node ATTRIBUTE_UNUSED) 5158 { 5159 xmlSchemaNotationPtr ret = NULL; 5160 5161 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5162 return (NULL); 5163 5164 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5165 if (ret == NULL) { 5166 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5167 return (NULL); 5168 } 5169 memset(ret, 0, sizeof(xmlSchemaNotation)); 5170 ret->type = XML_SCHEMA_TYPE_NOTATION; 5171 ret->name = name; 5172 ret->targetNamespace = nsName; 5173 /* TODO: do we need the node to be set? 5174 * ret->node = node;*/ 5175 WXS_ADD_GLOBAL(ctxt, ret); 5176 return (ret); 5177 } 5178 5179 /** 5180 * xmlSchemaAddAttribute: 5181 * @ctxt: a schema parser context 5182 * @schema: the schema being built 5183 * @name: the item name 5184 * @namespace: the namespace 5185 * 5186 * Add an XML schema Attribute declaration 5187 * *WARNING* this interface is highly subject to change 5188 * 5189 * Returns the new structure or NULL in case of error 5190 */ 5191 static xmlSchemaAttributePtr 5192 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5193 const xmlChar * name, const xmlChar * nsName, 5194 xmlNodePtr node, int topLevel) 5195 { 5196 xmlSchemaAttributePtr ret = NULL; 5197 5198 if ((ctxt == NULL) || (schema == NULL)) 5199 return (NULL); 5200 5201 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5202 if (ret == NULL) { 5203 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5204 return (NULL); 5205 } 5206 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5207 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5208 ret->node = node; 5209 ret->name = name; 5210 ret->targetNamespace = nsName; 5211 5212 if (topLevel) 5213 WXS_ADD_GLOBAL(ctxt, ret); 5214 else 5215 WXS_ADD_LOCAL(ctxt, ret); 5216 WXS_ADD_PENDING(ctxt, ret); 5217 return (ret); 5218 } 5219 5220 /** 5221 * xmlSchemaAddAttributeUse: 5222 * @ctxt: a schema parser context 5223 * @schema: the schema being built 5224 * @name: the item name 5225 * @namespace: the namespace 5226 * 5227 * Add an XML schema Attribute declaration 5228 * *WARNING* this interface is highly subject to change 5229 * 5230 * Returns the new structure or NULL in case of error 5231 */ 5232 static xmlSchemaAttributeUsePtr 5233 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5234 xmlNodePtr node) 5235 { 5236 xmlSchemaAttributeUsePtr ret = NULL; 5237 5238 if (pctxt == NULL) 5239 return (NULL); 5240 5241 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5242 if (ret == NULL) { 5243 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5244 return (NULL); 5245 } 5246 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5247 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5248 ret->node = node; 5249 5250 WXS_ADD_LOCAL(pctxt, ret); 5251 return (ret); 5252 } 5253 5254 /* 5255 * xmlSchemaAddRedef: 5256 * 5257 * Adds a redefinition information. This is used at a later stage to: 5258 * resolve references to the redefined components and to check constraints. 5259 */ 5260 static xmlSchemaRedefPtr 5261 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5262 xmlSchemaBucketPtr targetBucket, 5263 void *item, 5264 const xmlChar *refName, 5265 const xmlChar *refTargetNs) 5266 { 5267 xmlSchemaRedefPtr ret; 5268 5269 ret = (xmlSchemaRedefPtr) 5270 xmlMalloc(sizeof(xmlSchemaRedef)); 5271 if (ret == NULL) { 5272 xmlSchemaPErrMemory(pctxt, 5273 "allocating redefinition info", NULL); 5274 return (NULL); 5275 } 5276 memset(ret, 0, sizeof(xmlSchemaRedef)); 5277 ret->item = item; 5278 ret->targetBucket = targetBucket; 5279 ret->refName = refName; 5280 ret->refTargetNs = refTargetNs; 5281 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5282 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5283 else 5284 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5285 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5286 5287 return (ret); 5288 } 5289 5290 /** 5291 * xmlSchemaAddAttributeGroupDefinition: 5292 * @ctxt: a schema parser context 5293 * @schema: the schema being built 5294 * @name: the item name 5295 * @nsName: the target namespace 5296 * @node: the corresponding node 5297 * 5298 * Add an XML schema Attribute Group definition. 5299 * 5300 * Returns the new structure or NULL in case of error 5301 */ 5302 static xmlSchemaAttributeGroupPtr 5303 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5304 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5305 const xmlChar *name, 5306 const xmlChar *nsName, 5307 xmlNodePtr node) 5308 { 5309 xmlSchemaAttributeGroupPtr ret = NULL; 5310 5311 if ((pctxt == NULL) || (name == NULL)) 5312 return (NULL); 5313 5314 ret = (xmlSchemaAttributeGroupPtr) 5315 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5316 if (ret == NULL) { 5317 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5318 return (NULL); 5319 } 5320 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5321 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5322 ret->name = name; 5323 ret->targetNamespace = nsName; 5324 ret->node = node; 5325 5326 /* TODO: Remove the flag. */ 5327 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5328 if (pctxt->isRedefine) { 5329 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5330 ret, name, nsName); 5331 if (pctxt->redef == NULL) { 5332 xmlFree(ret); 5333 return(NULL); 5334 } 5335 pctxt->redefCounter = 0; 5336 } 5337 WXS_ADD_GLOBAL(pctxt, ret); 5338 WXS_ADD_PENDING(pctxt, ret); 5339 return (ret); 5340 } 5341 5342 /** 5343 * xmlSchemaAddElement: 5344 * @ctxt: a schema parser context 5345 * @schema: the schema being built 5346 * @name: the type name 5347 * @namespace: the type namespace 5348 * 5349 * Add an XML schema Element declaration 5350 * *WARNING* this interface is highly subject to change 5351 * 5352 * Returns the new structure or NULL in case of error 5353 */ 5354 static xmlSchemaElementPtr 5355 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5356 const xmlChar * name, const xmlChar * nsName, 5357 xmlNodePtr node, int topLevel) 5358 { 5359 xmlSchemaElementPtr ret = NULL; 5360 5361 if ((ctxt == NULL) || (name == NULL)) 5362 return (NULL); 5363 5364 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5365 if (ret == NULL) { 5366 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5367 return (NULL); 5368 } 5369 memset(ret, 0, sizeof(xmlSchemaElement)); 5370 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5371 ret->name = name; 5372 ret->targetNamespace = nsName; 5373 ret->node = node; 5374 5375 if (topLevel) 5376 WXS_ADD_GLOBAL(ctxt, ret); 5377 else 5378 WXS_ADD_LOCAL(ctxt, ret); 5379 WXS_ADD_PENDING(ctxt, ret); 5380 return (ret); 5381 } 5382 5383 /** 5384 * xmlSchemaAddType: 5385 * @ctxt: a schema parser context 5386 * @schema: the schema being built 5387 * @name: the item name 5388 * @namespace: the namespace 5389 * 5390 * Add an XML schema item 5391 * *WARNING* this interface is highly subject to change 5392 * 5393 * Returns the new structure or NULL in case of error 5394 */ 5395 static xmlSchemaTypePtr 5396 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5397 xmlSchemaTypeType type, 5398 const xmlChar * name, const xmlChar * nsName, 5399 xmlNodePtr node, int topLevel) 5400 { 5401 xmlSchemaTypePtr ret = NULL; 5402 5403 if ((ctxt == NULL) || (schema == NULL)) 5404 return (NULL); 5405 5406 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5407 if (ret == NULL) { 5408 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5409 return (NULL); 5410 } 5411 memset(ret, 0, sizeof(xmlSchemaType)); 5412 ret->type = type; 5413 ret->name = name; 5414 ret->targetNamespace = nsName; 5415 ret->node = node; 5416 if (topLevel) { 5417 if (ctxt->isRedefine) { 5418 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5419 ret, name, nsName); 5420 if (ctxt->redef == NULL) { 5421 xmlFree(ret); 5422 return(NULL); 5423 } 5424 ctxt->redefCounter = 0; 5425 } 5426 WXS_ADD_GLOBAL(ctxt, ret); 5427 } else 5428 WXS_ADD_LOCAL(ctxt, ret); 5429 WXS_ADD_PENDING(ctxt, ret); 5430 return (ret); 5431 } 5432 5433 static xmlSchemaQNameRefPtr 5434 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5435 xmlSchemaTypeType refType, 5436 const xmlChar *refName, 5437 const xmlChar *refNs) 5438 { 5439 xmlSchemaQNameRefPtr ret; 5440 5441 ret = (xmlSchemaQNameRefPtr) 5442 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5443 if (ret == NULL) { 5444 xmlSchemaPErrMemory(pctxt, 5445 "allocating QName reference item", NULL); 5446 return (NULL); 5447 } 5448 ret->node = NULL; 5449 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5450 ret->name = refName; 5451 ret->targetNamespace = refNs; 5452 ret->item = NULL; 5453 ret->itemType = refType; 5454 /* 5455 * Store the reference item in the schema. 5456 */ 5457 WXS_ADD_LOCAL(pctxt, ret); 5458 return (ret); 5459 } 5460 5461 static xmlSchemaAttributeUseProhibPtr 5462 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5463 { 5464 xmlSchemaAttributeUseProhibPtr ret; 5465 5466 ret = (xmlSchemaAttributeUseProhibPtr) 5467 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5468 if (ret == NULL) { 5469 xmlSchemaPErrMemory(pctxt, 5470 "allocating attribute use prohibition", NULL); 5471 return (NULL); 5472 } 5473 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5474 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5475 WXS_ADD_LOCAL(pctxt, ret); 5476 return (ret); 5477 } 5478 5479 5480 /** 5481 * xmlSchemaAddModelGroup: 5482 * @ctxt: a schema parser context 5483 * @schema: the schema being built 5484 * @type: the "compositor" type of the model group 5485 * @node: the node in the schema doc 5486 * 5487 * Adds a schema model group 5488 * *WARNING* this interface is highly subject to change 5489 * 5490 * Returns the new structure or NULL in case of error 5491 */ 5492 static xmlSchemaModelGroupPtr 5493 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5494 xmlSchemaPtr schema, 5495 xmlSchemaTypeType type, 5496 xmlNodePtr node) 5497 { 5498 xmlSchemaModelGroupPtr ret = NULL; 5499 5500 if ((ctxt == NULL) || (schema == NULL)) 5501 return (NULL); 5502 5503 ret = (xmlSchemaModelGroupPtr) 5504 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5505 if (ret == NULL) { 5506 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5507 NULL); 5508 return (NULL); 5509 } 5510 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5511 ret->type = type; 5512 ret->node = node; 5513 WXS_ADD_LOCAL(ctxt, ret); 5514 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5515 (type == XML_SCHEMA_TYPE_CHOICE)) 5516 WXS_ADD_PENDING(ctxt, ret); 5517 return (ret); 5518 } 5519 5520 5521 /** 5522 * xmlSchemaAddParticle: 5523 * @ctxt: a schema parser context 5524 * @schema: the schema being built 5525 * @node: the corresponding node in the schema doc 5526 * @min: the minOccurs 5527 * @max: the maxOccurs 5528 * 5529 * Adds an XML schema particle component. 5530 * *WARNING* this interface is highly subject to change 5531 * 5532 * Returns the new structure or NULL in case of error 5533 */ 5534 static xmlSchemaParticlePtr 5535 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5536 xmlNodePtr node, int min, int max) 5537 { 5538 xmlSchemaParticlePtr ret = NULL; 5539 if (ctxt == NULL) 5540 return (NULL); 5541 5542 #ifdef DEBUG 5543 fprintf(stderr, "Adding particle component\n"); 5544 #endif 5545 ret = (xmlSchemaParticlePtr) 5546 xmlMalloc(sizeof(xmlSchemaParticle)); 5547 if (ret == NULL) { 5548 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5549 NULL); 5550 return (NULL); 5551 } 5552 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5553 ret->annot = NULL; 5554 ret->node = node; 5555 ret->minOccurs = min; 5556 ret->maxOccurs = max; 5557 ret->next = NULL; 5558 ret->children = NULL; 5559 5560 WXS_ADD_LOCAL(ctxt, ret); 5561 /* 5562 * Note that addition to pending components will be done locally 5563 * to the specific parsing function, since the most particles 5564 * need not to be fixed up (i.e. the reference to be resolved). 5565 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5566 */ 5567 return (ret); 5568 } 5569 5570 /** 5571 * xmlSchemaAddModelGroupDefinition: 5572 * @ctxt: a schema validation context 5573 * @schema: the schema being built 5574 * @name: the group name 5575 * 5576 * Add an XML schema Group definition 5577 * 5578 * Returns the new structure or NULL in case of error 5579 */ 5580 static xmlSchemaModelGroupDefPtr 5581 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5582 xmlSchemaPtr schema, 5583 const xmlChar *name, 5584 const xmlChar *nsName, 5585 xmlNodePtr node) 5586 { 5587 xmlSchemaModelGroupDefPtr ret = NULL; 5588 5589 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5590 return (NULL); 5591 5592 ret = (xmlSchemaModelGroupDefPtr) 5593 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5594 if (ret == NULL) { 5595 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5596 return (NULL); 5597 } 5598 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5599 ret->name = name; 5600 ret->type = XML_SCHEMA_TYPE_GROUP; 5601 ret->node = node; 5602 ret->targetNamespace = nsName; 5603 5604 if (ctxt->isRedefine) { 5605 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5606 ret, name, nsName); 5607 if (ctxt->redef == NULL) { 5608 xmlFree(ret); 5609 return(NULL); 5610 } 5611 ctxt->redefCounter = 0; 5612 } 5613 WXS_ADD_GLOBAL(ctxt, ret); 5614 WXS_ADD_PENDING(ctxt, ret); 5615 return (ret); 5616 } 5617 5618 /** 5619 * xmlSchemaNewWildcardNs: 5620 * @ctxt: a schema validation context 5621 * 5622 * Creates a new wildcard namespace constraint. 5623 * 5624 * Returns the new structure or NULL in case of error 5625 */ 5626 static xmlSchemaWildcardNsPtr 5627 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5628 { 5629 xmlSchemaWildcardNsPtr ret; 5630 5631 ret = (xmlSchemaWildcardNsPtr) 5632 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5633 if (ret == NULL) { 5634 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5635 return (NULL); 5636 } 5637 ret->value = NULL; 5638 ret->next = NULL; 5639 return (ret); 5640 } 5641 5642 static xmlSchemaIDCPtr 5643 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5644 const xmlChar *name, const xmlChar *nsName, 5645 int category, xmlNodePtr node) 5646 { 5647 xmlSchemaIDCPtr ret = NULL; 5648 5649 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5650 return (NULL); 5651 5652 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5653 if (ret == NULL) { 5654 xmlSchemaPErrMemory(ctxt, 5655 "allocating an identity-constraint definition", NULL); 5656 return (NULL); 5657 } 5658 memset(ret, 0, sizeof(xmlSchemaIDC)); 5659 /* The target namespace of the parent element declaration. */ 5660 ret->targetNamespace = nsName; 5661 ret->name = name; 5662 ret->type = category; 5663 ret->node = node; 5664 5665 WXS_ADD_GLOBAL(ctxt, ret); 5666 /* 5667 * Only keyrefs need to be fixup up. 5668 */ 5669 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5670 WXS_ADD_PENDING(ctxt, ret); 5671 return (ret); 5672 } 5673 5674 /** 5675 * xmlSchemaAddWildcard: 5676 * @ctxt: a schema validation context 5677 * @schema: a schema 5678 * 5679 * Adds a wildcard. 5680 * It corresponds to a xsd:anyAttribute and xsd:any. 5681 * 5682 * Returns the new structure or NULL in case of error 5683 */ 5684 static xmlSchemaWildcardPtr 5685 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5686 xmlSchemaTypeType type, xmlNodePtr node) 5687 { 5688 xmlSchemaWildcardPtr ret = NULL; 5689 5690 if ((ctxt == NULL) || (schema == NULL)) 5691 return (NULL); 5692 5693 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5694 if (ret == NULL) { 5695 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5696 return (NULL); 5697 } 5698 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5699 ret->type = type; 5700 ret->node = node; 5701 WXS_ADD_LOCAL(ctxt, ret); 5702 return (ret); 5703 } 5704 5705 static void 5706 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5707 { 5708 if (group == NULL) 5709 return; 5710 if (group->members != NULL) 5711 xmlSchemaItemListFree(group->members); 5712 xmlFree(group); 5713 } 5714 5715 static void 5716 xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED) 5717 { 5718 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group); 5719 } 5720 5721 static xmlSchemaSubstGroupPtr 5722 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5723 xmlSchemaElementPtr head) 5724 { 5725 xmlSchemaSubstGroupPtr ret; 5726 5727 /* Init subst group hash. */ 5728 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5729 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5730 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5731 return(NULL); 5732 } 5733 /* Create a new substitution group. */ 5734 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5735 if (ret == NULL) { 5736 xmlSchemaPErrMemory(NULL, 5737 "allocating a substitution group container", NULL); 5738 return(NULL); 5739 } 5740 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5741 ret->head = head; 5742 /* Create list of members. */ 5743 ret->members = xmlSchemaItemListCreate(); 5744 if (ret->members == NULL) { 5745 xmlSchemaSubstGroupFree(ret); 5746 return(NULL); 5747 } 5748 /* Add subst group to hash. */ 5749 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5750 head->name, head->targetNamespace, ret) != 0) { 5751 PERROR_INT("xmlSchemaSubstGroupAdd", 5752 "failed to add a new substitution container"); 5753 xmlSchemaSubstGroupFree(ret); 5754 return(NULL); 5755 } 5756 return(ret); 5757 } 5758 5759 static xmlSchemaSubstGroupPtr 5760 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5761 xmlSchemaElementPtr head) 5762 { 5763 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5764 return(NULL); 5765 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5766 head->name, head->targetNamespace)); 5767 5768 } 5769 5770 /** 5771 * xmlSchemaAddElementSubstitutionMember: 5772 * @pctxt: a schema parser context 5773 * @head: the head of the substitution group 5774 * @member: the new member of the substitution group 5775 * 5776 * Allocate a new annotation structure. 5777 * 5778 * Returns the newly allocated structure or NULL in case or error 5779 */ 5780 static int 5781 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5782 xmlSchemaElementPtr head, 5783 xmlSchemaElementPtr member) 5784 { 5785 xmlSchemaSubstGroupPtr substGroup = NULL; 5786 5787 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5788 return (-1); 5789 5790 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5791 if (substGroup == NULL) 5792 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5793 if (substGroup == NULL) 5794 return(-1); 5795 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5796 return(-1); 5797 return(0); 5798 } 5799 5800 /************************************************************************ 5801 * * 5802 * Utilities for parsing * 5803 * * 5804 ************************************************************************/ 5805 5806 /** 5807 * xmlSchemaPValAttrNodeQNameValue: 5808 * @ctxt: a schema parser context 5809 * @schema: the schema context 5810 * @ownerItem: the parent as a schema object 5811 * @value: the QName value 5812 * @uri: the resulting namespace URI if found 5813 * @local: the resulting local part if found, the attribute value otherwise 5814 * 5815 * Extracts the local name and the URI of a QName value and validates it. 5816 * This one is intended to be used on attribute values that 5817 * should resolve to schema components. 5818 * 5819 * Returns 0, in case the QName is valid, a positive error code 5820 * if not valid and -1 if an internal error occurs. 5821 */ 5822 static int 5823 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5824 xmlSchemaPtr schema, 5825 xmlSchemaBasicItemPtr ownerItem, 5826 xmlAttrPtr attr, 5827 const xmlChar *value, 5828 const xmlChar **uri, 5829 const xmlChar **local) 5830 { 5831 const xmlChar *pref; 5832 xmlNsPtr ns; 5833 int len, ret; 5834 5835 *uri = NULL; 5836 *local = NULL; 5837 ret = xmlValidateQName(value, 1); 5838 if (ret > 0) { 5839 xmlSchemaPSimpleTypeErr(ctxt, 5840 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5841 ownerItem, (xmlNodePtr) attr, 5842 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5843 NULL, value, NULL, NULL, NULL); 5844 *local = value; 5845 return (ctxt->err); 5846 } else if (ret < 0) 5847 return (-1); 5848 5849 if (!strchr((char *) value, ':')) { 5850 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5851 if (ns) 5852 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5853 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5854 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5855 * parser context. */ 5856 /* 5857 * This one takes care of included schemas with no 5858 * target namespace. 5859 */ 5860 *uri = ctxt->targetNamespace; 5861 } 5862 *local = xmlDictLookup(ctxt->dict, value, -1); 5863 return (0); 5864 } 5865 /* 5866 * At this point xmlSplitQName3 has to return a local name. 5867 */ 5868 *local = xmlSplitQName3(value, &len); 5869 *local = xmlDictLookup(ctxt->dict, *local, -1); 5870 pref = xmlDictLookup(ctxt->dict, value, len); 5871 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5872 if (ns == NULL) { 5873 xmlSchemaPSimpleTypeErr(ctxt, 5874 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5875 ownerItem, (xmlNodePtr) attr, 5876 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5877 "The value '%s' of simple type 'xs:QName' has no " 5878 "corresponding namespace declaration in scope", value, NULL); 5879 return (ctxt->err); 5880 } else { 5881 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5882 } 5883 return (0); 5884 } 5885 5886 /** 5887 * xmlSchemaPValAttrNodeQName: 5888 * @ctxt: a schema parser context 5889 * @schema: the schema context 5890 * @ownerItem: the owner as a schema object 5891 * @attr: the attribute node 5892 * @uri: the resulting namespace URI if found 5893 * @local: the resulting local part if found, the attribute value otherwise 5894 * 5895 * Extracts and validates the QName of an attribute value. 5896 * This one is intended to be used on attribute values that 5897 * should resolve to schema components. 5898 * 5899 * Returns 0, in case the QName is valid, a positive error code 5900 * if not valid and -1 if an internal error occurs. 5901 */ 5902 static int 5903 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5904 xmlSchemaPtr schema, 5905 xmlSchemaBasicItemPtr ownerItem, 5906 xmlAttrPtr attr, 5907 const xmlChar **uri, 5908 const xmlChar **local) 5909 { 5910 const xmlChar *value; 5911 5912 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5913 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5914 ownerItem, attr, value, uri, local)); 5915 } 5916 5917 /** 5918 * xmlSchemaPValAttrQName: 5919 * @ctxt: a schema parser context 5920 * @schema: the schema context 5921 * @ownerItem: the owner as a schema object 5922 * @ownerElem: the parent node of the attribute 5923 * @name: the name of the attribute 5924 * @uri: the resulting namespace URI if found 5925 * @local: the resulting local part if found, the attribute value otherwise 5926 * 5927 * Extracts and validates the QName of an attribute value. 5928 * 5929 * Returns 0, in case the QName is valid, a positive error code 5930 * if not valid and -1 if an internal error occurs. 5931 */ 5932 static int 5933 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5934 xmlSchemaPtr schema, 5935 xmlSchemaBasicItemPtr ownerItem, 5936 xmlNodePtr ownerElem, 5937 const char *name, 5938 const xmlChar **uri, 5939 const xmlChar **local) 5940 { 5941 xmlAttrPtr attr; 5942 5943 attr = xmlSchemaGetPropNode(ownerElem, name); 5944 if (attr == NULL) { 5945 *local = NULL; 5946 *uri = NULL; 5947 return (0); 5948 } 5949 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5950 ownerItem, attr, uri, local)); 5951 } 5952 5953 /** 5954 * xmlSchemaPValAttrID: 5955 * @ctxt: a schema parser context 5956 * 5957 * Extracts and validates the ID of an attribute value. 5958 * 5959 * Returns 0, in case the ID is valid, a positive error code 5960 * if not valid and -1 if an internal error occurs. 5961 */ 5962 static int 5963 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5964 { 5965 int ret; 5966 const xmlChar *value; 5967 5968 if (attr == NULL) 5969 return(0); 5970 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5971 ret = xmlValidateNCName(value, 1); 5972 if (ret == 0) { 5973 /* 5974 * NOTE: the IDness might have already be declared in the DTD 5975 */ 5976 if (attr->atype != XML_ATTRIBUTE_ID) { 5977 xmlIDPtr res; 5978 xmlChar *strip; 5979 5980 /* 5981 * TODO: Use xmlSchemaStrip here; it's not exported at this 5982 * moment. 5983 */ 5984 strip = xmlSchemaCollapseString(value); 5985 if (strip != NULL) { 5986 xmlFree((xmlChar *) value); 5987 value = strip; 5988 } 5989 res = xmlAddID(NULL, attr->doc, value, attr); 5990 if (res == NULL) { 5991 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5992 xmlSchemaPSimpleTypeErr(ctxt, 5993 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5994 NULL, (xmlNodePtr) attr, 5995 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5996 NULL, NULL, "Duplicate value '%s' of simple " 5997 "type 'xs:ID'", value, NULL); 5998 } else 5999 attr->atype = XML_ATTRIBUTE_ID; 6000 } 6001 } else if (ret > 0) { 6002 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6003 xmlSchemaPSimpleTypeErr(ctxt, 6004 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6005 NULL, (xmlNodePtr) attr, 6006 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 6007 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 6008 "not a valid 'xs:NCName'", 6009 value, NULL); 6010 } 6011 if (value != NULL) 6012 xmlFree((xmlChar *)value); 6013 6014 return (ret); 6015 } 6016 6017 static int 6018 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 6019 xmlNodePtr ownerElem, 6020 const xmlChar *name) 6021 { 6022 xmlAttrPtr attr; 6023 6024 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 6025 if (attr == NULL) 6026 return(0); 6027 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6028 6029 } 6030 6031 /** 6032 * xmlGetMaxOccurs: 6033 * @ctxt: a schema validation context 6034 * @node: a subtree containing XML Schema informations 6035 * 6036 * Get the maxOccurs property 6037 * 6038 * Returns the default if not found, or the value 6039 */ 6040 static int 6041 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6042 int min, int max, int def, const char *expected) 6043 { 6044 const xmlChar *val, *cur; 6045 int ret = 0; 6046 xmlAttrPtr attr; 6047 6048 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6049 if (attr == NULL) 6050 return (def); 6051 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6052 6053 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6054 if (max != UNBOUNDED) { 6055 xmlSchemaPSimpleTypeErr(ctxt, 6056 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6057 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6058 NULL, (xmlNodePtr) attr, NULL, expected, 6059 val, NULL, NULL, NULL); 6060 return (def); 6061 } else 6062 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6063 } 6064 6065 cur = val; 6066 while (IS_BLANK_CH(*cur)) 6067 cur++; 6068 if (*cur == 0) { 6069 xmlSchemaPSimpleTypeErr(ctxt, 6070 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6071 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6072 NULL, (xmlNodePtr) attr, NULL, expected, 6073 val, NULL, NULL, NULL); 6074 return (def); 6075 } 6076 while ((*cur >= '0') && (*cur <= '9')) { 6077 ret = ret * 10 + (*cur - '0'); 6078 cur++; 6079 } 6080 while (IS_BLANK_CH(*cur)) 6081 cur++; 6082 /* 6083 * TODO: Restrict the maximal value to Integer. 6084 */ 6085 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6086 xmlSchemaPSimpleTypeErr(ctxt, 6087 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6088 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6089 NULL, (xmlNodePtr) attr, NULL, expected, 6090 val, NULL, NULL, NULL); 6091 return (def); 6092 } 6093 return (ret); 6094 } 6095 6096 /** 6097 * xmlGetMinOccurs: 6098 * @ctxt: a schema validation context 6099 * @node: a subtree containing XML Schema informations 6100 * 6101 * Get the minOccurs property 6102 * 6103 * Returns the default if not found, or the value 6104 */ 6105 static int 6106 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6107 int min, int max, int def, const char *expected) 6108 { 6109 const xmlChar *val, *cur; 6110 int ret = 0; 6111 xmlAttrPtr attr; 6112 6113 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6114 if (attr == NULL) 6115 return (def); 6116 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6117 cur = val; 6118 while (IS_BLANK_CH(*cur)) 6119 cur++; 6120 if (*cur == 0) { 6121 xmlSchemaPSimpleTypeErr(ctxt, 6122 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6123 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6124 NULL, (xmlNodePtr) attr, NULL, expected, 6125 val, NULL, NULL, NULL); 6126 return (def); 6127 } 6128 while ((*cur >= '0') && (*cur <= '9')) { 6129 ret = ret * 10 + (*cur - '0'); 6130 cur++; 6131 } 6132 while (IS_BLANK_CH(*cur)) 6133 cur++; 6134 /* 6135 * TODO: Restrict the maximal value to Integer. 6136 */ 6137 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6138 xmlSchemaPSimpleTypeErr(ctxt, 6139 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6140 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6141 NULL, (xmlNodePtr) attr, NULL, expected, 6142 val, NULL, NULL, NULL); 6143 return (def); 6144 } 6145 return (ret); 6146 } 6147 6148 /** 6149 * xmlSchemaPGetBoolNodeValue: 6150 * @ctxt: a schema validation context 6151 * @ownerItem: the owner as a schema item 6152 * @node: the node holding the value 6153 * 6154 * Converts a boolean string value into 1 or 0. 6155 * 6156 * Returns 0 or 1. 6157 */ 6158 static int 6159 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6160 xmlSchemaBasicItemPtr ownerItem, 6161 xmlNodePtr node) 6162 { 6163 xmlChar *value = NULL; 6164 int res = 0; 6165 6166 value = xmlNodeGetContent(node); 6167 /* 6168 * 3.2.2.1 Lexical representation 6169 * An instance of a datatype that is defined as `boolean` 6170 * can have the following legal literals {true, false, 1, 0}. 6171 */ 6172 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6173 res = 1; 6174 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6175 res = 0; 6176 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6177 res = 1; 6178 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6179 res = 0; 6180 else { 6181 xmlSchemaPSimpleTypeErr(ctxt, 6182 XML_SCHEMAP_INVALID_BOOLEAN, 6183 ownerItem, node, 6184 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6185 NULL, BAD_CAST value, 6186 NULL, NULL, NULL); 6187 } 6188 if (value != NULL) 6189 xmlFree(value); 6190 return (res); 6191 } 6192 6193 /** 6194 * xmlGetBooleanProp: 6195 * @ctxt: a schema validation context 6196 * @node: a subtree containing XML Schema informations 6197 * @name: the attribute name 6198 * @def: the default value 6199 * 6200 * Evaluate if a boolean property is set 6201 * 6202 * Returns the default if not found, 0 if found to be false, 6203 * 1 if found to be true 6204 */ 6205 static int 6206 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6207 xmlNodePtr node, 6208 const char *name, int def) 6209 { 6210 const xmlChar *val; 6211 6212 val = xmlSchemaGetProp(ctxt, node, name); 6213 if (val == NULL) 6214 return (def); 6215 /* 6216 * 3.2.2.1 Lexical representation 6217 * An instance of a datatype that is defined as `boolean` 6218 * can have the following legal literals {true, false, 1, 0}. 6219 */ 6220 if (xmlStrEqual(val, BAD_CAST "true")) 6221 def = 1; 6222 else if (xmlStrEqual(val, BAD_CAST "false")) 6223 def = 0; 6224 else if (xmlStrEqual(val, BAD_CAST "1")) 6225 def = 1; 6226 else if (xmlStrEqual(val, BAD_CAST "0")) 6227 def = 0; 6228 else { 6229 xmlSchemaPSimpleTypeErr(ctxt, 6230 XML_SCHEMAP_INVALID_BOOLEAN, 6231 NULL, 6232 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6233 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6234 NULL, val, NULL, NULL, NULL); 6235 } 6236 return (def); 6237 } 6238 6239 /************************************************************************ 6240 * * 6241 * Schema extraction from an Infoset * 6242 * * 6243 ************************************************************************/ 6244 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6245 ctxt, xmlSchemaPtr schema, 6246 xmlNodePtr node, 6247 int topLevel); 6248 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6249 ctxt, 6250 xmlSchemaPtr schema, 6251 xmlNodePtr node, 6252 int topLevel); 6253 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6254 ctxt, 6255 xmlSchemaPtr schema, 6256 xmlNodePtr node, 6257 xmlSchemaTypeType parentType); 6258 static xmlSchemaBasicItemPtr 6259 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6260 xmlSchemaPtr schema, 6261 xmlNodePtr node, 6262 xmlSchemaItemListPtr uses, 6263 int parentType); 6264 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6265 xmlSchemaPtr schema, 6266 xmlNodePtr node); 6267 static xmlSchemaWildcardPtr 6268 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6269 xmlSchemaPtr schema, xmlNodePtr node); 6270 6271 /** 6272 * xmlSchemaPValAttrNodeValue: 6273 * 6274 * @pctxt: a schema parser context 6275 * @ownerItem: the schema object owner if existent 6276 * @attr: the schema attribute node being validated 6277 * @value: the value 6278 * @type: the built-in type to be validated against 6279 * 6280 * Validates a value against the given built-in type. 6281 * This one is intended to be used internally for validation 6282 * of schema attribute values during parsing of the schema. 6283 * 6284 * Returns 0 if the value is valid, a positive error code 6285 * number otherwise and -1 in case of an internal or API error. 6286 */ 6287 static int 6288 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6289 xmlSchemaBasicItemPtr ownerItem, 6290 xmlAttrPtr attr, 6291 const xmlChar *value, 6292 xmlSchemaTypePtr type) 6293 { 6294 6295 int ret = 0; 6296 6297 /* 6298 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6299 * one is really meant to be used internally, so better not. 6300 */ 6301 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6302 return (-1); 6303 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6304 PERROR_INT("xmlSchemaPValAttrNodeValue", 6305 "the given type is not a built-in type"); 6306 return (-1); 6307 } 6308 switch (type->builtInType) { 6309 case XML_SCHEMAS_NCNAME: 6310 case XML_SCHEMAS_QNAME: 6311 case XML_SCHEMAS_ANYURI: 6312 case XML_SCHEMAS_TOKEN: 6313 case XML_SCHEMAS_LANGUAGE: 6314 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6315 (xmlNodePtr) attr); 6316 break; 6317 default: { 6318 PERROR_INT("xmlSchemaPValAttrNodeValue", 6319 "validation using the given type is not supported while " 6320 "parsing a schema"); 6321 return (-1); 6322 } 6323 } 6324 /* 6325 * TODO: Should we use the S4S error codes instead? 6326 */ 6327 if (ret < 0) { 6328 PERROR_INT("xmlSchemaPValAttrNodeValue", 6329 "failed to validate a schema attribute value"); 6330 return (-1); 6331 } else if (ret > 0) { 6332 if (WXS_IS_LIST(type)) 6333 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6334 else 6335 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6336 xmlSchemaPSimpleTypeErr(pctxt, 6337 ret, ownerItem, (xmlNodePtr) attr, 6338 type, NULL, value, NULL, NULL, NULL); 6339 } 6340 return (ret); 6341 } 6342 6343 /** 6344 * xmlSchemaPValAttrNode: 6345 * 6346 * @ctxt: a schema parser context 6347 * @ownerItem: the schema object owner if existent 6348 * @attr: the schema attribute node being validated 6349 * @type: the built-in type to be validated against 6350 * @value: the resulting value if any 6351 * 6352 * Extracts and validates a value against the given built-in type. 6353 * This one is intended to be used internally for validation 6354 * of schema attribute values during parsing of the schema. 6355 * 6356 * Returns 0 if the value is valid, a positive error code 6357 * number otherwise and -1 in case of an internal or API error. 6358 */ 6359 static int 6360 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6361 xmlSchemaBasicItemPtr ownerItem, 6362 xmlAttrPtr attr, 6363 xmlSchemaTypePtr type, 6364 const xmlChar **value) 6365 { 6366 const xmlChar *val; 6367 6368 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6369 return (-1); 6370 6371 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6372 if (value != NULL) 6373 *value = val; 6374 6375 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6376 val, type)); 6377 } 6378 6379 /** 6380 * xmlSchemaPValAttr: 6381 * 6382 * @ctxt: a schema parser context 6383 * @node: the element node of the attribute 6384 * @ownerItem: the schema object owner if existent 6385 * @ownerElem: the owner element node 6386 * @name: the name of the schema attribute node 6387 * @type: the built-in type to be validated against 6388 * @value: the resulting value if any 6389 * 6390 * Extracts and validates a value against the given built-in type. 6391 * This one is intended to be used internally for validation 6392 * of schema attribute values during parsing of the schema. 6393 * 6394 * Returns 0 if the value is valid, a positive error code 6395 * number otherwise and -1 in case of an internal or API error. 6396 */ 6397 static int 6398 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6399 xmlSchemaBasicItemPtr ownerItem, 6400 xmlNodePtr ownerElem, 6401 const char *name, 6402 xmlSchemaTypePtr type, 6403 const xmlChar **value) 6404 { 6405 xmlAttrPtr attr; 6406 6407 if ((ctxt == NULL) || (type == NULL)) { 6408 if (value != NULL) 6409 *value = NULL; 6410 return (-1); 6411 } 6412 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6413 if (value != NULL) 6414 *value = NULL; 6415 xmlSchemaPErr(ctxt, ownerElem, 6416 XML_SCHEMAP_INTERNAL, 6417 "Internal error: xmlSchemaPValAttr, the given " 6418 "type '%s' is not a built-in type.\n", 6419 type->name, NULL); 6420 return (-1); 6421 } 6422 attr = xmlSchemaGetPropNode(ownerElem, name); 6423 if (attr == NULL) { 6424 if (value != NULL) 6425 *value = NULL; 6426 return (0); 6427 } 6428 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6429 type, value)); 6430 } 6431 6432 static int 6433 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6434 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6435 xmlNodePtr node, 6436 xmlAttrPtr attr, 6437 const xmlChar *namespaceName) 6438 { 6439 /* TODO: Pointer comparison instead? */ 6440 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6441 return (0); 6442 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6443 return (0); 6444 /* 6445 * Check if the referenced namespace was <import>ed. 6446 */ 6447 if (WXS_BUCKET(pctxt)->relations != NULL) { 6448 xmlSchemaSchemaRelationPtr rel; 6449 6450 rel = WXS_BUCKET(pctxt)->relations; 6451 do { 6452 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6453 xmlStrEqual(namespaceName, rel->importNamespace)) 6454 return (0); 6455 rel = rel->next; 6456 } while (rel != NULL); 6457 } 6458 /* 6459 * No matching <import>ed namespace found. 6460 */ 6461 { 6462 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6463 6464 if (namespaceName == NULL) 6465 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6466 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6467 "References from this schema to components in no " 6468 "namespace are not allowed, since not indicated by an " 6469 "import statement", NULL, NULL); 6470 else 6471 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6472 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6473 "References from this schema to components in the " 6474 "namespace '%s' are not allowed, since not indicated by an " 6475 "import statement", namespaceName, NULL); 6476 } 6477 return (XML_SCHEMAP_SRC_RESOLVE); 6478 } 6479 6480 /** 6481 * xmlSchemaParseLocalAttributes: 6482 * @ctxt: a schema validation context 6483 * @schema: the schema being built 6484 * @node: a subtree containing XML Schema informations 6485 * @type: the hosting type where the attributes will be anchored 6486 * 6487 * Parses attribute uses and attribute declarations and 6488 * attribute group references. 6489 */ 6490 static int 6491 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6492 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6493 int parentType, int *hasRefs) 6494 { 6495 void *item; 6496 6497 while ((IS_SCHEMA((*child), "attribute")) || 6498 (IS_SCHEMA((*child), "attributeGroup"))) { 6499 if (IS_SCHEMA((*child), "attribute")) { 6500 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6501 *list, parentType); 6502 } else { 6503 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6504 if ((item != NULL) && (hasRefs != NULL)) 6505 *hasRefs = 1; 6506 } 6507 if (item != NULL) { 6508 if (*list == NULL) { 6509 /* TODO: Customize grow factor. */ 6510 *list = xmlSchemaItemListCreate(); 6511 if (*list == NULL) 6512 return(-1); 6513 } 6514 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6515 return(-1); 6516 } 6517 *child = (*child)->next; 6518 } 6519 return (0); 6520 } 6521 6522 /** 6523 * xmlSchemaParseAnnotation: 6524 * @ctxt: a schema validation context 6525 * @schema: the schema being built 6526 * @node: a subtree containing XML Schema informations 6527 * 6528 * parse a XML schema Attribute declaration 6529 * *WARNING* this interface is highly subject to change 6530 * 6531 * Returns -1 in case of error, 0 if the declaration is improper and 6532 * 1 in case of success. 6533 */ 6534 static xmlSchemaAnnotPtr 6535 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6536 { 6537 xmlSchemaAnnotPtr ret; 6538 xmlNodePtr child = NULL; 6539 xmlAttrPtr attr; 6540 int barked = 0; 6541 6542 /* 6543 * INFO: S4S completed. 6544 */ 6545 /* 6546 * id = ID 6547 * {any attributes with non-schema namespace . . .}> 6548 * Content: (appinfo | documentation)* 6549 */ 6550 if ((ctxt == NULL) || (node == NULL)) 6551 return (NULL); 6552 if (needed) 6553 ret = xmlSchemaNewAnnot(ctxt, node); 6554 else 6555 ret = NULL; 6556 attr = node->properties; 6557 while (attr != NULL) { 6558 if (((attr->ns == NULL) && 6559 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6560 ((attr->ns != NULL) && 6561 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6562 6563 xmlSchemaPIllegalAttrErr(ctxt, 6564 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6565 } 6566 attr = attr->next; 6567 } 6568 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6569 /* 6570 * And now for the children... 6571 */ 6572 child = node->children; 6573 while (child != NULL) { 6574 if (IS_SCHEMA(child, "appinfo")) { 6575 /* TODO: make available the content of "appinfo". */ 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 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6585 ((attr->ns != NULL) && 6586 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6587 6588 xmlSchemaPIllegalAttrErr(ctxt, 6589 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6590 } 6591 attr = attr->next; 6592 } 6593 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6594 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6595 child = child->next; 6596 } else if (IS_SCHEMA(child, "documentation")) { 6597 /* TODO: make available the content of "documentation". */ 6598 /* 6599 * source = anyURI 6600 * {any attributes with non-schema namespace . . .}> 6601 * Content: ({any})* 6602 */ 6603 attr = child->properties; 6604 while (attr != NULL) { 6605 if (attr->ns == NULL) { 6606 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6607 xmlSchemaPIllegalAttrErr(ctxt, 6608 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6609 } 6610 } else { 6611 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6612 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6613 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6614 6615 xmlSchemaPIllegalAttrErr(ctxt, 6616 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6617 } 6618 } 6619 attr = attr->next; 6620 } 6621 /* 6622 * Attribute "xml:lang". 6623 */ 6624 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6625 if (attr != NULL) 6626 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6627 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6628 child = child->next; 6629 } else { 6630 if (!barked) 6631 xmlSchemaPContentErr(ctxt, 6632 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6633 NULL, node, child, NULL, "(appinfo | documentation)*"); 6634 barked = 1; 6635 child = child->next; 6636 } 6637 } 6638 6639 return (ret); 6640 } 6641 6642 /** 6643 * xmlSchemaParseFacet: 6644 * @ctxt: a schema validation context 6645 * @schema: the schema being built 6646 * @node: a subtree containing XML Schema informations 6647 * 6648 * parse a XML schema Facet declaration 6649 * *WARNING* this interface is highly subject to change 6650 * 6651 * Returns the new type structure or NULL in case of error 6652 */ 6653 static xmlSchemaFacetPtr 6654 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6655 xmlNodePtr node) 6656 { 6657 xmlSchemaFacetPtr facet; 6658 xmlNodePtr child = NULL; 6659 const xmlChar *value; 6660 6661 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6662 return (NULL); 6663 6664 facet = xmlSchemaNewFacet(); 6665 if (facet == NULL) { 6666 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6667 return (NULL); 6668 } 6669 facet->node = node; 6670 value = xmlSchemaGetProp(ctxt, node, "value"); 6671 if (value == NULL) { 6672 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6673 "Facet %s has no value\n", node->name, NULL); 6674 xmlSchemaFreeFacet(facet); 6675 return (NULL); 6676 } 6677 if (IS_SCHEMA(node, "minInclusive")) { 6678 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6679 } else if (IS_SCHEMA(node, "minExclusive")) { 6680 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6681 } else if (IS_SCHEMA(node, "maxInclusive")) { 6682 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6683 } else if (IS_SCHEMA(node, "maxExclusive")) { 6684 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6685 } else if (IS_SCHEMA(node, "totalDigits")) { 6686 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6687 } else if (IS_SCHEMA(node, "fractionDigits")) { 6688 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6689 } else if (IS_SCHEMA(node, "pattern")) { 6690 facet->type = XML_SCHEMA_FACET_PATTERN; 6691 } else if (IS_SCHEMA(node, "enumeration")) { 6692 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6693 } else if (IS_SCHEMA(node, "whiteSpace")) { 6694 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6695 } else if (IS_SCHEMA(node, "length")) { 6696 facet->type = XML_SCHEMA_FACET_LENGTH; 6697 } else if (IS_SCHEMA(node, "maxLength")) { 6698 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6699 } else if (IS_SCHEMA(node, "minLength")) { 6700 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6701 } else { 6702 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6703 "Unknown facet type %s\n", node->name, NULL); 6704 xmlSchemaFreeFacet(facet); 6705 return (NULL); 6706 } 6707 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6708 facet->value = value; 6709 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6710 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6711 const xmlChar *fixed; 6712 6713 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6714 if (fixed != NULL) { 6715 if (xmlStrEqual(fixed, BAD_CAST "true")) 6716 facet->fixed = 1; 6717 } 6718 } 6719 child = node->children; 6720 6721 if (IS_SCHEMA(child, "annotation")) { 6722 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6723 child = child->next; 6724 } 6725 if (child != NULL) { 6726 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6727 "Facet %s has unexpected child content\n", 6728 node->name, NULL); 6729 } 6730 return (facet); 6731 } 6732 6733 /** 6734 * xmlSchemaParseWildcardNs: 6735 * @ctxt: a schema parser context 6736 * @wildc: the wildcard, already created 6737 * @node: a subtree containing XML Schema informations 6738 * 6739 * Parses the attribute "processContents" and "namespace" 6740 * of a xsd:anyAttribute and xsd:any. 6741 * *WARNING* this interface is highly subject to change 6742 * 6743 * Returns 0 if everything goes fine, a positive error code 6744 * if something is not valid and -1 if an internal error occurs. 6745 */ 6746 static int 6747 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6748 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6749 xmlSchemaWildcardPtr wildc, 6750 xmlNodePtr node) 6751 { 6752 const xmlChar *pc, *ns, *dictnsItem; 6753 int ret = 0; 6754 xmlChar *nsItem; 6755 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6756 xmlAttrPtr attr; 6757 6758 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6759 if ((pc == NULL) 6760 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6761 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6762 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6763 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6764 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6765 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6766 } else { 6767 xmlSchemaPSimpleTypeErr(ctxt, 6768 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6769 NULL, node, 6770 NULL, "(strict | skip | lax)", pc, 6771 NULL, NULL, NULL); 6772 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6773 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6774 } 6775 /* 6776 * Build the namespace constraints. 6777 */ 6778 attr = xmlSchemaGetPropNode(node, "namespace"); 6779 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6780 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6781 wildc->any = 1; 6782 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6783 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6784 if (wildc->negNsSet == NULL) { 6785 return (-1); 6786 } 6787 wildc->negNsSet->value = ctxt->targetNamespace; 6788 } else { 6789 const xmlChar *end, *cur; 6790 6791 cur = ns; 6792 do { 6793 while (IS_BLANK_CH(*cur)) 6794 cur++; 6795 end = cur; 6796 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6797 end++; 6798 if (end == cur) 6799 break; 6800 nsItem = xmlStrndup(cur, end - cur); 6801 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6802 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6803 xmlSchemaPSimpleTypeErr(ctxt, 6804 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6805 NULL, (xmlNodePtr) attr, 6806 NULL, 6807 "((##any | ##other) | List of (xs:anyURI | " 6808 "(##targetNamespace | ##local)))", 6809 nsItem, NULL, NULL, NULL); 6810 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6811 } else { 6812 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6813 dictnsItem = ctxt->targetNamespace; 6814 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6815 dictnsItem = NULL; 6816 } else { 6817 /* 6818 * Validate the item (anyURI). 6819 */ 6820 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6821 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6822 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6823 } 6824 /* 6825 * Avoid duplicate namespaces. 6826 */ 6827 tmp = wildc->nsSet; 6828 while (tmp != NULL) { 6829 if (dictnsItem == tmp->value) 6830 break; 6831 tmp = tmp->next; 6832 } 6833 if (tmp == NULL) { 6834 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6835 if (tmp == NULL) { 6836 xmlFree(nsItem); 6837 return (-1); 6838 } 6839 tmp->value = dictnsItem; 6840 tmp->next = NULL; 6841 if (wildc->nsSet == NULL) 6842 wildc->nsSet = tmp; 6843 else if (lastNs != NULL) 6844 lastNs->next = tmp; 6845 lastNs = tmp; 6846 } 6847 6848 } 6849 xmlFree(nsItem); 6850 cur = end; 6851 } while (*cur != 0); 6852 } 6853 return (ret); 6854 } 6855 6856 static int 6857 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6858 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6859 xmlNodePtr node, 6860 int minOccurs, 6861 int maxOccurs) { 6862 6863 if ((maxOccurs == 0) && ( minOccurs == 0)) 6864 return (0); 6865 if (maxOccurs != UNBOUNDED) { 6866 /* 6867 * TODO: Maybe we should better not create the particle, 6868 * if min/max is invalid, since it could confuse the build of the 6869 * content model. 6870 */ 6871 /* 6872 * 3.9.6 Schema Component Constraint: Particle Correct 6873 * 6874 */ 6875 if (maxOccurs < 1) { 6876 /* 6877 * 2.2 {max occurs} must be greater than or equal to 1. 6878 */ 6879 xmlSchemaPCustomAttrErr(ctxt, 6880 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6881 NULL, NULL, 6882 xmlSchemaGetPropNode(node, "maxOccurs"), 6883 "The value must be greater than or equal to 1"); 6884 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6885 } else if (minOccurs > maxOccurs) { 6886 /* 6887 * 2.1 {min occurs} must not be greater than {max occurs}. 6888 */ 6889 xmlSchemaPCustomAttrErr(ctxt, 6890 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6891 NULL, NULL, 6892 xmlSchemaGetPropNode(node, "minOccurs"), 6893 "The value must not be greater than the value of 'maxOccurs'"); 6894 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6895 } 6896 } 6897 return (0); 6898 } 6899 6900 /** 6901 * xmlSchemaParseAny: 6902 * @ctxt: a schema validation context 6903 * @schema: the schema being built 6904 * @node: a subtree containing XML Schema informations 6905 * 6906 * Parsea a XML schema <any> element. A particle and wildcard 6907 * will be created (except if minOccurs==maxOccurs==0, in this case 6908 * nothing will be created). 6909 * *WARNING* this interface is highly subject to change 6910 * 6911 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6912 */ 6913 static xmlSchemaParticlePtr 6914 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6915 xmlNodePtr node) 6916 { 6917 xmlSchemaParticlePtr particle; 6918 xmlNodePtr child = NULL; 6919 xmlSchemaWildcardPtr wild; 6920 int min, max; 6921 xmlAttrPtr attr; 6922 xmlSchemaAnnotPtr annot = NULL; 6923 6924 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6925 return (NULL); 6926 /* 6927 * Check for illegal attributes. 6928 */ 6929 attr = node->properties; 6930 while (attr != NULL) { 6931 if (attr->ns == NULL) { 6932 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6933 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6934 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6935 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6936 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6937 xmlSchemaPIllegalAttrErr(ctxt, 6938 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6939 } 6940 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6941 xmlSchemaPIllegalAttrErr(ctxt, 6942 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6943 } 6944 attr = attr->next; 6945 } 6946 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6947 /* 6948 * minOccurs/maxOccurs. 6949 */ 6950 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6951 "(xs:nonNegativeInteger | unbounded)"); 6952 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6953 "xs:nonNegativeInteger"); 6954 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6955 /* 6956 * Create & parse the wildcard. 6957 */ 6958 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6959 if (wild == NULL) 6960 return (NULL); 6961 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6962 /* 6963 * And now for the children... 6964 */ 6965 child = node->children; 6966 if (IS_SCHEMA(child, "annotation")) { 6967 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6968 child = child->next; 6969 } 6970 if (child != NULL) { 6971 xmlSchemaPContentErr(ctxt, 6972 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6973 NULL, node, child, 6974 NULL, "(annotation?)"); 6975 } 6976 /* 6977 * No component if minOccurs==maxOccurs==0. 6978 */ 6979 if ((min == 0) && (max == 0)) { 6980 /* Don't free the wildcard, since it's already on the list. */ 6981 return (NULL); 6982 } 6983 /* 6984 * Create the particle. 6985 */ 6986 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6987 if (particle == NULL) 6988 return (NULL); 6989 particle->annot = annot; 6990 particle->children = (xmlSchemaTreeItemPtr) wild; 6991 6992 return (particle); 6993 } 6994 6995 /** 6996 * xmlSchemaParseNotation: 6997 * @ctxt: a schema validation context 6998 * @schema: the schema being built 6999 * @node: a subtree containing XML Schema informations 7000 * 7001 * parse a XML schema Notation declaration 7002 * 7003 * Returns the new structure or NULL in case of error 7004 */ 7005 static xmlSchemaNotationPtr 7006 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 7007 xmlNodePtr node) 7008 { 7009 const xmlChar *name; 7010 xmlSchemaNotationPtr ret; 7011 xmlNodePtr child = NULL; 7012 7013 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7014 return (NULL); 7015 name = xmlSchemaGetProp(ctxt, node, "name"); 7016 if (name == NULL) { 7017 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 7018 "Notation has no name\n", NULL, NULL); 7019 return (NULL); 7020 } 7021 ret = xmlSchemaAddNotation(ctxt, schema, name, 7022 ctxt->targetNamespace, node); 7023 if (ret == NULL) 7024 return (NULL); 7025 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7026 7027 child = node->children; 7028 if (IS_SCHEMA(child, "annotation")) { 7029 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7030 child = child->next; 7031 } 7032 if (child != NULL) { 7033 xmlSchemaPContentErr(ctxt, 7034 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7035 NULL, node, child, 7036 NULL, "(annotation?)"); 7037 } 7038 7039 return (ret); 7040 } 7041 7042 /** 7043 * xmlSchemaParseAnyAttribute: 7044 * @ctxt: a schema validation context 7045 * @schema: the schema being built 7046 * @node: a subtree containing XML Schema informations 7047 * 7048 * parse a XML schema AnyAttribute declaration 7049 * *WARNING* this interface is highly subject to change 7050 * 7051 * Returns a wildcard or NULL. 7052 */ 7053 static xmlSchemaWildcardPtr 7054 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7055 xmlSchemaPtr schema, xmlNodePtr node) 7056 { 7057 xmlSchemaWildcardPtr ret; 7058 xmlNodePtr child = NULL; 7059 xmlAttrPtr attr; 7060 7061 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7062 return (NULL); 7063 7064 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7065 node); 7066 if (ret == NULL) { 7067 return (NULL); 7068 } 7069 /* 7070 * Check for illegal attributes. 7071 */ 7072 attr = node->properties; 7073 while (attr != NULL) { 7074 if (attr->ns == NULL) { 7075 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7076 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7077 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7078 xmlSchemaPIllegalAttrErr(ctxt, 7079 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7080 } 7081 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7082 xmlSchemaPIllegalAttrErr(ctxt, 7083 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7084 } 7085 attr = attr->next; 7086 } 7087 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7088 /* 7089 * Parse the namespace list. 7090 */ 7091 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7092 return (NULL); 7093 /* 7094 * And now for the children... 7095 */ 7096 child = node->children; 7097 if (IS_SCHEMA(child, "annotation")) { 7098 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7099 child = child->next; 7100 } 7101 if (child != NULL) { 7102 xmlSchemaPContentErr(ctxt, 7103 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7104 NULL, node, child, 7105 NULL, "(annotation?)"); 7106 } 7107 7108 return (ret); 7109 } 7110 7111 7112 /** 7113 * xmlSchemaParseAttribute: 7114 * @ctxt: a schema validation context 7115 * @schema: the schema being built 7116 * @node: a subtree containing XML Schema informations 7117 * 7118 * parse a XML schema Attribute declaration 7119 * *WARNING* this interface is highly subject to change 7120 * 7121 * Returns the attribute declaration. 7122 */ 7123 static xmlSchemaBasicItemPtr 7124 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7125 xmlSchemaPtr schema, 7126 xmlNodePtr node, 7127 xmlSchemaItemListPtr uses, 7128 int parentType) 7129 { 7130 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7131 xmlSchemaAttributeUsePtr use = NULL; 7132 xmlNodePtr child = NULL; 7133 xmlAttrPtr attr; 7134 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7135 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7136 int nberrors, hasForm = 0, defValueType = 0; 7137 7138 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7139 #define WXS_ATTR_DEF_VAL_FIXED 2 7140 7141 /* 7142 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7143 */ 7144 7145 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7146 return (NULL); 7147 attr = xmlSchemaGetPropNode(node, "ref"); 7148 if (attr != NULL) { 7149 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7150 NULL, attr, &tmpNs, &tmpName) != 0) { 7151 return (NULL); 7152 } 7153 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7154 return(NULL); 7155 isRef = 1; 7156 } 7157 nberrors = pctxt->nberrors; 7158 /* 7159 * Check for illegal attributes. 7160 */ 7161 attr = node->properties; 7162 while (attr != NULL) { 7163 if (attr->ns == NULL) { 7164 if (isRef) { 7165 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7166 xmlSchemaPValAttrNodeID(pctxt, attr); 7167 goto attr_next; 7168 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7169 goto attr_next; 7170 } 7171 } else { 7172 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7173 goto attr_next; 7174 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7175 xmlSchemaPValAttrNodeID(pctxt, attr); 7176 goto attr_next; 7177 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7178 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7179 attr, &tmpNs, &tmpName); 7180 goto attr_next; 7181 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7182 /* 7183 * Evaluate the target namespace 7184 */ 7185 hasForm = 1; 7186 attrValue = xmlSchemaGetNodeContent(pctxt, 7187 (xmlNodePtr) attr); 7188 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7189 ns = pctxt->targetNamespace; 7190 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7191 { 7192 xmlSchemaPSimpleTypeErr(pctxt, 7193 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7194 NULL, (xmlNodePtr) attr, 7195 NULL, "(qualified | unqualified)", 7196 attrValue, NULL, NULL, NULL); 7197 } 7198 goto attr_next; 7199 } 7200 } 7201 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7202 7203 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7204 /* TODO: Maybe we need to normalize the value beforehand. */ 7205 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7206 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7207 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7208 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7209 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7210 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7211 else { 7212 xmlSchemaPSimpleTypeErr(pctxt, 7213 XML_SCHEMAP_INVALID_ATTR_USE, 7214 NULL, (xmlNodePtr) attr, 7215 NULL, "(optional | prohibited | required)", 7216 attrValue, NULL, NULL, NULL); 7217 } 7218 goto attr_next; 7219 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7220 /* 7221 * 3.2.3 : 1 7222 * default and fixed must not both be present. 7223 */ 7224 if (defValue) { 7225 xmlSchemaPMutualExclAttrErr(pctxt, 7226 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7227 NULL, attr, "default", "fixed"); 7228 } else { 7229 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7230 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7231 } 7232 goto attr_next; 7233 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7234 /* 7235 * 3.2.3 : 1 7236 * default and fixed must not both be present. 7237 */ 7238 if (defValue) { 7239 xmlSchemaPMutualExclAttrErr(pctxt, 7240 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7241 NULL, attr, "default", "fixed"); 7242 } else { 7243 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7244 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7245 } 7246 goto attr_next; 7247 } 7248 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7249 goto attr_next; 7250 7251 xmlSchemaPIllegalAttrErr(pctxt, 7252 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7253 7254 attr_next: 7255 attr = attr->next; 7256 } 7257 /* 7258 * 3.2.3 : 2 7259 * If default and use are both present, use must have 7260 * the actual value optional. 7261 */ 7262 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7263 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7264 xmlSchemaPSimpleTypeErr(pctxt, 7265 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7266 NULL, node, NULL, 7267 "(optional | prohibited | required)", NULL, 7268 "The value of the attribute 'use' must be 'optional' " 7269 "if the attribute 'default' is present", 7270 NULL, NULL); 7271 } 7272 /* 7273 * We want correct attributes. 7274 */ 7275 if (nberrors != pctxt->nberrors) 7276 return(NULL); 7277 if (! isRef) { 7278 xmlSchemaAttributePtr attrDecl; 7279 7280 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7281 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7282 ns = pctxt->targetNamespace; 7283 /* 7284 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7285 * TODO: Move this to the component layer. 7286 */ 7287 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7288 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7289 XML_SCHEMAP_NO_XSI, 7290 node, NULL, 7291 "The target namespace must not match '%s'", 7292 xmlSchemaInstanceNs, NULL); 7293 } 7294 attr = xmlSchemaGetPropNode(node, "name"); 7295 if (attr == NULL) { 7296 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7297 NULL, node, "name", NULL); 7298 return (NULL); 7299 } 7300 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7301 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7302 return (NULL); 7303 } 7304 /* 7305 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7306 * TODO: Move this to the component layer. 7307 */ 7308 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7309 xmlSchemaPSimpleTypeErr(pctxt, 7310 XML_SCHEMAP_NO_XMLNS, 7311 NULL, (xmlNodePtr) attr, 7312 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7313 "The value of the attribute must not match 'xmlns'", 7314 NULL, NULL); 7315 return (NULL); 7316 } 7317 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7318 goto check_children; 7319 /* 7320 * Create the attribute use component. 7321 */ 7322 use = xmlSchemaAddAttributeUse(pctxt, node); 7323 if (use == NULL) 7324 return(NULL); 7325 use->occurs = occurs; 7326 /* 7327 * Create the attribute declaration. 7328 */ 7329 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7330 if (attrDecl == NULL) 7331 return (NULL); 7332 if (tmpName != NULL) { 7333 attrDecl->typeName = tmpName; 7334 attrDecl->typeNs = tmpNs; 7335 } 7336 use->attrDecl = attrDecl; 7337 /* 7338 * Value constraint. 7339 */ 7340 if (defValue != NULL) { 7341 attrDecl->defValue = defValue; 7342 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7343 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7344 } 7345 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7346 xmlSchemaQNameRefPtr ref; 7347 7348 /* 7349 * Create the attribute use component. 7350 */ 7351 use = xmlSchemaAddAttributeUse(pctxt, node); 7352 if (use == NULL) 7353 return(NULL); 7354 /* 7355 * We need to resolve the reference at later stage. 7356 */ 7357 WXS_ADD_PENDING(pctxt, use); 7358 use->occurs = occurs; 7359 /* 7360 * Create a QName reference to the attribute declaration. 7361 */ 7362 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7363 tmpName, tmpNs); 7364 if (ref == NULL) 7365 return(NULL); 7366 /* 7367 * Assign the reference. This will be substituted for the 7368 * referenced attribute declaration when the QName is resolved. 7369 */ 7370 use->attrDecl = WXS_ATTR_CAST ref; 7371 /* 7372 * Value constraint. 7373 */ 7374 if (defValue != NULL) 7375 use->defValue = defValue; 7376 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7377 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7378 } 7379 7380 check_children: 7381 /* 7382 * And now for the children... 7383 */ 7384 child = node->children; 7385 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7386 xmlSchemaAttributeUseProhibPtr prohib; 7387 7388 if (IS_SCHEMA(child, "annotation")) { 7389 xmlSchemaParseAnnotation(pctxt, child, 0); 7390 child = child->next; 7391 } 7392 if (child != NULL) { 7393 xmlSchemaPContentErr(pctxt, 7394 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7395 NULL, node, child, NULL, 7396 "(annotation?)"); 7397 } 7398 /* 7399 * Check for pointlessness of attribute prohibitions. 7400 */ 7401 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7402 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7403 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7404 node, NULL, 7405 "Skipping attribute use prohibition, since it is " 7406 "pointless inside an <attributeGroup>", 7407 NULL, NULL, NULL); 7408 return(NULL); 7409 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7410 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7411 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7412 node, NULL, 7413 "Skipping attribute use prohibition, since it is " 7414 "pointless when extending a type", 7415 NULL, NULL, NULL); 7416 return(NULL); 7417 } 7418 if (! isRef) { 7419 tmpName = name; 7420 tmpNs = ns; 7421 } 7422 /* 7423 * Check for duplicate attribute prohibitions. 7424 */ 7425 if (uses) { 7426 int i; 7427 7428 for (i = 0; i < uses->nbItems; i++) { 7429 use = uses->items[i]; 7430 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7431 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7432 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7433 { 7434 xmlChar *str = NULL; 7435 7436 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7437 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7438 node, NULL, 7439 "Skipping duplicate attribute use prohibition '%s'", 7440 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7441 NULL, NULL); 7442 FREE_AND_NULL(str) 7443 return(NULL); 7444 } 7445 } 7446 } 7447 /* 7448 * Create the attribute prohibition helper component. 7449 */ 7450 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7451 if (prohib == NULL) 7452 return(NULL); 7453 prohib->node = node; 7454 prohib->name = tmpName; 7455 prohib->targetNamespace = tmpNs; 7456 if (isRef) { 7457 /* 7458 * We need at least to resolve to the attribute declaration. 7459 */ 7460 WXS_ADD_PENDING(pctxt, prohib); 7461 } 7462 return(WXS_BASIC_CAST prohib); 7463 } else { 7464 if (IS_SCHEMA(child, "annotation")) { 7465 /* 7466 * TODO: Should this go into the attr decl? 7467 */ 7468 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7469 child = child->next; 7470 } 7471 if (isRef) { 7472 if (child != NULL) { 7473 if (IS_SCHEMA(child, "simpleType")) 7474 /* 7475 * 3.2.3 : 3.2 7476 * If ref is present, then all of <simpleType>, 7477 * form and type must be absent. 7478 */ 7479 xmlSchemaPContentErr(pctxt, 7480 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7481 NULL, node, child, NULL, 7482 "(annotation?)"); 7483 else 7484 xmlSchemaPContentErr(pctxt, 7485 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7486 NULL, node, child, NULL, 7487 "(annotation?)"); 7488 } 7489 } else { 7490 if (IS_SCHEMA(child, "simpleType")) { 7491 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7492 /* 7493 * 3.2.3 : 4 7494 * type and <simpleType> must not both be present. 7495 */ 7496 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7497 NULL, node, child, 7498 "The attribute 'type' and the <simpleType> child " 7499 "are mutually exclusive", NULL); 7500 } else 7501 WXS_ATTRUSE_TYPEDEF(use) = 7502 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7503 child = child->next; 7504 } 7505 if (child != NULL) 7506 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7507 NULL, node, child, NULL, 7508 "(annotation?, simpleType?)"); 7509 } 7510 } 7511 return (WXS_BASIC_CAST use); 7512 } 7513 7514 7515 static xmlSchemaAttributePtr 7516 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7517 xmlSchemaPtr schema, 7518 xmlNodePtr node) 7519 { 7520 const xmlChar *attrValue; 7521 xmlSchemaAttributePtr ret; 7522 xmlNodePtr child = NULL; 7523 xmlAttrPtr attr; 7524 7525 /* 7526 * Note that the w3c spec assumes the schema to be validated with schema 7527 * for schemas beforehand. 7528 * 7529 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7530 */ 7531 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7532 return (NULL); 7533 /* 7534 * 3.2.3 : 3.1 7535 * One of ref or name must be present, but not both 7536 */ 7537 attr = xmlSchemaGetPropNode(node, "name"); 7538 if (attr == NULL) { 7539 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7540 NULL, node, "name", NULL); 7541 return (NULL); 7542 } 7543 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7544 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7545 return (NULL); 7546 } 7547 /* 7548 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7549 * TODO: Move this to the component layer. 7550 */ 7551 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7552 xmlSchemaPSimpleTypeErr(pctxt, 7553 XML_SCHEMAP_NO_XMLNS, 7554 NULL, (xmlNodePtr) attr, 7555 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7556 "The value of the attribute must not match 'xmlns'", 7557 NULL, NULL); 7558 return (NULL); 7559 } 7560 /* 7561 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7562 * TODO: Move this to the component layer. 7563 * Or better leave it here and add it to the component layer 7564 * if we have a schema construction API. 7565 */ 7566 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7567 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7568 XML_SCHEMAP_NO_XSI, node, NULL, 7569 "The target namespace must not match '%s'", 7570 xmlSchemaInstanceNs, NULL); 7571 } 7572 7573 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7574 pctxt->targetNamespace, node, 1); 7575 if (ret == NULL) 7576 return (NULL); 7577 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7578 7579 /* 7580 * Check for illegal attributes. 7581 */ 7582 attr = node->properties; 7583 while (attr != NULL) { 7584 if (attr->ns == NULL) { 7585 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7586 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7587 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7588 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7589 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7590 { 7591 xmlSchemaPIllegalAttrErr(pctxt, 7592 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7593 } 7594 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7595 xmlSchemaPIllegalAttrErr(pctxt, 7596 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7597 } 7598 attr = attr->next; 7599 } 7600 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7601 node, "type", &ret->typeNs, &ret->typeName); 7602 7603 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7604 /* 7605 * Attribute "fixed". 7606 */ 7607 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7608 if (ret->defValue != NULL) 7609 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7610 /* 7611 * Attribute "default". 7612 */ 7613 attr = xmlSchemaGetPropNode(node, "default"); 7614 if (attr != NULL) { 7615 /* 7616 * 3.2.3 : 1 7617 * default and fixed must not both be present. 7618 */ 7619 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7620 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7621 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7622 } else 7623 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7624 } 7625 /* 7626 * And now for the children... 7627 */ 7628 child = node->children; 7629 if (IS_SCHEMA(child, "annotation")) { 7630 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7631 child = child->next; 7632 } 7633 if (IS_SCHEMA(child, "simpleType")) { 7634 if (ret->typeName != NULL) { 7635 /* 7636 * 3.2.3 : 4 7637 * type and <simpleType> must not both be present. 7638 */ 7639 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7640 NULL, node, child, 7641 "The attribute 'type' and the <simpleType> child " 7642 "are mutually exclusive", NULL); 7643 } else 7644 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7645 child = child->next; 7646 } 7647 if (child != NULL) 7648 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7649 NULL, node, child, NULL, 7650 "(annotation?, simpleType?)"); 7651 7652 return (ret); 7653 } 7654 7655 /** 7656 * xmlSchemaParseAttributeGroupRef: 7657 * @ctxt: a schema validation context 7658 * @schema: the schema being built 7659 * @node: a subtree containing XML Schema informations 7660 * 7661 * Parse an attribute group definition reference. 7662 * Note that a reference to an attribute group does not 7663 * correspond to any component at all. 7664 * *WARNING* this interface is highly subject to change 7665 * 7666 * Returns the attribute group or NULL in case of error. 7667 */ 7668 static xmlSchemaQNameRefPtr 7669 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7670 xmlSchemaPtr schema, 7671 xmlNodePtr node) 7672 { 7673 xmlSchemaQNameRefPtr ret; 7674 xmlNodePtr child = NULL; 7675 xmlAttrPtr attr; 7676 const xmlChar *refNs = NULL, *ref = NULL; 7677 7678 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7679 return (NULL); 7680 7681 attr = xmlSchemaGetPropNode(node, "ref"); 7682 if (attr == NULL) { 7683 xmlSchemaPMissingAttrErr(pctxt, 7684 XML_SCHEMAP_S4S_ATTR_MISSING, 7685 NULL, node, "ref", NULL); 7686 return (NULL); 7687 } 7688 xmlSchemaPValAttrNodeQName(pctxt, schema, 7689 NULL, attr, &refNs, &ref); 7690 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7691 return(NULL); 7692 7693 /* 7694 * Check for illegal attributes. 7695 */ 7696 attr = node->properties; 7697 while (attr != NULL) { 7698 if (attr->ns == NULL) { 7699 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7700 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7701 { 7702 xmlSchemaPIllegalAttrErr(pctxt, 7703 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7704 } 7705 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7706 xmlSchemaPIllegalAttrErr(pctxt, 7707 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7708 } 7709 attr = attr->next; 7710 } 7711 /* Attribute ID */ 7712 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7713 7714 /* 7715 * And now for the children... 7716 */ 7717 child = node->children; 7718 if (IS_SCHEMA(child, "annotation")) { 7719 /* 7720 * TODO: We do not have a place to store the annotation, do we? 7721 */ 7722 xmlSchemaParseAnnotation(pctxt, child, 0); 7723 child = child->next; 7724 } 7725 if (child != NULL) { 7726 xmlSchemaPContentErr(pctxt, 7727 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7728 NULL, node, child, NULL, 7729 "(annotation?)"); 7730 } 7731 7732 /* 7733 * Handle attribute group redefinitions. 7734 */ 7735 if (pctxt->isRedefine && pctxt->redef && 7736 (pctxt->redef->item->type == 7737 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7738 (ref == pctxt->redef->refName) && 7739 (refNs == pctxt->redef->refTargetNs)) 7740 { 7741 /* 7742 * SPEC src-redefine: 7743 * (7.1) "If it has an <attributeGroup> among its contents 7744 * the `actual value` of whose ref [attribute] is the same 7745 * as the `actual value` of its own name attribute plus 7746 * target namespace, then it must have exactly one such group." 7747 */ 7748 if (pctxt->redefCounter != 0) { 7749 xmlChar *str = NULL; 7750 7751 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7752 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7753 "The redefining attribute group definition " 7754 "'%s' must not contain more than one " 7755 "reference to the redefined definition", 7756 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7757 FREE_AND_NULL(str); 7758 return(NULL); 7759 } 7760 pctxt->redefCounter++; 7761 /* 7762 * URGENT TODO: How to ensure that the reference will not be 7763 * handled by the normal component resolution mechanism? 7764 */ 7765 ret = xmlSchemaNewQNameRef(pctxt, 7766 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7767 if (ret == NULL) 7768 return(NULL); 7769 ret->node = node; 7770 pctxt->redef->reference = WXS_BASIC_CAST ret; 7771 } else { 7772 /* 7773 * Create a QName-reference helper component. We will substitute this 7774 * component for the attribute uses of the referenced attribute group 7775 * definition. 7776 */ 7777 ret = xmlSchemaNewQNameRef(pctxt, 7778 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7779 if (ret == NULL) 7780 return(NULL); 7781 ret->node = node; 7782 /* Add to pending items, to be able to resolve the reference. */ 7783 WXS_ADD_PENDING(pctxt, ret); 7784 } 7785 return (ret); 7786 } 7787 7788 /** 7789 * xmlSchemaParseAttributeGroupDefinition: 7790 * @pctxt: a schema validation context 7791 * @schema: the schema being built 7792 * @node: a subtree containing XML Schema informations 7793 * 7794 * parse a XML schema Attribute Group declaration 7795 * *WARNING* this interface is highly subject to change 7796 * 7797 * Returns the attribute group definition or NULL in case of error. 7798 */ 7799 static xmlSchemaAttributeGroupPtr 7800 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7801 xmlSchemaPtr schema, 7802 xmlNodePtr node) 7803 { 7804 const xmlChar *name; 7805 xmlSchemaAttributeGroupPtr ret; 7806 xmlNodePtr child = NULL; 7807 xmlAttrPtr attr; 7808 int hasRefs = 0; 7809 7810 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7811 return (NULL); 7812 7813 attr = xmlSchemaGetPropNode(node, "name"); 7814 if (attr == NULL) { 7815 xmlSchemaPMissingAttrErr(pctxt, 7816 XML_SCHEMAP_S4S_ATTR_MISSING, 7817 NULL, node, "name", NULL); 7818 return (NULL); 7819 } 7820 /* 7821 * The name is crucial, exit if invalid. 7822 */ 7823 if (xmlSchemaPValAttrNode(pctxt, 7824 NULL, attr, 7825 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7826 return (NULL); 7827 } 7828 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7829 name, pctxt->targetNamespace, node); 7830 if (ret == NULL) 7831 return (NULL); 7832 /* 7833 * Check for illegal attributes. 7834 */ 7835 attr = node->properties; 7836 while (attr != NULL) { 7837 if (attr->ns == NULL) { 7838 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7839 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7840 { 7841 xmlSchemaPIllegalAttrErr(pctxt, 7842 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7843 } 7844 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7845 xmlSchemaPIllegalAttrErr(pctxt, 7846 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7847 } 7848 attr = attr->next; 7849 } 7850 /* Attribute ID */ 7851 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7852 /* 7853 * And now for the children... 7854 */ 7855 child = node->children; 7856 if (IS_SCHEMA(child, "annotation")) { 7857 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7858 child = child->next; 7859 } 7860 /* 7861 * Parse contained attribute decls/refs. 7862 */ 7863 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7864 (xmlSchemaItemListPtr *) &(ret->attrUses), 7865 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7866 return(NULL); 7867 if (hasRefs) 7868 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7869 /* 7870 * Parse the attribute wildcard. 7871 */ 7872 if (IS_SCHEMA(child, "anyAttribute")) { 7873 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7874 schema, child); 7875 child = child->next; 7876 } 7877 if (child != NULL) { 7878 xmlSchemaPContentErr(pctxt, 7879 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7880 NULL, node, child, NULL, 7881 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7882 } 7883 return (ret); 7884 } 7885 7886 /** 7887 * xmlSchemaPValAttrFormDefault: 7888 * @value: the value 7889 * @flags: the flags to be modified 7890 * @flagQualified: the specific flag for "qualified" 7891 * 7892 * Returns 0 if the value is valid, 1 otherwise. 7893 */ 7894 static int 7895 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7896 int *flags, 7897 int flagQualified) 7898 { 7899 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7900 if ((*flags & flagQualified) == 0) 7901 *flags |= flagQualified; 7902 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7903 return (1); 7904 7905 return (0); 7906 } 7907 7908 /** 7909 * xmlSchemaPValAttrBlockFinal: 7910 * @value: the value 7911 * @flags: the flags to be modified 7912 * @flagAll: the specific flag for "#all" 7913 * @flagExtension: the specific flag for "extension" 7914 * @flagRestriction: the specific flag for "restriction" 7915 * @flagSubstitution: the specific flag for "substitution" 7916 * @flagList: the specific flag for "list" 7917 * @flagUnion: the specific flag for "union" 7918 * 7919 * Validates the value of the attribute "final" and "block". The value 7920 * is converted into the specified flag values and returned in @flags. 7921 * 7922 * Returns 0 if the value is valid, 1 otherwise. 7923 */ 7924 7925 static int 7926 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7927 int *flags, 7928 int flagAll, 7929 int flagExtension, 7930 int flagRestriction, 7931 int flagSubstitution, 7932 int flagList, 7933 int flagUnion) 7934 { 7935 int ret = 0; 7936 7937 /* 7938 * TODO: This does not check for duplicate entries. 7939 */ 7940 if ((flags == NULL) || (value == NULL)) 7941 return (-1); 7942 if (value[0] == 0) 7943 return (0); 7944 if (xmlStrEqual(value, BAD_CAST "#all")) { 7945 if (flagAll != -1) 7946 *flags |= flagAll; 7947 else { 7948 if (flagExtension != -1) 7949 *flags |= flagExtension; 7950 if (flagRestriction != -1) 7951 *flags |= flagRestriction; 7952 if (flagSubstitution != -1) 7953 *flags |= flagSubstitution; 7954 if (flagList != -1) 7955 *flags |= flagList; 7956 if (flagUnion != -1) 7957 *flags |= flagUnion; 7958 } 7959 } else { 7960 const xmlChar *end, *cur = value; 7961 xmlChar *item; 7962 7963 do { 7964 while (IS_BLANK_CH(*cur)) 7965 cur++; 7966 end = cur; 7967 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7968 end++; 7969 if (end == cur) 7970 break; 7971 item = xmlStrndup(cur, end - cur); 7972 if (xmlStrEqual(item, BAD_CAST "extension")) { 7973 if (flagExtension != -1) { 7974 if ((*flags & flagExtension) == 0) 7975 *flags |= flagExtension; 7976 } else 7977 ret = 1; 7978 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7979 if (flagRestriction != -1) { 7980 if ((*flags & flagRestriction) == 0) 7981 *flags |= flagRestriction; 7982 } else 7983 ret = 1; 7984 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7985 if (flagSubstitution != -1) { 7986 if ((*flags & flagSubstitution) == 0) 7987 *flags |= flagSubstitution; 7988 } else 7989 ret = 1; 7990 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7991 if (flagList != -1) { 7992 if ((*flags & flagList) == 0) 7993 *flags |= flagList; 7994 } else 7995 ret = 1; 7996 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7997 if (flagUnion != -1) { 7998 if ((*flags & flagUnion) == 0) 7999 *flags |= flagUnion; 8000 } else 8001 ret = 1; 8002 } else 8003 ret = 1; 8004 if (item != NULL) 8005 xmlFree(item); 8006 cur = end; 8007 } while ((ret == 0) && (*cur != 0)); 8008 } 8009 8010 return (ret); 8011 } 8012 8013 static int 8014 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 8015 xmlSchemaIDCPtr idc, 8016 xmlSchemaIDCSelectPtr selector, 8017 xmlAttrPtr attr, 8018 int isField) 8019 { 8020 xmlNodePtr node; 8021 8022 /* 8023 * c-selector-xpath: 8024 * Schema Component Constraint: Selector Value OK 8025 * 8026 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8027 * in [XPath]. 8028 */ 8029 if (selector == NULL) { 8030 xmlSchemaPErr(ctxt, idc->node, 8031 XML_SCHEMAP_INTERNAL, 8032 "Internal error: xmlSchemaCheckCSelectorXPath, " 8033 "the selector is not specified.\n", NULL, NULL); 8034 return (-1); 8035 } 8036 if (attr == NULL) 8037 node = idc->node; 8038 else 8039 node = (xmlNodePtr) attr; 8040 if (selector->xpath == NULL) { 8041 xmlSchemaPCustomErr(ctxt, 8042 /* TODO: Adjust error code. */ 8043 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8044 NULL, node, 8045 "The XPath expression of the selector is not valid", NULL); 8046 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8047 } else { 8048 const xmlChar **nsArray = NULL; 8049 xmlNsPtr *nsList = NULL; 8050 /* 8051 * Compile the XPath expression. 8052 */ 8053 /* 8054 * TODO: We need the array of in-scope namespaces for compilation. 8055 * TODO: Call xmlPatterncompile with different options for selector/ 8056 * field. 8057 */ 8058 if (attr == NULL) 8059 nsList = NULL; 8060 else 8061 nsList = xmlGetNsList(attr->doc, attr->parent); 8062 /* 8063 * Build an array of prefixes and namespaces. 8064 */ 8065 if (nsList != NULL) { 8066 int i, count = 0; 8067 8068 for (i = 0; nsList[i] != NULL; i++) 8069 count++; 8070 8071 nsArray = (const xmlChar **) xmlMalloc( 8072 (count * 2 + 1) * sizeof(const xmlChar *)); 8073 if (nsArray == NULL) { 8074 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8075 NULL); 8076 xmlFree(nsList); 8077 return (-1); 8078 } 8079 for (i = 0; i < count; i++) { 8080 nsArray[2 * i] = nsList[i]->href; 8081 nsArray[2 * i + 1] = nsList[i]->prefix; 8082 } 8083 nsArray[count * 2] = NULL; 8084 xmlFree(nsList); 8085 } 8086 /* 8087 * TODO: Differentiate between "selector" and "field". 8088 */ 8089 if (isField) 8090 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8091 NULL, XML_PATTERN_XSFIELD, nsArray); 8092 else 8093 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8094 NULL, XML_PATTERN_XSSEL, nsArray); 8095 if (nsArray != NULL) 8096 xmlFree((xmlChar **) nsArray); 8097 8098 if (selector->xpathComp == NULL) { 8099 xmlSchemaPCustomErr(ctxt, 8100 /* TODO: Adjust error code? */ 8101 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8102 NULL, node, 8103 "The XPath expression '%s' could not be " 8104 "compiled", selector->xpath); 8105 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8106 } 8107 } 8108 return (0); 8109 } 8110 8111 #define ADD_ANNOTATION(annot) \ 8112 xmlSchemaAnnotPtr cur = item->annot; \ 8113 if (item->annot == NULL) { \ 8114 item->annot = annot; \ 8115 return (annot); \ 8116 } \ 8117 cur = item->annot; \ 8118 if (cur->next != NULL) { \ 8119 cur = cur->next; \ 8120 } \ 8121 cur->next = annot; 8122 8123 /** 8124 * xmlSchemaAssignAnnotation: 8125 * @item: the schema component 8126 * @annot: the annotation 8127 * 8128 * Adds the annotation to the given schema component. 8129 * 8130 * Returns the given annotation. 8131 */ 8132 static xmlSchemaAnnotPtr 8133 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8134 xmlSchemaAnnotPtr annot) 8135 { 8136 if ((annItem == NULL) || (annot == NULL)) 8137 return (NULL); 8138 switch (annItem->type) { 8139 case XML_SCHEMA_TYPE_ELEMENT: { 8140 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8141 ADD_ANNOTATION(annot) 8142 } 8143 break; 8144 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8145 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8146 ADD_ANNOTATION(annot) 8147 } 8148 break; 8149 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8150 case XML_SCHEMA_TYPE_ANY: { 8151 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8152 ADD_ANNOTATION(annot) 8153 } 8154 break; 8155 case XML_SCHEMA_TYPE_PARTICLE: 8156 case XML_SCHEMA_TYPE_IDC_KEY: 8157 case XML_SCHEMA_TYPE_IDC_KEYREF: 8158 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8159 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8160 ADD_ANNOTATION(annot) 8161 } 8162 break; 8163 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8164 xmlSchemaAttributeGroupPtr item = 8165 (xmlSchemaAttributeGroupPtr) annItem; 8166 ADD_ANNOTATION(annot) 8167 } 8168 break; 8169 case XML_SCHEMA_TYPE_NOTATION: { 8170 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8171 ADD_ANNOTATION(annot) 8172 } 8173 break; 8174 case XML_SCHEMA_FACET_MININCLUSIVE: 8175 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8176 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8177 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8178 case XML_SCHEMA_FACET_TOTALDIGITS: 8179 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8180 case XML_SCHEMA_FACET_PATTERN: 8181 case XML_SCHEMA_FACET_ENUMERATION: 8182 case XML_SCHEMA_FACET_WHITESPACE: 8183 case XML_SCHEMA_FACET_LENGTH: 8184 case XML_SCHEMA_FACET_MAXLENGTH: 8185 case XML_SCHEMA_FACET_MINLENGTH: { 8186 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8187 ADD_ANNOTATION(annot) 8188 } 8189 break; 8190 case XML_SCHEMA_TYPE_SIMPLE: 8191 case XML_SCHEMA_TYPE_COMPLEX: { 8192 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8193 ADD_ANNOTATION(annot) 8194 } 8195 break; 8196 case XML_SCHEMA_TYPE_GROUP: { 8197 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8198 ADD_ANNOTATION(annot) 8199 } 8200 break; 8201 case XML_SCHEMA_TYPE_SEQUENCE: 8202 case XML_SCHEMA_TYPE_CHOICE: 8203 case XML_SCHEMA_TYPE_ALL: { 8204 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8205 ADD_ANNOTATION(annot) 8206 } 8207 break; 8208 default: 8209 xmlSchemaPCustomErr(NULL, 8210 XML_SCHEMAP_INTERNAL, 8211 NULL, NULL, 8212 "Internal error: xmlSchemaAddAnnotation, " 8213 "The item is not a annotated schema component", NULL); 8214 break; 8215 } 8216 return (annot); 8217 } 8218 8219 /** 8220 * xmlSchemaParseIDCSelectorAndField: 8221 * @ctxt: a schema validation context 8222 * @schema: the schema being built 8223 * @node: a subtree containing XML Schema informations 8224 * 8225 * Parses a XML Schema identity-constraint definition's 8226 * <selector> and <field> elements. 8227 * 8228 * Returns the parsed identity-constraint definition. 8229 */ 8230 static xmlSchemaIDCSelectPtr 8231 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8232 xmlSchemaIDCPtr idc, 8233 xmlNodePtr node, 8234 int isField) 8235 { 8236 xmlSchemaIDCSelectPtr item; 8237 xmlNodePtr child = NULL; 8238 xmlAttrPtr attr; 8239 8240 /* 8241 * Check for illegal attributes. 8242 */ 8243 attr = node->properties; 8244 while (attr != NULL) { 8245 if (attr->ns == NULL) { 8246 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8247 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8248 xmlSchemaPIllegalAttrErr(ctxt, 8249 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8250 } 8251 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8252 xmlSchemaPIllegalAttrErr(ctxt, 8253 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8254 } 8255 attr = attr->next; 8256 } 8257 /* 8258 * Create the item. 8259 */ 8260 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8261 if (item == NULL) { 8262 xmlSchemaPErrMemory(ctxt, 8263 "allocating a 'selector' of an identity-constraint definition", 8264 NULL); 8265 return (NULL); 8266 } 8267 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8268 /* 8269 * Attribute "xpath" (mandatory). 8270 */ 8271 attr = xmlSchemaGetPropNode(node, "xpath"); 8272 if (attr == NULL) { 8273 xmlSchemaPMissingAttrErr(ctxt, 8274 XML_SCHEMAP_S4S_ATTR_MISSING, 8275 NULL, node, 8276 "name", NULL); 8277 } else { 8278 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8279 /* 8280 * URGENT TODO: "field"s have an other syntax than "selector"s. 8281 */ 8282 8283 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8284 isField) == -1) { 8285 xmlSchemaPErr(ctxt, 8286 (xmlNodePtr) attr, 8287 XML_SCHEMAP_INTERNAL, 8288 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8289 "validating the XPath expression of a IDC selector.\n", 8290 NULL, NULL); 8291 } 8292 8293 } 8294 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8295 /* 8296 * And now for the children... 8297 */ 8298 child = node->children; 8299 if (IS_SCHEMA(child, "annotation")) { 8300 /* 8301 * Add the annotation to the parent IDC. 8302 */ 8303 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8304 xmlSchemaParseAnnotation(ctxt, child, 1)); 8305 child = child->next; 8306 } 8307 if (child != NULL) { 8308 xmlSchemaPContentErr(ctxt, 8309 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8310 NULL, node, child, 8311 NULL, "(annotation?)"); 8312 } 8313 8314 return (item); 8315 } 8316 8317 /** 8318 * xmlSchemaParseIDC: 8319 * @ctxt: a schema validation context 8320 * @schema: the schema being built 8321 * @node: a subtree containing XML Schema informations 8322 * 8323 * Parses a XML Schema identity-constraint definition. 8324 * 8325 * Returns the parsed identity-constraint definition. 8326 */ 8327 static xmlSchemaIDCPtr 8328 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8329 xmlSchemaPtr schema, 8330 xmlNodePtr node, 8331 xmlSchemaTypeType idcCategory, 8332 const xmlChar *targetNamespace) 8333 { 8334 xmlSchemaIDCPtr item = NULL; 8335 xmlNodePtr child = NULL; 8336 xmlAttrPtr attr; 8337 const xmlChar *name = NULL; 8338 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8339 8340 /* 8341 * Check for illegal attributes. 8342 */ 8343 attr = node->properties; 8344 while (attr != NULL) { 8345 if (attr->ns == NULL) { 8346 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8347 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8348 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8349 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8350 xmlSchemaPIllegalAttrErr(ctxt, 8351 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8352 } 8353 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8354 xmlSchemaPIllegalAttrErr(ctxt, 8355 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8356 } 8357 attr = attr->next; 8358 } 8359 /* 8360 * Attribute "name" (mandatory). 8361 */ 8362 attr = xmlSchemaGetPropNode(node, "name"); 8363 if (attr == NULL) { 8364 xmlSchemaPMissingAttrErr(ctxt, 8365 XML_SCHEMAP_S4S_ATTR_MISSING, 8366 NULL, node, 8367 "name", NULL); 8368 return (NULL); 8369 } else if (xmlSchemaPValAttrNode(ctxt, 8370 NULL, attr, 8371 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8372 return (NULL); 8373 } 8374 /* Create the component. */ 8375 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8376 idcCategory, node); 8377 if (item == NULL) 8378 return(NULL); 8379 8380 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8381 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8382 /* 8383 * Attribute "refer" (mandatory). 8384 */ 8385 attr = xmlSchemaGetPropNode(node, "refer"); 8386 if (attr == NULL) { 8387 xmlSchemaPMissingAttrErr(ctxt, 8388 XML_SCHEMAP_S4S_ATTR_MISSING, 8389 NULL, node, 8390 "refer", NULL); 8391 } else { 8392 /* 8393 * Create a reference item. 8394 */ 8395 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8396 NULL, NULL); 8397 if (item->ref == NULL) 8398 return (NULL); 8399 xmlSchemaPValAttrNodeQName(ctxt, schema, 8400 NULL, attr, 8401 &(item->ref->targetNamespace), 8402 &(item->ref->name)); 8403 xmlSchemaCheckReference(ctxt, schema, node, attr, 8404 item->ref->targetNamespace); 8405 } 8406 } 8407 /* 8408 * And now for the children... 8409 */ 8410 child = node->children; 8411 if (IS_SCHEMA(child, "annotation")) { 8412 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8413 child = child->next; 8414 } 8415 if (child == NULL) { 8416 xmlSchemaPContentErr(ctxt, 8417 XML_SCHEMAP_S4S_ELEM_MISSING, 8418 NULL, node, child, 8419 "A child element is missing", 8420 "(annotation?, (selector, field+))"); 8421 } 8422 /* 8423 * Child element <selector>. 8424 */ 8425 if (IS_SCHEMA(child, "selector")) { 8426 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8427 item, child, 0); 8428 child = child->next; 8429 /* 8430 * Child elements <field>. 8431 */ 8432 if (IS_SCHEMA(child, "field")) { 8433 do { 8434 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8435 item, child, 1); 8436 if (field != NULL) { 8437 field->index = item->nbFields; 8438 item->nbFields++; 8439 if (lastField != NULL) 8440 lastField->next = field; 8441 else 8442 item->fields = field; 8443 lastField = field; 8444 } 8445 child = child->next; 8446 } while (IS_SCHEMA(child, "field")); 8447 } else { 8448 xmlSchemaPContentErr(ctxt, 8449 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8450 NULL, node, child, 8451 NULL, "(annotation?, (selector, field+))"); 8452 } 8453 } 8454 if (child != NULL) { 8455 xmlSchemaPContentErr(ctxt, 8456 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8457 NULL, node, child, 8458 NULL, "(annotation?, (selector, field+))"); 8459 } 8460 8461 return (item); 8462 } 8463 8464 /** 8465 * xmlSchemaParseElement: 8466 * @ctxt: a schema validation context 8467 * @schema: the schema being built 8468 * @node: a subtree containing XML Schema informations 8469 * @topLevel: indicates if this is global declaration 8470 * 8471 * Parses a XML schema element declaration. 8472 * *WARNING* this interface is highly subject to change 8473 * 8474 * Returns the element declaration or a particle; NULL in case 8475 * of an error or if the particle has minOccurs==maxOccurs==0. 8476 */ 8477 static xmlSchemaBasicItemPtr 8478 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8479 xmlNodePtr node, int *isElemRef, int topLevel) 8480 { 8481 xmlSchemaElementPtr decl = NULL; 8482 xmlSchemaParticlePtr particle = NULL; 8483 xmlSchemaAnnotPtr annot = NULL; 8484 xmlNodePtr child = NULL; 8485 xmlAttrPtr attr, nameAttr; 8486 int min, max, isRef = 0; 8487 xmlChar *des = NULL; 8488 8489 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8490 /* TODO: Complete implementation of 3.3.6 */ 8491 8492 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8493 return (NULL); 8494 8495 if (isElemRef != NULL) 8496 *isElemRef = 0; 8497 /* 8498 * If we get a "ref" attribute on a local <element> we will assume it's 8499 * a reference - even if there's a "name" attribute; this seems to be more 8500 * robust. 8501 */ 8502 nameAttr = xmlSchemaGetPropNode(node, "name"); 8503 attr = xmlSchemaGetPropNode(node, "ref"); 8504 if ((topLevel) || (attr == NULL)) { 8505 if (nameAttr == NULL) { 8506 xmlSchemaPMissingAttrErr(ctxt, 8507 XML_SCHEMAP_S4S_ATTR_MISSING, 8508 NULL, node, "name", NULL); 8509 return (NULL); 8510 } 8511 } else 8512 isRef = 1; 8513 8514 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8515 child = node->children; 8516 if (IS_SCHEMA(child, "annotation")) { 8517 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8518 child = child->next; 8519 } 8520 /* 8521 * Skip particle part if a global declaration. 8522 */ 8523 if (topLevel) 8524 goto declaration_part; 8525 /* 8526 * The particle part ================================================== 8527 */ 8528 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8529 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8530 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8531 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8532 if (particle == NULL) 8533 goto return_null; 8534 8535 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8536 8537 if (isRef) { 8538 const xmlChar *refNs = NULL, *ref = NULL; 8539 xmlSchemaQNameRefPtr refer = NULL; 8540 /* 8541 * The reference part ============================================= 8542 */ 8543 if (isElemRef != NULL) 8544 *isElemRef = 1; 8545 8546 xmlSchemaPValAttrNodeQName(ctxt, schema, 8547 NULL, attr, &refNs, &ref); 8548 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8549 /* 8550 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8551 */ 8552 if (nameAttr != NULL) { 8553 xmlSchemaPMutualExclAttrErr(ctxt, 8554 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8555 } 8556 /* 8557 * Check for illegal attributes. 8558 */ 8559 attr = node->properties; 8560 while (attr != NULL) { 8561 if (attr->ns == NULL) { 8562 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8563 xmlStrEqual(attr->name, BAD_CAST "name") || 8564 xmlStrEqual(attr->name, BAD_CAST "id") || 8565 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8566 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8567 { 8568 attr = attr->next; 8569 continue; 8570 } else { 8571 /* SPEC (3.3.3 : 2.2) */ 8572 xmlSchemaPCustomAttrErr(ctxt, 8573 XML_SCHEMAP_SRC_ELEMENT_2_2, 8574 NULL, NULL, attr, 8575 "Only the attributes 'minOccurs', 'maxOccurs' and " 8576 "'id' are allowed in addition to 'ref'"); 8577 break; 8578 } 8579 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8580 xmlSchemaPIllegalAttrErr(ctxt, 8581 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8582 } 8583 attr = attr->next; 8584 } 8585 /* 8586 * No children except <annotation> expected. 8587 */ 8588 if (child != NULL) { 8589 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8590 NULL, node, child, NULL, "(annotation?)"); 8591 } 8592 if ((min == 0) && (max == 0)) 8593 goto return_null; 8594 /* 8595 * Create the reference item and attach it to the particle. 8596 */ 8597 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8598 ref, refNs); 8599 if (refer == NULL) 8600 goto return_null; 8601 particle->children = (xmlSchemaTreeItemPtr) refer; 8602 particle->annot = annot; 8603 /* 8604 * Add the particle to pending components, since the reference 8605 * need to be resolved. 8606 */ 8607 WXS_ADD_PENDING(ctxt, particle); 8608 return ((xmlSchemaBasicItemPtr) particle); 8609 } 8610 /* 8611 * The declaration part =============================================== 8612 */ 8613 declaration_part: 8614 { 8615 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8616 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8617 8618 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8619 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8620 goto return_null; 8621 /* 8622 * Evaluate the target namespace. 8623 */ 8624 if (topLevel) { 8625 ns = ctxt->targetNamespace; 8626 } else { 8627 attr = xmlSchemaGetPropNode(node, "form"); 8628 if (attr != NULL) { 8629 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8630 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8631 ns = ctxt->targetNamespace; 8632 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8633 xmlSchemaPSimpleTypeErr(ctxt, 8634 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8635 NULL, (xmlNodePtr) attr, 8636 NULL, "(qualified | unqualified)", 8637 attrValue, NULL, NULL, NULL); 8638 } 8639 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8640 ns = ctxt->targetNamespace; 8641 } 8642 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8643 if (decl == NULL) { 8644 goto return_null; 8645 } 8646 /* 8647 * Check for illegal attributes. 8648 */ 8649 attr = node->properties; 8650 while (attr != NULL) { 8651 if (attr->ns == NULL) { 8652 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8653 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8654 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8655 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8656 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8657 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8658 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8659 { 8660 if (topLevel == 0) { 8661 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8662 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8663 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8664 { 8665 xmlSchemaPIllegalAttrErr(ctxt, 8666 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8667 } 8668 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8669 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8670 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8671 8672 xmlSchemaPIllegalAttrErr(ctxt, 8673 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8674 } 8675 } 8676 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8677 8678 xmlSchemaPIllegalAttrErr(ctxt, 8679 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8680 } 8681 attr = attr->next; 8682 } 8683 /* 8684 * Extract/validate attributes. 8685 */ 8686 if (topLevel) { 8687 /* 8688 * Process top attributes of global element declarations here. 8689 */ 8690 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8691 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8692 xmlSchemaPValAttrQName(ctxt, schema, 8693 NULL, node, "substitutionGroup", 8694 &(decl->substGroupNs), &(decl->substGroup)); 8695 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8696 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8697 /* 8698 * Attribute "final". 8699 */ 8700 attr = xmlSchemaGetPropNode(node, "final"); 8701 if (attr == NULL) { 8702 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8703 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8704 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8705 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8706 } else { 8707 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8708 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8709 -1, 8710 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8711 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8712 xmlSchemaPSimpleTypeErr(ctxt, 8713 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8714 NULL, (xmlNodePtr) attr, 8715 NULL, "(#all | List of (extension | restriction))", 8716 attrValue, NULL, NULL, NULL); 8717 } 8718 } 8719 } 8720 /* 8721 * Attribute "block". 8722 */ 8723 attr = xmlSchemaGetPropNode(node, "block"); 8724 if (attr == NULL) { 8725 /* 8726 * Apply default "block" values. 8727 */ 8728 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8729 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8730 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8731 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8732 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8733 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8734 } else { 8735 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8736 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8737 -1, 8738 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8739 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8740 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8741 xmlSchemaPSimpleTypeErr(ctxt, 8742 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8743 NULL, (xmlNodePtr) attr, 8744 NULL, "(#all | List of (extension | " 8745 "restriction | substitution))", attrValue, 8746 NULL, NULL, NULL); 8747 } 8748 } 8749 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8750 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8751 8752 attr = xmlSchemaGetPropNode(node, "type"); 8753 if (attr != NULL) { 8754 xmlSchemaPValAttrNodeQName(ctxt, schema, 8755 NULL, attr, 8756 &(decl->namedTypeNs), &(decl->namedType)); 8757 xmlSchemaCheckReference(ctxt, schema, node, 8758 attr, decl->namedTypeNs); 8759 } 8760 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8761 attr = xmlSchemaGetPropNode(node, "fixed"); 8762 if (attr != NULL) { 8763 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8764 if (decl->value != NULL) { 8765 /* 8766 * 3.3.3 : 1 8767 * default and fixed must not both be present. 8768 */ 8769 xmlSchemaPMutualExclAttrErr(ctxt, 8770 XML_SCHEMAP_SRC_ELEMENT_1, 8771 NULL, attr, "default", "fixed"); 8772 } else { 8773 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8774 decl->value = fixed; 8775 } 8776 } 8777 /* 8778 * And now for the children... 8779 */ 8780 if (IS_SCHEMA(child, "complexType")) { 8781 /* 8782 * 3.3.3 : 3 8783 * "type" and either <simpleType> or <complexType> are mutually 8784 * exclusive 8785 */ 8786 if (decl->namedType != NULL) { 8787 xmlSchemaPContentErr(ctxt, 8788 XML_SCHEMAP_SRC_ELEMENT_3, 8789 NULL, node, child, 8790 "The attribute 'type' and the <complexType> child are " 8791 "mutually exclusive", NULL); 8792 } else 8793 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8794 child = child->next; 8795 } else if (IS_SCHEMA(child, "simpleType")) { 8796 /* 8797 * 3.3.3 : 3 8798 * "type" and either <simpleType> or <complexType> are 8799 * mutually exclusive 8800 */ 8801 if (decl->namedType != NULL) { 8802 xmlSchemaPContentErr(ctxt, 8803 XML_SCHEMAP_SRC_ELEMENT_3, 8804 NULL, node, child, 8805 "The attribute 'type' and the <simpleType> child are " 8806 "mutually exclusive", NULL); 8807 } else 8808 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8809 child = child->next; 8810 } 8811 while ((IS_SCHEMA(child, "unique")) || 8812 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8813 if (IS_SCHEMA(child, "unique")) { 8814 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8815 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8816 } else if (IS_SCHEMA(child, "key")) { 8817 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8818 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8819 } else if (IS_SCHEMA(child, "keyref")) { 8820 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8821 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8822 } 8823 if (lastIDC != NULL) 8824 lastIDC->next = curIDC; 8825 else 8826 decl->idcs = (void *) curIDC; 8827 lastIDC = curIDC; 8828 child = child->next; 8829 } 8830 if (child != NULL) { 8831 xmlSchemaPContentErr(ctxt, 8832 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8833 NULL, node, child, 8834 NULL, "(annotation?, ((simpleType | complexType)?, " 8835 "(unique | key | keyref)*))"); 8836 } 8837 decl->annot = annot; 8838 } 8839 /* 8840 * NOTE: Element Declaration Representation OK 4. will be checked at a 8841 * different layer. 8842 */ 8843 FREE_AND_NULL(des) 8844 if (topLevel) 8845 return ((xmlSchemaBasicItemPtr) decl); 8846 else { 8847 particle->children = (xmlSchemaTreeItemPtr) decl; 8848 return ((xmlSchemaBasicItemPtr) particle); 8849 } 8850 8851 return_null: 8852 FREE_AND_NULL(des); 8853 if (annot != NULL) { 8854 if (particle != NULL) 8855 particle->annot = NULL; 8856 if (decl != NULL) 8857 decl->annot = NULL; 8858 xmlSchemaFreeAnnot(annot); 8859 } 8860 return (NULL); 8861 } 8862 8863 /** 8864 * xmlSchemaParseUnion: 8865 * @ctxt: a schema validation context 8866 * @schema: the schema being built 8867 * @node: a subtree containing XML Schema informations 8868 * 8869 * parse a XML schema Union definition 8870 * *WARNING* this interface is highly subject to change 8871 * 8872 * Returns -1 in case of internal error, 0 in case of success and a positive 8873 * error code otherwise. 8874 */ 8875 static int 8876 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8877 xmlNodePtr node) 8878 { 8879 xmlSchemaTypePtr type; 8880 xmlNodePtr child = NULL; 8881 xmlAttrPtr attr; 8882 const xmlChar *cur = NULL; 8883 8884 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8885 return (-1); 8886 /* Not a component, don't create it. */ 8887 type = ctxt->ctxtType; 8888 /* 8889 * Mark the simple type as being of variety "union". 8890 */ 8891 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8892 /* 8893 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8894 * then the `simple ur-type definition`." 8895 */ 8896 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8897 /* 8898 * Check for illegal attributes. 8899 */ 8900 attr = node->properties; 8901 while (attr != NULL) { 8902 if (attr->ns == NULL) { 8903 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8904 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8905 xmlSchemaPIllegalAttrErr(ctxt, 8906 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8907 } 8908 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8909 xmlSchemaPIllegalAttrErr(ctxt, 8910 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8911 } 8912 attr = attr->next; 8913 } 8914 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8915 /* 8916 * Attribute "memberTypes". This is a list of QNames. 8917 * TODO: Check the value to contain anything. 8918 */ 8919 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8920 if (attr != NULL) { 8921 const xmlChar *end; 8922 xmlChar *tmp; 8923 const xmlChar *localName, *nsName; 8924 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8925 xmlSchemaQNameRefPtr ref; 8926 8927 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8928 type->base = cur; 8929 do { 8930 while (IS_BLANK_CH(*cur)) 8931 cur++; 8932 end = cur; 8933 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8934 end++; 8935 if (end == cur) 8936 break; 8937 tmp = xmlStrndup(cur, end - cur); 8938 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8939 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8940 /* 8941 * Create the member type link. 8942 */ 8943 link = (xmlSchemaTypeLinkPtr) 8944 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8945 if (link == NULL) { 8946 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8947 "allocating a type link", NULL); 8948 return (-1); 8949 } 8950 link->type = NULL; 8951 link->next = NULL; 8952 if (lastLink == NULL) 8953 type->memberTypes = link; 8954 else 8955 lastLink->next = link; 8956 lastLink = link; 8957 /* 8958 * Create a reference item. 8959 */ 8960 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8961 localName, nsName); 8962 if (ref == NULL) { 8963 FREE_AND_NULL(tmp) 8964 return (-1); 8965 } 8966 /* 8967 * Assign the reference to the link, it will be resolved 8968 * later during fixup of the union simple type. 8969 */ 8970 link->type = (xmlSchemaTypePtr) ref; 8971 } 8972 FREE_AND_NULL(tmp) 8973 cur = end; 8974 } while (*cur != 0); 8975 8976 } 8977 /* 8978 * And now for the children... 8979 */ 8980 child = node->children; 8981 if (IS_SCHEMA(child, "annotation")) { 8982 /* 8983 * Add the annotation to the simple type ancestor. 8984 */ 8985 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8986 xmlSchemaParseAnnotation(ctxt, child, 1)); 8987 child = child->next; 8988 } 8989 if (IS_SCHEMA(child, "simpleType")) { 8990 xmlSchemaTypePtr subtype, last = NULL; 8991 8992 /* 8993 * Anchor the member types in the "subtypes" field of the 8994 * simple type. 8995 */ 8996 while (IS_SCHEMA(child, "simpleType")) { 8997 subtype = (xmlSchemaTypePtr) 8998 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8999 if (subtype != NULL) { 9000 if (last == NULL) { 9001 type->subtypes = subtype; 9002 last = subtype; 9003 } else { 9004 last->next = subtype; 9005 last = subtype; 9006 } 9007 last->next = NULL; 9008 } 9009 child = child->next; 9010 } 9011 } 9012 if (child != NULL) { 9013 xmlSchemaPContentErr(ctxt, 9014 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9015 NULL, node, child, NULL, "(annotation?, simpleType*)"); 9016 } 9017 if ((attr == NULL) && (type->subtypes == NULL)) { 9018 /* 9019 * src-union-memberTypes-or-simpleTypes 9020 * Either the memberTypes [attribute] of the <union> element must 9021 * be non-empty or there must be at least one simpleType [child]. 9022 */ 9023 xmlSchemaPCustomErr(ctxt, 9024 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9025 NULL, node, 9026 "Either the attribute 'memberTypes' or " 9027 "at least one <simpleType> child must be present", NULL); 9028 } 9029 return (0); 9030 } 9031 9032 /** 9033 * xmlSchemaParseList: 9034 * @ctxt: a schema validation context 9035 * @schema: the schema being built 9036 * @node: a subtree containing XML Schema informations 9037 * 9038 * parse a XML schema List definition 9039 * *WARNING* this interface is highly subject to change 9040 * 9041 * Returns -1 in case of error, 0 if the declaration is improper and 9042 * 1 in case of success. 9043 */ 9044 static xmlSchemaTypePtr 9045 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9046 xmlNodePtr node) 9047 { 9048 xmlSchemaTypePtr type; 9049 xmlNodePtr child = NULL; 9050 xmlAttrPtr attr; 9051 9052 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9053 return (NULL); 9054 /* Not a component, don't create it. */ 9055 type = ctxt->ctxtType; 9056 /* 9057 * Mark the type as being of variety "list". 9058 */ 9059 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9060 /* 9061 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9062 * then the `simple ur-type definition`." 9063 */ 9064 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9065 /* 9066 * Check for illegal attributes. 9067 */ 9068 attr = node->properties; 9069 while (attr != NULL) { 9070 if (attr->ns == NULL) { 9071 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9072 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9073 xmlSchemaPIllegalAttrErr(ctxt, 9074 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9075 } 9076 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9077 xmlSchemaPIllegalAttrErr(ctxt, 9078 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9079 } 9080 attr = attr->next; 9081 } 9082 9083 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9084 9085 /* 9086 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9087 * fields for holding the reference to the itemType. 9088 * 9089 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9090 * the "ref" fields. 9091 */ 9092 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9093 node, "itemType", &(type->baseNs), &(type->base)); 9094 /* 9095 * And now for the children... 9096 */ 9097 child = node->children; 9098 if (IS_SCHEMA(child, "annotation")) { 9099 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9100 xmlSchemaParseAnnotation(ctxt, child, 1)); 9101 child = child->next; 9102 } 9103 if (IS_SCHEMA(child, "simpleType")) { 9104 /* 9105 * src-list-itemType-or-simpleType 9106 * Either the itemType [attribute] or the <simpleType> [child] of 9107 * the <list> element must be present, but not both. 9108 */ 9109 if (type->base != NULL) { 9110 xmlSchemaPCustomErr(ctxt, 9111 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9112 NULL, node, 9113 "The attribute 'itemType' and the <simpleType> child " 9114 "are mutually exclusive", NULL); 9115 } else { 9116 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9117 } 9118 child = child->next; 9119 } else if (type->base == NULL) { 9120 xmlSchemaPCustomErr(ctxt, 9121 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9122 NULL, node, 9123 "Either the attribute 'itemType' or the <simpleType> child " 9124 "must be present", NULL); 9125 } 9126 if (child != NULL) { 9127 xmlSchemaPContentErr(ctxt, 9128 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9129 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9130 } 9131 if ((type->base == NULL) && 9132 (type->subtypes == NULL) && 9133 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9134 xmlSchemaPCustomErr(ctxt, 9135 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9136 NULL, node, 9137 "Either the attribute 'itemType' or the <simpleType> child " 9138 "must be present", NULL); 9139 } 9140 return (NULL); 9141 } 9142 9143 /** 9144 * xmlSchemaParseSimpleType: 9145 * @ctxt: a schema validation context 9146 * @schema: the schema being built 9147 * @node: a subtree containing XML Schema informations 9148 * 9149 * parse a XML schema Simple Type definition 9150 * *WARNING* this interface is highly subject to change 9151 * 9152 * Returns -1 in case of error, 0 if the declaration is improper and 9153 * 1 in case of success. 9154 */ 9155 static xmlSchemaTypePtr 9156 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9157 xmlNodePtr node, int topLevel) 9158 { 9159 xmlSchemaTypePtr type, oldCtxtType; 9160 xmlNodePtr child = NULL; 9161 const xmlChar *attrValue = NULL; 9162 xmlAttrPtr attr; 9163 int hasRestriction = 0; 9164 9165 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9166 return (NULL); 9167 9168 if (topLevel) { 9169 attr = xmlSchemaGetPropNode(node, "name"); 9170 if (attr == NULL) { 9171 xmlSchemaPMissingAttrErr(ctxt, 9172 XML_SCHEMAP_S4S_ATTR_MISSING, 9173 NULL, node, 9174 "name", NULL); 9175 return (NULL); 9176 } else { 9177 if (xmlSchemaPValAttrNode(ctxt, 9178 NULL, attr, 9179 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9180 return (NULL); 9181 /* 9182 * Skip built-in types. 9183 */ 9184 if (ctxt->isS4S) { 9185 xmlSchemaTypePtr biType; 9186 9187 if (ctxt->isRedefine) { 9188 /* 9189 * REDEFINE: Disallow redefinition of built-in-types. 9190 * TODO: It seems that the spec does not say anything 9191 * about this case. 9192 */ 9193 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9194 NULL, node, 9195 "Redefinition of built-in simple types is not " 9196 "supported", NULL); 9197 return(NULL); 9198 } 9199 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9200 if (biType != NULL) 9201 return (biType); 9202 } 9203 } 9204 } 9205 /* 9206 * TargetNamespace: 9207 * SPEC "The `actual value` of the targetNamespace [attribute] 9208 * of the <schema> ancestor element information item if present, 9209 * otherwise `absent`. 9210 */ 9211 if (topLevel == 0) { 9212 #ifdef ENABLE_NAMED_LOCALS 9213 char buf[40]; 9214 #endif 9215 /* 9216 * Parse as local simple type definition. 9217 */ 9218 #ifdef ENABLE_NAMED_LOCALS 9219 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9220 type = xmlSchemaAddType(ctxt, schema, 9221 XML_SCHEMA_TYPE_SIMPLE, 9222 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9223 ctxt->targetNamespace, node, 0); 9224 #else 9225 type = xmlSchemaAddType(ctxt, schema, 9226 XML_SCHEMA_TYPE_SIMPLE, 9227 NULL, ctxt->targetNamespace, node, 0); 9228 #endif 9229 if (type == NULL) 9230 return (NULL); 9231 type->type = XML_SCHEMA_TYPE_SIMPLE; 9232 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9233 /* 9234 * Check for illegal attributes. 9235 */ 9236 attr = node->properties; 9237 while (attr != NULL) { 9238 if (attr->ns == NULL) { 9239 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9240 xmlSchemaPIllegalAttrErr(ctxt, 9241 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9242 } 9243 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9244 xmlSchemaPIllegalAttrErr(ctxt, 9245 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9246 } 9247 attr = attr->next; 9248 } 9249 } else { 9250 /* 9251 * Parse as global simple type definition. 9252 * 9253 * Note that attrValue is the value of the attribute "name" here. 9254 */ 9255 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9256 attrValue, ctxt->targetNamespace, node, 1); 9257 if (type == NULL) 9258 return (NULL); 9259 type->type = XML_SCHEMA_TYPE_SIMPLE; 9260 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9261 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9262 /* 9263 * Check for illegal attributes. 9264 */ 9265 attr = node->properties; 9266 while (attr != NULL) { 9267 if (attr->ns == NULL) { 9268 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9269 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9270 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9271 xmlSchemaPIllegalAttrErr(ctxt, 9272 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9273 } 9274 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9275 xmlSchemaPIllegalAttrErr(ctxt, 9276 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9277 } 9278 attr = attr->next; 9279 } 9280 /* 9281 * Attribute "final". 9282 */ 9283 attr = xmlSchemaGetPropNode(node, "final"); 9284 if (attr == NULL) { 9285 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9286 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9287 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9288 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9289 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9290 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9291 } else { 9292 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9293 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9294 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9295 XML_SCHEMAS_TYPE_FINAL_LIST, 9296 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9297 9298 xmlSchemaPSimpleTypeErr(ctxt, 9299 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9300 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9301 NULL, "(#all | List of (list | union | restriction)", 9302 attrValue, NULL, NULL, NULL); 9303 } 9304 } 9305 } 9306 type->targetNamespace = ctxt->targetNamespace; 9307 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9308 /* 9309 * And now for the children... 9310 */ 9311 oldCtxtType = ctxt->ctxtType; 9312 9313 ctxt->ctxtType = type; 9314 9315 child = node->children; 9316 if (IS_SCHEMA(child, "annotation")) { 9317 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9318 child = child->next; 9319 } 9320 if (child == NULL) { 9321 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9322 NULL, node, child, NULL, 9323 "(annotation?, (restriction | list | union))"); 9324 } else if (IS_SCHEMA(child, "restriction")) { 9325 xmlSchemaParseRestriction(ctxt, schema, child, 9326 XML_SCHEMA_TYPE_SIMPLE); 9327 hasRestriction = 1; 9328 child = child->next; 9329 } else if (IS_SCHEMA(child, "list")) { 9330 xmlSchemaParseList(ctxt, schema, child); 9331 child = child->next; 9332 } else if (IS_SCHEMA(child, "union")) { 9333 xmlSchemaParseUnion(ctxt, schema, child); 9334 child = child->next; 9335 } 9336 if (child != NULL) { 9337 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9338 NULL, node, child, NULL, 9339 "(annotation?, (restriction | list | union))"); 9340 } 9341 /* 9342 * REDEFINE: SPEC src-redefine (5) 9343 * "Within the [children], each <simpleType> must have a 9344 * <restriction> among its [children] ... the `actual value` of whose 9345 * base [attribute] must be the same as the `actual value` of its own 9346 * name attribute plus target namespace;" 9347 */ 9348 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9349 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9350 NULL, node, "This is a redefinition, thus the " 9351 "<simpleType> must have a <restriction> child", NULL); 9352 } 9353 9354 ctxt->ctxtType = oldCtxtType; 9355 return (type); 9356 } 9357 9358 /** 9359 * xmlSchemaParseModelGroupDefRef: 9360 * @ctxt: the parser context 9361 * @schema: the schema being built 9362 * @node: the node 9363 * 9364 * Parses a reference to a model group definition. 9365 * 9366 * We will return a particle component with a qname-component or 9367 * NULL in case of an error. 9368 */ 9369 static xmlSchemaTreeItemPtr 9370 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9371 xmlSchemaPtr schema, 9372 xmlNodePtr node) 9373 { 9374 xmlSchemaParticlePtr item; 9375 xmlNodePtr child = NULL; 9376 xmlAttrPtr attr; 9377 const xmlChar *ref = NULL, *refNs = NULL; 9378 int min, max; 9379 9380 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9381 return (NULL); 9382 9383 attr = xmlSchemaGetPropNode(node, "ref"); 9384 if (attr == NULL) { 9385 xmlSchemaPMissingAttrErr(ctxt, 9386 XML_SCHEMAP_S4S_ATTR_MISSING, 9387 NULL, node, "ref", NULL); 9388 return (NULL); 9389 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9390 attr, &refNs, &ref) != 0) { 9391 return (NULL); 9392 } 9393 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9394 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9395 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9396 "(xs:nonNegativeInteger | unbounded)"); 9397 /* 9398 * Check for illegal attributes. 9399 */ 9400 attr = node->properties; 9401 while (attr != NULL) { 9402 if (attr->ns == NULL) { 9403 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9404 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9405 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9406 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9407 xmlSchemaPIllegalAttrErr(ctxt, 9408 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9409 } 9410 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9411 xmlSchemaPIllegalAttrErr(ctxt, 9412 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9413 } 9414 attr = attr->next; 9415 } 9416 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9417 item = xmlSchemaAddParticle(ctxt, node, min, max); 9418 if (item == NULL) 9419 return (NULL); 9420 /* 9421 * Create a qname-reference and set as the term; it will be substituted 9422 * for the model group after the reference has been resolved. 9423 */ 9424 item->children = (xmlSchemaTreeItemPtr) 9425 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9426 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9427 /* 9428 * And now for the children... 9429 */ 9430 child = node->children; 9431 /* TODO: Is annotation even allowed for a model group reference? */ 9432 if (IS_SCHEMA(child, "annotation")) { 9433 /* 9434 * TODO: What to do exactly with the annotation? 9435 */ 9436 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9437 child = child->next; 9438 } 9439 if (child != NULL) { 9440 xmlSchemaPContentErr(ctxt, 9441 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9442 NULL, node, child, NULL, 9443 "(annotation?)"); 9444 } 9445 /* 9446 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9447 */ 9448 if ((min == 0) && (max == 0)) 9449 return (NULL); 9450 9451 return ((xmlSchemaTreeItemPtr) item); 9452 } 9453 9454 /** 9455 * xmlSchemaParseModelGroupDefinition: 9456 * @ctxt: a schema validation context 9457 * @schema: the schema being built 9458 * @node: a subtree containing XML Schema informations 9459 * 9460 * Parses a XML schema model group definition. 9461 * 9462 * Note that the constraint src-redefine (6.2) can't be applied until 9463 * references have been resolved. So we will do this at the 9464 * component fixup level. 9465 * 9466 * *WARNING* this interface is highly subject to change 9467 * 9468 * Returns -1 in case of error, 0 if the declaration is improper and 9469 * 1 in case of success. 9470 */ 9471 static xmlSchemaModelGroupDefPtr 9472 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9473 xmlSchemaPtr schema, 9474 xmlNodePtr node) 9475 { 9476 xmlSchemaModelGroupDefPtr item; 9477 xmlNodePtr child = NULL; 9478 xmlAttrPtr attr; 9479 const xmlChar *name; 9480 9481 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9482 return (NULL); 9483 9484 attr = xmlSchemaGetPropNode(node, "name"); 9485 if (attr == NULL) { 9486 xmlSchemaPMissingAttrErr(ctxt, 9487 XML_SCHEMAP_S4S_ATTR_MISSING, 9488 NULL, node, 9489 "name", NULL); 9490 return (NULL); 9491 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9492 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9493 return (NULL); 9494 } 9495 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9496 ctxt->targetNamespace, node); 9497 if (item == NULL) 9498 return (NULL); 9499 /* 9500 * Check for illegal attributes. 9501 */ 9502 attr = node->properties; 9503 while (attr != NULL) { 9504 if (attr->ns == NULL) { 9505 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9506 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9507 xmlSchemaPIllegalAttrErr(ctxt, 9508 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9509 } 9510 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9511 xmlSchemaPIllegalAttrErr(ctxt, 9512 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9513 } 9514 attr = attr->next; 9515 } 9516 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9517 /* 9518 * And now for the children... 9519 */ 9520 child = node->children; 9521 if (IS_SCHEMA(child, "annotation")) { 9522 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9523 child = child->next; 9524 } 9525 if (IS_SCHEMA(child, "all")) { 9526 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9527 XML_SCHEMA_TYPE_ALL, 0); 9528 child = child->next; 9529 } else if (IS_SCHEMA(child, "choice")) { 9530 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9531 XML_SCHEMA_TYPE_CHOICE, 0); 9532 child = child->next; 9533 } else if (IS_SCHEMA(child, "sequence")) { 9534 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9535 XML_SCHEMA_TYPE_SEQUENCE, 0); 9536 child = child->next; 9537 } 9538 9539 9540 9541 if (child != NULL) { 9542 xmlSchemaPContentErr(ctxt, 9543 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9544 NULL, node, child, NULL, 9545 "(annotation?, (all | choice | sequence)?)"); 9546 } 9547 return (item); 9548 } 9549 9550 /** 9551 * xmlSchemaCleanupDoc: 9552 * @ctxt: a schema validation context 9553 * @node: the root of the document. 9554 * 9555 * removes unwanted nodes in a schemas document tree 9556 */ 9557 static void 9558 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9559 { 9560 xmlNodePtr delete, cur; 9561 9562 if ((ctxt == NULL) || (root == NULL)) return; 9563 9564 /* 9565 * Remove all the blank text nodes 9566 */ 9567 delete = NULL; 9568 cur = root; 9569 while (cur != NULL) { 9570 if (delete != NULL) { 9571 xmlUnlinkNode(delete); 9572 xmlFreeNode(delete); 9573 delete = NULL; 9574 } 9575 if (cur->type == XML_TEXT_NODE) { 9576 if (IS_BLANK_NODE(cur)) { 9577 if (xmlNodeGetSpacePreserve(cur) != 1) { 9578 delete = cur; 9579 } 9580 } 9581 } else if ((cur->type != XML_ELEMENT_NODE) && 9582 (cur->type != XML_CDATA_SECTION_NODE)) { 9583 delete = cur; 9584 goto skip_children; 9585 } 9586 9587 /* 9588 * Skip to next node 9589 */ 9590 if (cur->children != NULL) { 9591 if ((cur->children->type != XML_ENTITY_DECL) && 9592 (cur->children->type != XML_ENTITY_REF_NODE) && 9593 (cur->children->type != XML_ENTITY_NODE)) { 9594 cur = cur->children; 9595 continue; 9596 } 9597 } 9598 skip_children: 9599 if (cur->next != NULL) { 9600 cur = cur->next; 9601 continue; 9602 } 9603 9604 do { 9605 cur = cur->parent; 9606 if (cur == NULL) 9607 break; 9608 if (cur == root) { 9609 cur = NULL; 9610 break; 9611 } 9612 if (cur->next != NULL) { 9613 cur = cur->next; 9614 break; 9615 } 9616 } while (cur != NULL); 9617 } 9618 if (delete != NULL) { 9619 xmlUnlinkNode(delete); 9620 xmlFreeNode(delete); 9621 delete = NULL; 9622 } 9623 } 9624 9625 9626 static void 9627 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9628 { 9629 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9630 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9631 9632 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9633 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9634 9635 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9636 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9637 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9638 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9639 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9640 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9641 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9642 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9643 9644 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9645 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9646 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9647 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9648 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9649 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9650 } 9651 9652 static int 9653 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9654 xmlSchemaPtr schema, 9655 xmlNodePtr node) 9656 { 9657 xmlAttrPtr attr; 9658 const xmlChar *val; 9659 int res = 0, oldErrs = ctxt->nberrors; 9660 9661 /* 9662 * Those flags should be moved to the parser context flags, 9663 * since they are not visible at the component level. I.e. 9664 * they are used if processing schema *documents* only. 9665 */ 9666 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9667 HFAILURE; 9668 9669 /* 9670 * Since the version is of type xs:token, we won't bother to 9671 * check it. 9672 */ 9673 /* REMOVED: 9674 attr = xmlSchemaGetPropNode(node, "version"); 9675 if (attr != NULL) { 9676 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9677 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9678 HFAILURE; 9679 } 9680 */ 9681 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9682 if (attr != NULL) { 9683 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9684 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9685 HFAILURE; 9686 if (res != 0) { 9687 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9688 goto exit; 9689 } 9690 } 9691 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9692 if (attr != NULL) { 9693 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9694 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9695 XML_SCHEMAS_QUALIF_ELEM); 9696 HFAILURE; 9697 if (res != 0) { 9698 xmlSchemaPSimpleTypeErr(ctxt, 9699 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9700 NULL, (xmlNodePtr) attr, NULL, 9701 "(qualified | unqualified)", val, NULL, NULL, NULL); 9702 } 9703 } 9704 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9705 if (attr != NULL) { 9706 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9707 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9708 XML_SCHEMAS_QUALIF_ATTR); 9709 HFAILURE; 9710 if (res != 0) { 9711 xmlSchemaPSimpleTypeErr(ctxt, 9712 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9713 NULL, (xmlNodePtr) attr, NULL, 9714 "(qualified | unqualified)", val, NULL, NULL, NULL); 9715 } 9716 } 9717 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9718 if (attr != NULL) { 9719 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9720 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9721 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9722 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9723 -1, 9724 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9725 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9726 HFAILURE; 9727 if (res != 0) { 9728 xmlSchemaPSimpleTypeErr(ctxt, 9729 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9730 NULL, (xmlNodePtr) attr, NULL, 9731 "(#all | List of (extension | restriction | list | union))", 9732 val, NULL, NULL, NULL); 9733 } 9734 } 9735 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9736 if (attr != NULL) { 9737 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9738 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9739 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9740 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9741 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9742 HFAILURE; 9743 if (res != 0) { 9744 xmlSchemaPSimpleTypeErr(ctxt, 9745 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9746 NULL, (xmlNodePtr) attr, NULL, 9747 "(#all | List of (extension | restriction | substitution))", 9748 val, NULL, NULL, NULL); 9749 } 9750 } 9751 9752 exit: 9753 if (oldErrs != ctxt->nberrors) 9754 res = ctxt->err; 9755 return(res); 9756 exit_failure: 9757 return(-1); 9758 } 9759 9760 /** 9761 * xmlSchemaParseSchemaTopLevel: 9762 * @ctxt: a schema validation context 9763 * @schema: the schemas 9764 * @nodes: the list of top level nodes 9765 * 9766 * Returns the internal XML Schema structure built from the resource or 9767 * NULL in case of error 9768 */ 9769 static int 9770 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9771 xmlSchemaPtr schema, xmlNodePtr nodes) 9772 { 9773 xmlNodePtr child; 9774 xmlSchemaAnnotPtr annot; 9775 int res = 0, oldErrs, tmpOldErrs; 9776 9777 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9778 return(-1); 9779 9780 oldErrs = ctxt->nberrors; 9781 child = nodes; 9782 while ((IS_SCHEMA(child, "include")) || 9783 (IS_SCHEMA(child, "import")) || 9784 (IS_SCHEMA(child, "redefine")) || 9785 (IS_SCHEMA(child, "annotation"))) { 9786 if (IS_SCHEMA(child, "annotation")) { 9787 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9788 if (schema->annot == NULL) 9789 schema->annot = annot; 9790 else 9791 xmlSchemaFreeAnnot(annot); 9792 } else if (IS_SCHEMA(child, "import")) { 9793 tmpOldErrs = ctxt->nberrors; 9794 res = xmlSchemaParseImport(ctxt, schema, child); 9795 HFAILURE; 9796 HSTOP(ctxt); 9797 if (tmpOldErrs != ctxt->nberrors) 9798 goto exit; 9799 } else if (IS_SCHEMA(child, "include")) { 9800 tmpOldErrs = ctxt->nberrors; 9801 res = xmlSchemaParseInclude(ctxt, schema, child); 9802 HFAILURE; 9803 HSTOP(ctxt); 9804 if (tmpOldErrs != ctxt->nberrors) 9805 goto exit; 9806 } else if (IS_SCHEMA(child, "redefine")) { 9807 tmpOldErrs = ctxt->nberrors; 9808 res = xmlSchemaParseRedefine(ctxt, schema, child); 9809 HFAILURE; 9810 HSTOP(ctxt); 9811 if (tmpOldErrs != ctxt->nberrors) 9812 goto exit; 9813 } 9814 child = child->next; 9815 } 9816 /* 9817 * URGENT TODO: Change the functions to return int results. 9818 * We need especially to catch internal errors. 9819 */ 9820 while (child != NULL) { 9821 if (IS_SCHEMA(child, "complexType")) { 9822 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9823 child = child->next; 9824 } else if (IS_SCHEMA(child, "simpleType")) { 9825 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9826 child = child->next; 9827 } else if (IS_SCHEMA(child, "element")) { 9828 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9829 child = child->next; 9830 } else if (IS_SCHEMA(child, "attribute")) { 9831 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9832 child = child->next; 9833 } else if (IS_SCHEMA(child, "attributeGroup")) { 9834 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9835 child = child->next; 9836 } else if (IS_SCHEMA(child, "group")) { 9837 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9838 child = child->next; 9839 } else if (IS_SCHEMA(child, "notation")) { 9840 xmlSchemaParseNotation(ctxt, schema, child); 9841 child = child->next; 9842 } else { 9843 xmlSchemaPContentErr(ctxt, 9844 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9845 NULL, child->parent, child, 9846 NULL, "((include | import | redefine | annotation)*, " 9847 "(((simpleType | complexType | group | attributeGroup) " 9848 "| element | attribute | notation), annotation*)*)"); 9849 child = child->next; 9850 } 9851 while (IS_SCHEMA(child, "annotation")) { 9852 /* 9853 * TODO: We should add all annotations. 9854 */ 9855 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9856 if (schema->annot == NULL) 9857 schema->annot = annot; 9858 else 9859 xmlSchemaFreeAnnot(annot); 9860 child = child->next; 9861 } 9862 } 9863 exit: 9864 ctxt->ctxtType = NULL; 9865 if (oldErrs != ctxt->nberrors) 9866 res = ctxt->err; 9867 return(res); 9868 exit_failure: 9869 return(-1); 9870 } 9871 9872 static xmlSchemaSchemaRelationPtr 9873 xmlSchemaSchemaRelationCreate(void) 9874 { 9875 xmlSchemaSchemaRelationPtr ret; 9876 9877 ret = (xmlSchemaSchemaRelationPtr) 9878 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9879 if (ret == NULL) { 9880 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9881 return(NULL); 9882 } 9883 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9884 return(ret); 9885 } 9886 9887 #if 0 9888 static void 9889 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9890 { 9891 xmlFree(rel); 9892 } 9893 #endif 9894 9895 static void 9896 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9897 { 9898 xmlSchemaRedefPtr prev; 9899 9900 while (redef != NULL) { 9901 prev = redef; 9902 redef = redef->next; 9903 xmlFree(prev); 9904 } 9905 } 9906 9907 static void 9908 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9909 { 9910 /* 9911 * After the construction context has been freed, there will be 9912 * no schema graph available any more. Only the schema buckets 9913 * will stay alive, which are put into the "schemasImports" and 9914 * "includes" slots of the xmlSchema. 9915 */ 9916 if (con->buckets != NULL) 9917 xmlSchemaItemListFree(con->buckets); 9918 if (con->pending != NULL) 9919 xmlSchemaItemListFree(con->pending); 9920 if (con->substGroups != NULL) 9921 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); 9922 if (con->redefs != NULL) 9923 xmlSchemaRedefListFree(con->redefs); 9924 if (con->dict != NULL) 9925 xmlDictFree(con->dict); 9926 xmlFree(con); 9927 } 9928 9929 static xmlSchemaConstructionCtxtPtr 9930 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9931 { 9932 xmlSchemaConstructionCtxtPtr ret; 9933 9934 ret = (xmlSchemaConstructionCtxtPtr) 9935 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9936 if (ret == NULL) { 9937 xmlSchemaPErrMemory(NULL, 9938 "allocating schema construction context", NULL); 9939 return (NULL); 9940 } 9941 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9942 9943 ret->buckets = xmlSchemaItemListCreate(); 9944 if (ret->buckets == NULL) { 9945 xmlSchemaPErrMemory(NULL, 9946 "allocating list of schema buckets", NULL); 9947 xmlFree(ret); 9948 return (NULL); 9949 } 9950 ret->pending = xmlSchemaItemListCreate(); 9951 if (ret->pending == NULL) { 9952 xmlSchemaPErrMemory(NULL, 9953 "allocating list of pending global components", NULL); 9954 xmlSchemaConstructionCtxtFree(ret); 9955 return (NULL); 9956 } 9957 ret->dict = dict; 9958 xmlDictReference(dict); 9959 return(ret); 9960 } 9961 9962 static xmlSchemaParserCtxtPtr 9963 xmlSchemaParserCtxtCreate(void) 9964 { 9965 xmlSchemaParserCtxtPtr ret; 9966 9967 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9968 if (ret == NULL) { 9969 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9970 NULL); 9971 return (NULL); 9972 } 9973 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9974 ret->type = XML_SCHEMA_CTXT_PARSER; 9975 ret->attrProhibs = xmlSchemaItemListCreate(); 9976 if (ret->attrProhibs == NULL) { 9977 xmlFree(ret); 9978 return(NULL); 9979 } 9980 return(ret); 9981 } 9982 9983 /** 9984 * xmlSchemaNewParserCtxtUseDict: 9985 * @URL: the location of the schema 9986 * @dict: the dictionary to be used 9987 * 9988 * Create an XML Schemas parse context for that file/resource expected 9989 * to contain an XML Schemas file. 9990 * 9991 * Returns the parser context or NULL in case of error 9992 */ 9993 static xmlSchemaParserCtxtPtr 9994 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9995 { 9996 xmlSchemaParserCtxtPtr ret; 9997 9998 ret = xmlSchemaParserCtxtCreate(); 9999 if (ret == NULL) 10000 return (NULL); 10001 ret->dict = dict; 10002 xmlDictReference(dict); 10003 if (URL != NULL) 10004 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 10005 return (ret); 10006 } 10007 10008 static int 10009 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 10010 { 10011 if (vctxt->pctxt == NULL) { 10012 if (vctxt->schema != NULL) 10013 vctxt->pctxt = 10014 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 10015 else 10016 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 10017 if (vctxt->pctxt == NULL) { 10018 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 10019 "failed to create a temp. parser context"); 10020 return (-1); 10021 } 10022 /* TODO: Pass user data. */ 10023 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10024 vctxt->warning, vctxt->errCtxt); 10025 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10026 vctxt->errCtxt); 10027 } 10028 return (0); 10029 } 10030 10031 /** 10032 * xmlSchemaGetSchemaBucket: 10033 * @pctxt: the schema parser context 10034 * @schemaLocation: the URI of the schema document 10035 * 10036 * Returns a schema bucket if it was already parsed. 10037 * 10038 * Returns a schema bucket if it was already parsed from 10039 * @schemaLocation, NULL otherwise. 10040 */ 10041 static xmlSchemaBucketPtr 10042 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10043 const xmlChar *schemaLocation) 10044 { 10045 xmlSchemaBucketPtr cur; 10046 xmlSchemaItemListPtr list; 10047 10048 list = pctxt->constructor->buckets; 10049 if (list->nbItems == 0) 10050 return(NULL); 10051 else { 10052 int i; 10053 for (i = 0; i < list->nbItems; i++) { 10054 cur = (xmlSchemaBucketPtr) list->items[i]; 10055 /* Pointer comparison! */ 10056 if (cur->schemaLocation == schemaLocation) 10057 return(cur); 10058 } 10059 } 10060 return(NULL); 10061 } 10062 10063 static xmlSchemaBucketPtr 10064 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10065 const xmlChar *schemaLocation, 10066 const xmlChar *targetNamespace) 10067 { 10068 xmlSchemaBucketPtr cur; 10069 xmlSchemaItemListPtr list; 10070 10071 list = pctxt->constructor->buckets; 10072 if (list->nbItems == 0) 10073 return(NULL); 10074 else { 10075 int i; 10076 for (i = 0; i < list->nbItems; i++) { 10077 cur = (xmlSchemaBucketPtr) list->items[i]; 10078 /* Pointer comparison! */ 10079 if ((cur->origTargetNamespace == NULL) && 10080 (cur->schemaLocation == schemaLocation) && 10081 (cur->targetNamespace == targetNamespace)) 10082 return(cur); 10083 } 10084 } 10085 return(NULL); 10086 } 10087 10088 10089 #define IS_BAD_SCHEMA_DOC(b) \ 10090 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10091 10092 static xmlSchemaBucketPtr 10093 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10094 const xmlChar *targetNamespace, 10095 int imported) 10096 { 10097 xmlSchemaBucketPtr cur; 10098 xmlSchemaItemListPtr list; 10099 10100 list = pctxt->constructor->buckets; 10101 if (list->nbItems == 0) 10102 return(NULL); 10103 else { 10104 int i; 10105 for (i = 0; i < list->nbItems; i++) { 10106 cur = (xmlSchemaBucketPtr) list->items[i]; 10107 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10108 (cur->origTargetNamespace == targetNamespace) && 10109 ((imported && cur->imported) || 10110 ((!imported) && (!cur->imported)))) 10111 return(cur); 10112 } 10113 } 10114 return(NULL); 10115 } 10116 10117 static int 10118 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10119 xmlSchemaPtr schema, 10120 xmlSchemaBucketPtr bucket) 10121 { 10122 int oldFlags; 10123 xmlDocPtr oldDoc; 10124 xmlNodePtr node; 10125 int ret, oldErrs; 10126 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10127 10128 /* 10129 * Save old values; reset the *main* schema. 10130 * URGENT TODO: This is not good; move the per-document information 10131 * to the parser. Get rid of passing the main schema to the 10132 * parsing functions. 10133 */ 10134 oldFlags = schema->flags; 10135 oldDoc = schema->doc; 10136 if (schema->flags != 0) 10137 xmlSchemaClearSchemaDefaults(schema); 10138 schema->doc = bucket->doc; 10139 pctxt->schema = schema; 10140 /* 10141 * Keep the current target namespace on the parser *not* on the 10142 * main schema. 10143 */ 10144 pctxt->targetNamespace = bucket->targetNamespace; 10145 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10146 10147 if ((bucket->targetNamespace != NULL) && 10148 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10149 /* 10150 * We are parsing the schema for schemas! 10151 */ 10152 pctxt->isS4S = 1; 10153 } 10154 /* Mark it as parsed, even if parsing fails. */ 10155 bucket->parsed++; 10156 /* Compile the schema doc. */ 10157 node = xmlDocGetRootElement(bucket->doc); 10158 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10159 if (ret != 0) 10160 goto exit; 10161 /* An empty schema; just get out. */ 10162 if (node->children == NULL) 10163 goto exit; 10164 oldErrs = pctxt->nberrors; 10165 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10166 if (ret != 0) 10167 goto exit; 10168 /* 10169 * TODO: Not nice, but I'm not 100% sure we will get always an error 10170 * as a result of the above functions; so better rely on pctxt->err 10171 * as well. 10172 */ 10173 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10174 ret = pctxt->err; 10175 goto exit; 10176 } 10177 10178 exit: 10179 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10180 /* Restore schema values. */ 10181 schema->doc = oldDoc; 10182 schema->flags = oldFlags; 10183 return(ret); 10184 } 10185 10186 static int 10187 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10188 xmlSchemaPtr schema, 10189 xmlSchemaBucketPtr bucket) 10190 { 10191 xmlSchemaParserCtxtPtr newpctxt; 10192 int res = 0; 10193 10194 if (bucket == NULL) 10195 return(0); 10196 if (bucket->parsed) { 10197 PERROR_INT("xmlSchemaParseNewDoc", 10198 "reparsing a schema doc"); 10199 return(-1); 10200 } 10201 if (bucket->doc == NULL) { 10202 PERROR_INT("xmlSchemaParseNewDoc", 10203 "parsing a schema doc, but there's no doc"); 10204 return(-1); 10205 } 10206 if (pctxt->constructor == NULL) { 10207 PERROR_INT("xmlSchemaParseNewDoc", 10208 "no constructor"); 10209 return(-1); 10210 } 10211 /* Create and init the temporary parser context. */ 10212 newpctxt = xmlSchemaNewParserCtxtUseDict( 10213 (const char *) bucket->schemaLocation, pctxt->dict); 10214 if (newpctxt == NULL) 10215 return(-1); 10216 newpctxt->constructor = pctxt->constructor; 10217 /* 10218 * TODO: Can we avoid that the parser knows about the main schema? 10219 * It would be better if he knows about the current schema bucket 10220 * only. 10221 */ 10222 newpctxt->schema = schema; 10223 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10224 pctxt->errCtxt); 10225 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10226 pctxt->errCtxt); 10227 newpctxt->counter = pctxt->counter; 10228 10229 10230 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10231 10232 /* Channel back errors and cleanup the temporary parser context. */ 10233 if (res != 0) 10234 pctxt->err = res; 10235 pctxt->nberrors += newpctxt->nberrors; 10236 pctxt->counter = newpctxt->counter; 10237 newpctxt->constructor = NULL; 10238 /* Free the parser context. */ 10239 xmlSchemaFreeParserCtxt(newpctxt); 10240 return(res); 10241 } 10242 10243 static void 10244 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10245 xmlSchemaSchemaRelationPtr rel) 10246 { 10247 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10248 10249 if (cur == NULL) { 10250 bucket->relations = rel; 10251 return; 10252 } 10253 while (cur->next != NULL) 10254 cur = cur->next; 10255 cur->next = rel; 10256 } 10257 10258 10259 static const xmlChar * 10260 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10261 xmlNodePtr ctxtNode) 10262 { 10263 /* 10264 * Build an absolute location URI. 10265 */ 10266 if (location != NULL) { 10267 if (ctxtNode == NULL) 10268 return(location); 10269 else { 10270 xmlChar *base, *URI; 10271 const xmlChar *ret = NULL; 10272 10273 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10274 if (base == NULL) { 10275 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10276 } else { 10277 URI = xmlBuildURI(location, base); 10278 xmlFree(base); 10279 } 10280 if (URI != NULL) { 10281 ret = xmlDictLookup(dict, URI, -1); 10282 xmlFree(URI); 10283 return(ret); 10284 } 10285 } 10286 } 10287 return(NULL); 10288 } 10289 10290 10291 10292 /** 10293 * xmlSchemaAddSchemaDoc: 10294 * @pctxt: a schema validation context 10295 * @schema: the schema being built 10296 * @node: a subtree containing XML Schema informations 10297 * 10298 * Parse an included (and to-be-redefined) XML schema document. 10299 * 10300 * Returns 0 on success, a positive error code on errors and 10301 * -1 in case of an internal or API error. 10302 */ 10303 10304 static int 10305 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10306 int type, /* import or include or redefine */ 10307 const xmlChar *schemaLocation, 10308 xmlDocPtr schemaDoc, 10309 const char *schemaBuffer, 10310 int schemaBufferLen, 10311 xmlNodePtr invokingNode, 10312 const xmlChar *sourceTargetNamespace, 10313 const xmlChar *importNamespace, 10314 xmlSchemaBucketPtr *bucket) 10315 { 10316 const xmlChar *targetNamespace = NULL; 10317 xmlSchemaSchemaRelationPtr relation = NULL; 10318 xmlDocPtr doc = NULL; 10319 int res = 0, err = 0, located = 0, preserveDoc = 0; 10320 xmlSchemaBucketPtr bkt = NULL; 10321 10322 if (bucket != NULL) 10323 *bucket = NULL; 10324 10325 switch (type) { 10326 case XML_SCHEMA_SCHEMA_IMPORT: 10327 case XML_SCHEMA_SCHEMA_MAIN: 10328 err = XML_SCHEMAP_SRC_IMPORT; 10329 break; 10330 case XML_SCHEMA_SCHEMA_INCLUDE: 10331 err = XML_SCHEMAP_SRC_INCLUDE; 10332 break; 10333 case XML_SCHEMA_SCHEMA_REDEFINE: 10334 err = XML_SCHEMAP_SRC_REDEFINE; 10335 break; 10336 } 10337 10338 10339 /* Special handling for the main schema: 10340 * skip the location and relation logic and just parse the doc. 10341 * We need just a bucket to be returned in this case. 10342 */ 10343 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10344 goto doc_load; 10345 10346 /* Note that we expect the location to be an absolute URI. */ 10347 if (schemaLocation != NULL) { 10348 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10349 if ((bkt != NULL) && 10350 (pctxt->constructor->bucket == bkt)) { 10351 /* Report self-imports/inclusions/redefinitions. */ 10352 10353 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10354 invokingNode, NULL, 10355 "The schema must not import/include/redefine itself", 10356 NULL, NULL); 10357 goto exit; 10358 } 10359 } 10360 /* 10361 * Create a relation for the graph of schemas. 10362 */ 10363 relation = xmlSchemaSchemaRelationCreate(); 10364 if (relation == NULL) 10365 return(-1); 10366 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10367 relation); 10368 relation->type = type; 10369 10370 /* 10371 * Save the namespace import information. 10372 */ 10373 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10374 relation->importNamespace = importNamespace; 10375 if (schemaLocation == NULL) { 10376 /* 10377 * No location; this is just an import of the namespace. 10378 * Note that we don't assign a bucket to the relation 10379 * in this case. 10380 */ 10381 goto exit; 10382 } 10383 targetNamespace = importNamespace; 10384 } 10385 10386 /* Did we already fetch the doc? */ 10387 if (bkt != NULL) { 10388 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10389 /* 10390 * We included/redefined and then try to import a schema, 10391 * but the new location provided for import was different. 10392 */ 10393 if (schemaLocation == NULL) 10394 schemaLocation = BAD_CAST "in_memory_buffer"; 10395 if (!xmlStrEqual(schemaLocation, 10396 bkt->schemaLocation)) { 10397 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10398 invokingNode, NULL, 10399 "The schema document '%s' cannot be imported, since " 10400 "it was already included or redefined", 10401 schemaLocation, NULL); 10402 goto exit; 10403 } 10404 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10405 /* 10406 * We imported and then try to include/redefine a schema, 10407 * but the new location provided for the include/redefine 10408 * was different. 10409 */ 10410 if (schemaLocation == NULL) 10411 schemaLocation = BAD_CAST "in_memory_buffer"; 10412 if (!xmlStrEqual(schemaLocation, 10413 bkt->schemaLocation)) { 10414 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10415 invokingNode, NULL, 10416 "The schema document '%s' cannot be included or " 10417 "redefined, since it was already imported", 10418 schemaLocation, NULL); 10419 goto exit; 10420 } 10421 } 10422 } 10423 10424 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10425 /* 10426 * Given that the schemaLocation [attribute] is only a hint, it is open 10427 * to applications to ignore all but the first <import> for a given 10428 * namespace, regardless of the `actual value` of schemaLocation, but 10429 * such a strategy risks missing useful information when new 10430 * schemaLocations are offered. 10431 * 10432 * We will use the first <import> that comes with a location. 10433 * Further <import>s *with* a location, will result in an error. 10434 * TODO: Better would be to just report a warning here, but 10435 * we'll try it this way until someone complains. 10436 * 10437 * Schema Document Location Strategy: 10438 * 3 Based on the namespace name, identify an existing schema document, 10439 * either as a resource which is an XML document or a <schema> element 10440 * information item, in some local schema repository; 10441 * 5 Attempt to resolve the namespace name to locate such a resource. 10442 * 10443 * NOTE: (3) and (5) are not supported. 10444 */ 10445 if (bkt != NULL) { 10446 relation->bucket = bkt; 10447 goto exit; 10448 } 10449 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10450 importNamespace, 1); 10451 10452 if (bkt != NULL) { 10453 relation->bucket = bkt; 10454 if (bkt->schemaLocation == NULL) { 10455 /* First given location of the schema; load the doc. */ 10456 bkt->schemaLocation = schemaLocation; 10457 } else { 10458 if (!xmlStrEqual(schemaLocation, 10459 bkt->schemaLocation)) { 10460 /* 10461 * Additional location given; just skip it. 10462 * URGENT TODO: We should report a warning here. 10463 * res = XML_SCHEMAP_SRC_IMPORT; 10464 */ 10465 if (schemaLocation == NULL) 10466 schemaLocation = BAD_CAST "in_memory_buffer"; 10467 10468 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10469 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10470 invokingNode, NULL, 10471 "Skipping import of schema located at '%s' for the " 10472 "namespace '%s', since this namespace was already " 10473 "imported with the schema located at '%s'", 10474 schemaLocation, importNamespace, bkt->schemaLocation); 10475 } 10476 goto exit; 10477 } 10478 } 10479 /* 10480 * No bucket + first location: load the doc and create a 10481 * bucket. 10482 */ 10483 } else { 10484 /* <include> and <redefine> */ 10485 if (bkt != NULL) { 10486 10487 if ((bkt->origTargetNamespace == NULL) && 10488 (bkt->targetNamespace != sourceTargetNamespace)) { 10489 xmlSchemaBucketPtr chamel; 10490 10491 /* 10492 * Chameleon include/redefine: skip loading only if it was 10493 * already build for the targetNamespace of the including 10494 * schema. 10495 */ 10496 /* 10497 * URGENT TODO: If the schema is a chameleon-include then copy 10498 * the components into the including schema and modify the 10499 * targetNamespace of those components, do nothing otherwise. 10500 * NOTE: This is currently worked-around by compiling the 10501 * chameleon for every distinct including targetNamespace; thus 10502 * not performant at the moment. 10503 * TODO: Check when the namespace in wildcards for chameleons 10504 * needs to be converted: before we built wildcard intersections 10505 * or after. 10506 * Answer: after! 10507 */ 10508 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10509 schemaLocation, sourceTargetNamespace); 10510 if (chamel != NULL) { 10511 /* A fitting chameleon was already parsed; NOP. */ 10512 relation->bucket = chamel; 10513 goto exit; 10514 } 10515 /* 10516 * We need to parse the chameleon again for a different 10517 * targetNamespace. 10518 * CHAMELEON TODO: Optimize this by only parsing the 10519 * chameleon once, and then copying the components to 10520 * the new targetNamespace. 10521 */ 10522 bkt = NULL; 10523 } else { 10524 relation->bucket = bkt; 10525 goto exit; 10526 } 10527 } 10528 } 10529 if ((bkt != NULL) && (bkt->doc != NULL)) { 10530 PERROR_INT("xmlSchemaAddSchemaDoc", 10531 "trying to load a schema doc, but a doc is already " 10532 "assigned to the schema bucket"); 10533 goto exit_failure; 10534 } 10535 10536 doc_load: 10537 /* 10538 * Load the document. 10539 */ 10540 if (schemaDoc != NULL) { 10541 doc = schemaDoc; 10542 /* Don' free this one, since it was provided by the caller. */ 10543 preserveDoc = 1; 10544 /* TODO: Does the context or the doc hold the location? */ 10545 if (schemaDoc->URL != NULL) 10546 schemaLocation = xmlDictLookup(pctxt->dict, 10547 schemaDoc->URL, -1); 10548 else 10549 schemaLocation = BAD_CAST "in_memory_buffer"; 10550 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10551 xmlParserCtxtPtr parserCtxt; 10552 10553 parserCtxt = xmlNewParserCtxt(); 10554 if (parserCtxt == NULL) { 10555 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10556 "allocating a parser context", NULL); 10557 goto exit_failure; 10558 } 10559 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10560 /* 10561 * TODO: Do we have to burden the schema parser dict with all 10562 * the content of the schema doc? 10563 */ 10564 xmlDictFree(parserCtxt->dict); 10565 parserCtxt->dict = pctxt->dict; 10566 xmlDictReference(parserCtxt->dict); 10567 } 10568 if (schemaLocation != NULL) { 10569 /* Parse from file. */ 10570 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10571 NULL, SCHEMAS_PARSE_OPTIONS); 10572 } else if (schemaBuffer != NULL) { 10573 /* Parse from memory buffer. */ 10574 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10575 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10576 schemaLocation = BAD_CAST "in_memory_buffer"; 10577 if (doc != NULL) 10578 doc->URL = xmlStrdup(schemaLocation); 10579 } 10580 /* 10581 * For <import>: 10582 * 2.1 The referent is (a fragment of) a resource which is an 10583 * XML document (see clause 1.1), which in turn corresponds to 10584 * a <schema> element information item in a well-formed information 10585 * set, which in turn corresponds to a valid schema. 10586 * TODO: (2.1) fragments of XML documents are not supported. 10587 * 10588 * 2.2 The referent is a <schema> element information item in 10589 * a well-formed information set, which in turn corresponds 10590 * to a valid schema. 10591 * TODO: (2.2) is not supported. 10592 */ 10593 if (doc == NULL) { 10594 xmlErrorPtr lerr; 10595 lerr = xmlGetLastError(); 10596 /* 10597 * Check if this a parser error, or if the document could 10598 * just not be located. 10599 * TODO: Try to find specific error codes to react only on 10600 * localisation failures. 10601 */ 10602 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10603 /* 10604 * We assume a parser error here. 10605 */ 10606 located = 1; 10607 /* TODO: Error code ?? */ 10608 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10609 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10610 invokingNode, NULL, 10611 "Failed to parse the XML resource '%s'", 10612 schemaLocation, NULL); 10613 } 10614 } 10615 xmlFreeParserCtxt(parserCtxt); 10616 if ((doc == NULL) && located) 10617 goto exit_error; 10618 } else { 10619 xmlSchemaPErr(pctxt, NULL, 10620 XML_SCHEMAP_NOTHING_TO_PARSE, 10621 "No information for parsing was provided with the " 10622 "given schema parser context.\n", 10623 NULL, NULL); 10624 goto exit_failure; 10625 } 10626 /* 10627 * Preprocess the document. 10628 */ 10629 if (doc != NULL) { 10630 xmlNodePtr docElem = NULL; 10631 10632 located = 1; 10633 docElem = xmlDocGetRootElement(doc); 10634 if (docElem == NULL) { 10635 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10636 invokingNode, NULL, 10637 "The document '%s' has no document element", 10638 schemaLocation, NULL); 10639 goto exit_error; 10640 } 10641 /* 10642 * Remove all the blank text nodes. 10643 */ 10644 xmlSchemaCleanupDoc(pctxt, docElem); 10645 /* 10646 * Check the schema's top level element. 10647 */ 10648 if (!IS_SCHEMA(docElem, "schema")) { 10649 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10650 invokingNode, NULL, 10651 "The XML document '%s' is not a schema document", 10652 schemaLocation, NULL); 10653 goto exit_error; 10654 } 10655 /* 10656 * Note that we don't apply a type check for the 10657 * targetNamespace value here. 10658 */ 10659 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10660 "targetNamespace"); 10661 } 10662 10663 /* after_doc_loading: */ 10664 if ((bkt == NULL) && located) { 10665 /* Only create a bucket if the schema was located. */ 10666 bkt = xmlSchemaBucketCreate(pctxt, type, 10667 targetNamespace); 10668 if (bkt == NULL) 10669 goto exit_failure; 10670 } 10671 if (bkt != NULL) { 10672 bkt->schemaLocation = schemaLocation; 10673 bkt->located = located; 10674 if (doc != NULL) { 10675 bkt->doc = doc; 10676 bkt->targetNamespace = targetNamespace; 10677 bkt->origTargetNamespace = targetNamespace; 10678 if (preserveDoc) 10679 bkt->preserveDoc = 1; 10680 } 10681 if (WXS_IS_BUCKET_IMPMAIN(type)) 10682 bkt->imported++; 10683 /* 10684 * Add it to the graph of schemas. 10685 */ 10686 if (relation != NULL) 10687 relation->bucket = bkt; 10688 } 10689 10690 exit: 10691 /* 10692 * Return the bucket explicitly; this is needed for the 10693 * main schema. 10694 */ 10695 if (bucket != NULL) 10696 *bucket = bkt; 10697 return (0); 10698 10699 exit_error: 10700 if ((doc != NULL) && (! preserveDoc)) { 10701 xmlFreeDoc(doc); 10702 if (bkt != NULL) 10703 bkt->doc = NULL; 10704 } 10705 return(pctxt->err); 10706 10707 exit_failure: 10708 if ((doc != NULL) && (! preserveDoc)) { 10709 xmlFreeDoc(doc); 10710 if (bkt != NULL) 10711 bkt->doc = NULL; 10712 } 10713 return (-1); 10714 } 10715 10716 /** 10717 * xmlSchemaParseImport: 10718 * @ctxt: a schema validation context 10719 * @schema: the schema being built 10720 * @node: a subtree containing XML Schema informations 10721 * 10722 * parse a XML schema Import definition 10723 * *WARNING* this interface is highly subject to change 10724 * 10725 * Returns 0 in case of success, a positive error code if 10726 * not valid and -1 in case of an internal error. 10727 */ 10728 static int 10729 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10730 xmlNodePtr node) 10731 { 10732 xmlNodePtr child; 10733 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10734 const xmlChar *thisTargetNamespace; 10735 xmlAttrPtr attr; 10736 int ret = 0; 10737 xmlSchemaBucketPtr bucket = NULL; 10738 10739 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10740 return (-1); 10741 10742 /* 10743 * Check for illegal attributes. 10744 */ 10745 attr = node->properties; 10746 while (attr != NULL) { 10747 if (attr->ns == NULL) { 10748 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10749 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10750 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10751 xmlSchemaPIllegalAttrErr(pctxt, 10752 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10753 } 10754 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10755 xmlSchemaPIllegalAttrErr(pctxt, 10756 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10757 } 10758 attr = attr->next; 10759 } 10760 /* 10761 * Extract and validate attributes. 10762 */ 10763 if (xmlSchemaPValAttr(pctxt, NULL, node, 10764 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10765 &namespaceName) != 0) { 10766 xmlSchemaPSimpleTypeErr(pctxt, 10767 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10768 NULL, node, 10769 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10770 NULL, namespaceName, NULL, NULL, NULL); 10771 return (pctxt->err); 10772 } 10773 10774 if (xmlSchemaPValAttr(pctxt, NULL, node, 10775 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10776 &schemaLocation) != 0) { 10777 xmlSchemaPSimpleTypeErr(pctxt, 10778 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10779 NULL, node, 10780 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10781 NULL, schemaLocation, NULL, NULL, NULL); 10782 return (pctxt->err); 10783 } 10784 /* 10785 * And now for the children... 10786 */ 10787 child = node->children; 10788 if (IS_SCHEMA(child, "annotation")) { 10789 /* 10790 * the annotation here is simply discarded ... 10791 * TODO: really? 10792 */ 10793 child = child->next; 10794 } 10795 if (child != NULL) { 10796 xmlSchemaPContentErr(pctxt, 10797 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10798 NULL, node, child, NULL, 10799 "(annotation?)"); 10800 } 10801 /* 10802 * Apply additional constraints. 10803 * 10804 * Note that it is important to use the original @targetNamespace 10805 * (or none at all), to rule out imports of schemas _with_ a 10806 * @targetNamespace if the importing schema is a chameleon schema 10807 * (with no @targetNamespace). 10808 */ 10809 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10810 if (namespaceName != NULL) { 10811 /* 10812 * 1.1 If the namespace [attribute] is present, then its `actual value` 10813 * must not match the `actual value` of the enclosing <schema>'s 10814 * targetNamespace [attribute]. 10815 */ 10816 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10817 xmlSchemaPCustomErr(pctxt, 10818 XML_SCHEMAP_SRC_IMPORT_1_1, 10819 NULL, node, 10820 "The value of the attribute 'namespace' must not match " 10821 "the target namespace '%s' of the importing schema", 10822 thisTargetNamespace); 10823 return (pctxt->err); 10824 } 10825 } else { 10826 /* 10827 * 1.2 If the namespace [attribute] is not present, then the enclosing 10828 * <schema> must have a targetNamespace [attribute]. 10829 */ 10830 if (thisTargetNamespace == NULL) { 10831 xmlSchemaPCustomErr(pctxt, 10832 XML_SCHEMAP_SRC_IMPORT_1_2, 10833 NULL, node, 10834 "The attribute 'namespace' must be existent if " 10835 "the importing schema has no target namespace", 10836 NULL); 10837 return (pctxt->err); 10838 } 10839 } 10840 /* 10841 * Locate and acquire the schema document. 10842 */ 10843 if (schemaLocation != NULL) 10844 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10845 schemaLocation, node); 10846 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10847 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10848 namespaceName, &bucket); 10849 10850 if (ret != 0) 10851 return(ret); 10852 10853 /* 10854 * For <import>: "It is *not* an error for the application 10855 * schema reference strategy to fail." 10856 * So just don't parse if no schema document was found. 10857 * Note that we will get no bucket if the schema could not be 10858 * located or if there was no schemaLocation. 10859 */ 10860 if ((bucket == NULL) && (schemaLocation != NULL)) { 10861 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10862 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10863 node, NULL, 10864 "Failed to locate a schema at location '%s'. " 10865 "Skipping the import", schemaLocation, NULL, NULL); 10866 } 10867 10868 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10869 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10870 } 10871 10872 return (ret); 10873 } 10874 10875 static int 10876 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10877 xmlSchemaPtr schema, 10878 xmlNodePtr node, 10879 xmlChar **schemaLocation, 10880 int type) 10881 { 10882 xmlAttrPtr attr; 10883 10884 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10885 (schemaLocation == NULL)) 10886 return (-1); 10887 10888 *schemaLocation = NULL; 10889 /* 10890 * Check for illegal attributes. 10891 * Applies for both <include> and <redefine>. 10892 */ 10893 attr = node->properties; 10894 while (attr != NULL) { 10895 if (attr->ns == NULL) { 10896 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10897 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10898 xmlSchemaPIllegalAttrErr(pctxt, 10899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10900 } 10901 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10902 xmlSchemaPIllegalAttrErr(pctxt, 10903 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10904 } 10905 attr = attr->next; 10906 } 10907 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10908 /* 10909 * Preliminary step, extract the URI-Reference and make an URI 10910 * from the base. 10911 */ 10912 /* 10913 * Attribute "schemaLocation" is mandatory. 10914 */ 10915 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10916 if (attr != NULL) { 10917 xmlChar *base = NULL; 10918 xmlChar *uri = NULL; 10919 10920 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10921 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10922 (const xmlChar **) schemaLocation) != 0) 10923 goto exit_error; 10924 base = xmlNodeGetBase(node->doc, node); 10925 if (base == NULL) { 10926 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10927 } else { 10928 uri = xmlBuildURI(*schemaLocation, base); 10929 xmlFree(base); 10930 } 10931 if (uri == NULL) { 10932 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10933 "could not build an URI from the schemaLocation") 10934 goto exit_failure; 10935 } 10936 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10937 xmlFree(uri); 10938 } else { 10939 xmlSchemaPMissingAttrErr(pctxt, 10940 XML_SCHEMAP_S4S_ATTR_MISSING, 10941 NULL, node, "schemaLocation", NULL); 10942 goto exit_error; 10943 } 10944 /* 10945 * Report self-inclusion and self-redefinition. 10946 */ 10947 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10948 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10949 xmlSchemaPCustomErr(pctxt, 10950 XML_SCHEMAP_SRC_REDEFINE, 10951 NULL, node, 10952 "The schema document '%s' cannot redefine itself.", 10953 *schemaLocation); 10954 } else { 10955 xmlSchemaPCustomErr(pctxt, 10956 XML_SCHEMAP_SRC_INCLUDE, 10957 NULL, node, 10958 "The schema document '%s' cannot include itself.", 10959 *schemaLocation); 10960 } 10961 goto exit_error; 10962 } 10963 10964 return(0); 10965 exit_error: 10966 return(pctxt->err); 10967 exit_failure: 10968 return(-1); 10969 } 10970 10971 static int 10972 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10973 xmlSchemaPtr schema, 10974 xmlNodePtr node, 10975 int type) 10976 { 10977 xmlNodePtr child = NULL; 10978 const xmlChar *schemaLocation = NULL; 10979 int res = 0; /* hasRedefinitions = 0 */ 10980 int isChameleon = 0, wasChameleon = 0; 10981 xmlSchemaBucketPtr bucket = NULL; 10982 10983 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10984 return (-1); 10985 10986 /* 10987 * Parse attributes. Note that the returned schemaLocation will 10988 * be already converted to an absolute URI. 10989 */ 10990 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10991 node, (xmlChar **) (&schemaLocation), type); 10992 if (res != 0) 10993 return(res); 10994 /* 10995 * Load and add the schema document. 10996 */ 10997 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10998 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10999 if (res != 0) 11000 return(res); 11001 /* 11002 * If we get no schema bucket back, then this means that the schema 11003 * document could not be located or was broken XML or was not 11004 * a schema document. 11005 */ 11006 if ((bucket == NULL) || (bucket->doc == NULL)) { 11007 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 11008 /* 11009 * WARNING for <include>: 11010 * We will raise an error if the schema cannot be located 11011 * for inclusions, since the that was the feedback from the 11012 * schema people. I.e. the following spec piece will *not* be 11013 * satisfied: 11014 * SPEC src-include: "It is not an error for the `actual value` of the 11015 * schemaLocation [attribute] to fail to resolve it all, in which 11016 * case no corresponding inclusion is performed. 11017 * So do we need a warning report here?" 11018 */ 11019 res = XML_SCHEMAP_SRC_INCLUDE; 11020 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11021 node, NULL, 11022 "Failed to load the document '%s' for inclusion", 11023 schemaLocation, NULL); 11024 } else { 11025 /* 11026 * NOTE: This was changed to raise an error even if no redefinitions 11027 * are specified. 11028 * 11029 * SPEC src-redefine (1) 11030 * "If there are any element information items among the [children] 11031 * other than <annotation> then the `actual value` of the 11032 * schemaLocation [attribute] must successfully resolve." 11033 * TODO: Ask the WG if a the location has always to resolve 11034 * here as well! 11035 */ 11036 res = XML_SCHEMAP_SRC_REDEFINE; 11037 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11038 node, NULL, 11039 "Failed to load the document '%s' for redefinition", 11040 schemaLocation, NULL); 11041 } 11042 } else { 11043 /* 11044 * Check targetNamespace sanity before parsing the new schema. 11045 * TODO: Note that we won't check further content if the 11046 * targetNamespace was bad. 11047 */ 11048 if (bucket->origTargetNamespace != NULL) { 11049 /* 11050 * SPEC src-include (2.1) 11051 * "SII has a targetNamespace [attribute], and its `actual 11052 * value` is identical to the `actual value` of the targetNamespace 11053 * [attribute] of SII' (which must have such an [attribute])." 11054 */ 11055 if (pctxt->targetNamespace == NULL) { 11056 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11057 XML_SCHEMAP_SRC_INCLUDE, 11058 node, NULL, 11059 "The target namespace of the included/redefined schema " 11060 "'%s' has to be absent, since the including/redefining " 11061 "schema has no target namespace", 11062 schemaLocation, NULL); 11063 goto exit_error; 11064 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11065 pctxt->targetNamespace)) { 11066 /* TODO: Change error function. */ 11067 xmlSchemaPCustomErrExt(pctxt, 11068 XML_SCHEMAP_SRC_INCLUDE, 11069 NULL, node, 11070 "The target namespace '%s' of the included/redefined " 11071 "schema '%s' differs from '%s' of the " 11072 "including/redefining schema", 11073 bucket->origTargetNamespace, schemaLocation, 11074 pctxt->targetNamespace); 11075 goto exit_error; 11076 } 11077 } else if (pctxt->targetNamespace != NULL) { 11078 /* 11079 * Chameleons: the original target namespace will 11080 * differ from the resulting namespace. 11081 */ 11082 isChameleon = 1; 11083 if (bucket->parsed && 11084 bucket->origTargetNamespace != NULL) { 11085 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11086 XML_SCHEMAP_SRC_INCLUDE, 11087 node, NULL, 11088 "The target namespace of the included/redefined schema " 11089 "'%s' has to be absent or the same as the " 11090 "including/redefining schema's target namespace", 11091 schemaLocation, NULL); 11092 goto exit_error; 11093 } 11094 bucket->targetNamespace = pctxt->targetNamespace; 11095 } 11096 } 11097 /* 11098 * Parse the schema. 11099 */ 11100 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11101 if (isChameleon) { 11102 /* TODO: Get rid of this flag on the schema itself. */ 11103 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11104 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11105 } else 11106 wasChameleon = 1; 11107 } 11108 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11109 /* Restore chameleon flag. */ 11110 if (isChameleon && (!wasChameleon)) 11111 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11112 } 11113 /* 11114 * And now for the children... 11115 */ 11116 child = node->children; 11117 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11118 /* 11119 * Parse (simpleType | complexType | group | attributeGroup))* 11120 */ 11121 pctxt->redefined = bucket; 11122 /* 11123 * How to proceed if the redefined schema was not located? 11124 */ 11125 pctxt->isRedefine = 1; 11126 while (IS_SCHEMA(child, "annotation") || 11127 IS_SCHEMA(child, "simpleType") || 11128 IS_SCHEMA(child, "complexType") || 11129 IS_SCHEMA(child, "group") || 11130 IS_SCHEMA(child, "attributeGroup")) { 11131 if (IS_SCHEMA(child, "annotation")) { 11132 /* 11133 * TODO: discard or not? 11134 */ 11135 } else if (IS_SCHEMA(child, "simpleType")) { 11136 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11137 } else if (IS_SCHEMA(child, "complexType")) { 11138 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11139 /* hasRedefinitions = 1; */ 11140 } else if (IS_SCHEMA(child, "group")) { 11141 /* hasRedefinitions = 1; */ 11142 xmlSchemaParseModelGroupDefinition(pctxt, 11143 schema, child); 11144 } else if (IS_SCHEMA(child, "attributeGroup")) { 11145 /* hasRedefinitions = 1; */ 11146 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11147 child); 11148 } 11149 child = child->next; 11150 } 11151 pctxt->redefined = NULL; 11152 pctxt->isRedefine = 0; 11153 } else { 11154 if (IS_SCHEMA(child, "annotation")) { 11155 /* 11156 * TODO: discard or not? 11157 */ 11158 child = child->next; 11159 } 11160 } 11161 if (child != NULL) { 11162 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11163 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11164 xmlSchemaPContentErr(pctxt, res, 11165 NULL, node, child, NULL, 11166 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11167 } else { 11168 xmlSchemaPContentErr(pctxt, res, 11169 NULL, node, child, NULL, 11170 "(annotation?)"); 11171 } 11172 } 11173 return(res); 11174 11175 exit_error: 11176 return(pctxt->err); 11177 } 11178 11179 static int 11180 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11181 xmlNodePtr node) 11182 { 11183 int res; 11184 #ifndef ENABLE_REDEFINE 11185 TODO 11186 return(0); 11187 #endif 11188 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11189 XML_SCHEMA_SCHEMA_REDEFINE); 11190 if (res != 0) 11191 return(res); 11192 return(0); 11193 } 11194 11195 static int 11196 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11197 xmlNodePtr node) 11198 { 11199 int res; 11200 11201 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11202 XML_SCHEMA_SCHEMA_INCLUDE); 11203 if (res != 0) 11204 return(res); 11205 return(0); 11206 } 11207 11208 /** 11209 * xmlSchemaParseModelGroup: 11210 * @ctxt: a schema validation context 11211 * @schema: the schema being built 11212 * @node: a subtree containing XML Schema informations 11213 * @type: the "compositor" type 11214 * @particleNeeded: if a a model group with a particle 11215 * 11216 * parse a XML schema Sequence definition. 11217 * Applies parts of: 11218 * Schema Representation Constraint: 11219 * Redefinition Constraints and Semantics (src-redefine) 11220 * (6.1), (6.1.1), (6.1.2) 11221 * 11222 * Schema Component Constraint: 11223 * All Group Limited (cos-all-limited) (2) 11224 * TODO: Actually this should go to component-level checks, 11225 * but is done here due to performance. Move it to an other layer 11226 * is schema construction via an API is implemented. 11227 * 11228 * *WARNING* this interface is highly subject to change 11229 * 11230 * Returns -1 in case of error, 0 if the declaration is improper and 11231 * 1 in case of success. 11232 */ 11233 static xmlSchemaTreeItemPtr 11234 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11235 xmlNodePtr node, xmlSchemaTypeType type, 11236 int withParticle) 11237 { 11238 xmlSchemaModelGroupPtr item; 11239 xmlSchemaParticlePtr particle = NULL; 11240 xmlNodePtr child = NULL; 11241 xmlAttrPtr attr; 11242 int min = 1, max = 1, isElemRef, hasRefs = 0; 11243 11244 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11245 return (NULL); 11246 /* 11247 * Create a model group with the given compositor. 11248 */ 11249 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11250 if (item == NULL) 11251 return (NULL); 11252 11253 if (withParticle) { 11254 if (type == XML_SCHEMA_TYPE_ALL) { 11255 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11256 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11257 } else { 11258 /* choice + sequence */ 11259 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11260 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11261 "(xs:nonNegativeInteger | unbounded)"); 11262 } 11263 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11264 /* 11265 * Create a particle 11266 */ 11267 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11268 if (particle == NULL) 11269 return (NULL); 11270 particle->children = (xmlSchemaTreeItemPtr) item; 11271 /* 11272 * Check for illegal attributes. 11273 */ 11274 attr = node->properties; 11275 while (attr != NULL) { 11276 if (attr->ns == NULL) { 11277 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11278 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11279 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11280 xmlSchemaPIllegalAttrErr(ctxt, 11281 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11282 } 11283 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11284 xmlSchemaPIllegalAttrErr(ctxt, 11285 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11286 } 11287 attr = attr->next; 11288 } 11289 } else { 11290 /* 11291 * Check for illegal attributes. 11292 */ 11293 attr = node->properties; 11294 while (attr != NULL) { 11295 if (attr->ns == NULL) { 11296 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11297 xmlSchemaPIllegalAttrErr(ctxt, 11298 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11299 } 11300 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11301 xmlSchemaPIllegalAttrErr(ctxt, 11302 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11303 } 11304 attr = attr->next; 11305 } 11306 } 11307 11308 /* 11309 * Extract and validate attributes. 11310 */ 11311 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11312 /* 11313 * And now for the children... 11314 */ 11315 child = node->children; 11316 if (IS_SCHEMA(child, "annotation")) { 11317 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11318 child = child->next; 11319 } 11320 if (type == XML_SCHEMA_TYPE_ALL) { 11321 xmlSchemaParticlePtr part, last = NULL; 11322 11323 while (IS_SCHEMA(child, "element")) { 11324 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11325 schema, child, &isElemRef, 0); 11326 /* 11327 * SPEC cos-all-limited (2) 11328 * "The {max occurs} of all the particles in the {particles} 11329 * of the ('all') group must be 0 or 1. 11330 */ 11331 if (part != NULL) { 11332 if (isElemRef) 11333 hasRefs++; 11334 if (part->minOccurs > 1) { 11335 xmlSchemaPCustomErr(ctxt, 11336 XML_SCHEMAP_COS_ALL_LIMITED, 11337 NULL, child, 11338 "Invalid value for minOccurs (must be 0 or 1)", 11339 NULL); 11340 /* Reset to 1. */ 11341 part->minOccurs = 1; 11342 } 11343 if (part->maxOccurs > 1) { 11344 xmlSchemaPCustomErr(ctxt, 11345 XML_SCHEMAP_COS_ALL_LIMITED, 11346 NULL, child, 11347 "Invalid value for maxOccurs (must be 0 or 1)", 11348 NULL); 11349 /* Reset to 1. */ 11350 part->maxOccurs = 1; 11351 } 11352 if (last == NULL) 11353 item->children = (xmlSchemaTreeItemPtr) part; 11354 else 11355 last->next = (xmlSchemaTreeItemPtr) part; 11356 last = part; 11357 } 11358 child = child->next; 11359 } 11360 if (child != NULL) { 11361 xmlSchemaPContentErr(ctxt, 11362 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11363 NULL, node, child, NULL, 11364 "(annotation?, (annotation?, element*)"); 11365 } 11366 } else { 11367 /* choice + sequence */ 11368 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11369 11370 while ((IS_SCHEMA(child, "element")) || 11371 (IS_SCHEMA(child, "group")) || 11372 (IS_SCHEMA(child, "any")) || 11373 (IS_SCHEMA(child, "choice")) || 11374 (IS_SCHEMA(child, "sequence"))) { 11375 11376 if (IS_SCHEMA(child, "element")) { 11377 part = (xmlSchemaTreeItemPtr) 11378 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11379 if (part && isElemRef) 11380 hasRefs++; 11381 } else if (IS_SCHEMA(child, "group")) { 11382 part = 11383 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11384 if (part != NULL) 11385 hasRefs++; 11386 /* 11387 * Handle redefinitions. 11388 */ 11389 if (ctxt->isRedefine && ctxt->redef && 11390 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11391 part && part->children) 11392 { 11393 if ((xmlSchemaGetQNameRefName(part->children) == 11394 ctxt->redef->refName) && 11395 (xmlSchemaGetQNameRefTargetNs(part->children) == 11396 ctxt->redef->refTargetNs)) 11397 { 11398 /* 11399 * SPEC src-redefine: 11400 * (6.1) "If it has a <group> among its contents at 11401 * some level the `actual value` of whose ref 11402 * [attribute] is the same as the `actual value` of 11403 * its own name attribute plus target namespace, then 11404 * all of the following must be true:" 11405 * (6.1.1) "It must have exactly one such group." 11406 */ 11407 if (ctxt->redefCounter != 0) { 11408 xmlChar *str = NULL; 11409 11410 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11411 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11412 "The redefining model group definition " 11413 "'%s' must not contain more than one " 11414 "reference to the redefined definition", 11415 xmlSchemaFormatQName(&str, 11416 ctxt->redef->refTargetNs, 11417 ctxt->redef->refName), 11418 NULL); 11419 FREE_AND_NULL(str) 11420 part = NULL; 11421 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11422 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11423 { 11424 xmlChar *str = NULL; 11425 /* 11426 * SPEC src-redefine: 11427 * (6.1.2) "The `actual value` of both that 11428 * group's minOccurs and maxOccurs [attribute] 11429 * must be 1 (or `absent`). 11430 */ 11431 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11432 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11433 "The redefining model group definition " 11434 "'%s' must not contain a reference to the " 11435 "redefined definition with a " 11436 "maxOccurs/minOccurs other than 1", 11437 xmlSchemaFormatQName(&str, 11438 ctxt->redef->refTargetNs, 11439 ctxt->redef->refName), 11440 NULL); 11441 FREE_AND_NULL(str) 11442 part = NULL; 11443 } 11444 ctxt->redef->reference = WXS_BASIC_CAST part; 11445 ctxt->redefCounter++; 11446 } 11447 } 11448 } else if (IS_SCHEMA(child, "any")) { 11449 part = (xmlSchemaTreeItemPtr) 11450 xmlSchemaParseAny(ctxt, schema, child); 11451 } else if (IS_SCHEMA(child, "choice")) { 11452 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11453 XML_SCHEMA_TYPE_CHOICE, 1); 11454 } else if (IS_SCHEMA(child, "sequence")) { 11455 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11456 XML_SCHEMA_TYPE_SEQUENCE, 1); 11457 } 11458 if (part != NULL) { 11459 if (last == NULL) 11460 item->children = part; 11461 else 11462 last->next = part; 11463 last = part; 11464 } 11465 child = child->next; 11466 } 11467 if (child != NULL) { 11468 xmlSchemaPContentErr(ctxt, 11469 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11470 NULL, node, child, NULL, 11471 "(annotation?, (element | group | choice | sequence | any)*)"); 11472 } 11473 } 11474 if ((max == 0) && (min == 0)) 11475 return (NULL); 11476 if (hasRefs) { 11477 /* 11478 * We need to resolve references. 11479 */ 11480 WXS_ADD_PENDING(ctxt, item); 11481 } 11482 if (withParticle) 11483 return ((xmlSchemaTreeItemPtr) particle); 11484 else 11485 return ((xmlSchemaTreeItemPtr) item); 11486 } 11487 11488 /** 11489 * xmlSchemaParseRestriction: 11490 * @ctxt: a schema validation context 11491 * @schema: the schema being built 11492 * @node: a subtree containing XML Schema informations 11493 * 11494 * parse a XML schema Restriction definition 11495 * *WARNING* this interface is highly subject to change 11496 * 11497 * Returns the type definition or NULL in case of error 11498 */ 11499 static xmlSchemaTypePtr 11500 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11501 xmlNodePtr node, xmlSchemaTypeType parentType) 11502 { 11503 xmlSchemaTypePtr type; 11504 xmlNodePtr child = NULL; 11505 xmlAttrPtr attr; 11506 11507 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11508 return (NULL); 11509 /* Not a component, don't create it. */ 11510 type = ctxt->ctxtType; 11511 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11512 11513 /* 11514 * Check for illegal attributes. 11515 */ 11516 attr = node->properties; 11517 while (attr != NULL) { 11518 if (attr->ns == NULL) { 11519 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11520 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11521 xmlSchemaPIllegalAttrErr(ctxt, 11522 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11523 } 11524 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11525 xmlSchemaPIllegalAttrErr(ctxt, 11526 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11527 } 11528 attr = attr->next; 11529 } 11530 /* 11531 * Extract and validate attributes. 11532 */ 11533 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11534 /* 11535 * Attribute 11536 */ 11537 /* 11538 * Extract the base type. The "base" attribute is mandatory if inside 11539 * a complex type or if redefining. 11540 * 11541 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11542 * among its [children]), the simple type definition which is 11543 * the {content type} of the type definition `resolved` to by 11544 * the `actual value` of the base [attribute]" 11545 */ 11546 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11547 &(type->baseNs), &(type->base)) == 0) 11548 { 11549 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11550 xmlSchemaPMissingAttrErr(ctxt, 11551 XML_SCHEMAP_S4S_ATTR_MISSING, 11552 NULL, node, "base", NULL); 11553 } else if ((ctxt->isRedefine) && 11554 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11555 { 11556 if (type->base == NULL) { 11557 xmlSchemaPMissingAttrErr(ctxt, 11558 XML_SCHEMAP_S4S_ATTR_MISSING, 11559 NULL, node, "base", NULL); 11560 } else if ((! xmlStrEqual(type->base, type->name)) || 11561 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11562 { 11563 xmlChar *str1 = NULL, *str2 = NULL; 11564 /* 11565 * REDEFINE: SPEC src-redefine (5) 11566 * "Within the [children], each <simpleType> must have a 11567 * <restriction> among its [children] ... the `actual value` of 11568 * whose base [attribute] must be the same as the `actual value` 11569 * of its own name attribute plus target namespace;" 11570 */ 11571 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11572 NULL, node, "This is a redefinition, but the QName " 11573 "value '%s' of the 'base' attribute does not match the " 11574 "type's designation '%s'", 11575 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11576 xmlSchemaFormatQName(&str2, type->targetNamespace, 11577 type->name), NULL); 11578 FREE_AND_NULL(str1); 11579 FREE_AND_NULL(str2); 11580 /* Avoid confusion and erase the values. */ 11581 type->base = NULL; 11582 type->baseNs = NULL; 11583 } 11584 } 11585 } 11586 /* 11587 * And now for the children... 11588 */ 11589 child = node->children; 11590 if (IS_SCHEMA(child, "annotation")) { 11591 /* 11592 * Add the annotation to the simple type ancestor. 11593 */ 11594 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11595 xmlSchemaParseAnnotation(ctxt, child, 1)); 11596 child = child->next; 11597 } 11598 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11599 /* 11600 * Corresponds to <simpleType><restriction><simpleType>. 11601 */ 11602 if (IS_SCHEMA(child, "simpleType")) { 11603 if (type->base != NULL) { 11604 /* 11605 * src-restriction-base-or-simpleType 11606 * Either the base [attribute] or the simpleType [child] of the 11607 * <restriction> element must be present, but not both. 11608 */ 11609 xmlSchemaPContentErr(ctxt, 11610 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11611 NULL, node, child, 11612 "The attribute 'base' and the <simpleType> child are " 11613 "mutually exclusive", NULL); 11614 } else { 11615 type->baseType = (xmlSchemaTypePtr) 11616 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11617 } 11618 child = child->next; 11619 } else if (type->base == NULL) { 11620 xmlSchemaPContentErr(ctxt, 11621 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11622 NULL, node, child, 11623 "Either the attribute 'base' or a <simpleType> child " 11624 "must be present", NULL); 11625 } 11626 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11627 /* 11628 * Corresponds to <complexType><complexContent><restriction>... 11629 * followed by: 11630 * 11631 * Model groups <all>, <choice> and <sequence>. 11632 */ 11633 if (IS_SCHEMA(child, "all")) { 11634 type->subtypes = (xmlSchemaTypePtr) 11635 xmlSchemaParseModelGroup(ctxt, schema, child, 11636 XML_SCHEMA_TYPE_ALL, 1); 11637 child = child->next; 11638 } else if (IS_SCHEMA(child, "choice")) { 11639 type->subtypes = (xmlSchemaTypePtr) 11640 xmlSchemaParseModelGroup(ctxt, 11641 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11642 child = child->next; 11643 } else if (IS_SCHEMA(child, "sequence")) { 11644 type->subtypes = (xmlSchemaTypePtr) 11645 xmlSchemaParseModelGroup(ctxt, schema, child, 11646 XML_SCHEMA_TYPE_SEQUENCE, 1); 11647 child = child->next; 11648 /* 11649 * Model group reference <group>. 11650 */ 11651 } else if (IS_SCHEMA(child, "group")) { 11652 type->subtypes = (xmlSchemaTypePtr) 11653 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11654 /* 11655 * Note that the reference will be resolved in 11656 * xmlSchemaResolveTypeReferences(); 11657 */ 11658 child = child->next; 11659 } 11660 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11661 /* 11662 * Corresponds to <complexType><simpleContent><restriction>... 11663 * 11664 * "1.1 the simple type definition corresponding to the <simpleType> 11665 * among the [children] of <restriction> if there is one;" 11666 */ 11667 if (IS_SCHEMA(child, "simpleType")) { 11668 /* 11669 * We will store the to-be-restricted simple type in 11670 * type->contentTypeDef *temporarily*. 11671 */ 11672 type->contentTypeDef = (xmlSchemaTypePtr) 11673 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11674 if ( type->contentTypeDef == NULL) 11675 return (NULL); 11676 child = child->next; 11677 } 11678 } 11679 11680 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11681 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11682 xmlSchemaFacetPtr facet, lastfacet = NULL; 11683 /* 11684 * Corresponds to <complexType><simpleContent><restriction>... 11685 * <simpleType><restriction>... 11686 */ 11687 11688 /* 11689 * Add the facets to the simple type ancestor. 11690 */ 11691 /* 11692 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11693 * Simple Type Definition Schema Representation Constraint: 11694 * *Single Facet Value* 11695 */ 11696 while ((IS_SCHEMA(child, "minInclusive")) || 11697 (IS_SCHEMA(child, "minExclusive")) || 11698 (IS_SCHEMA(child, "maxInclusive")) || 11699 (IS_SCHEMA(child, "maxExclusive")) || 11700 (IS_SCHEMA(child, "totalDigits")) || 11701 (IS_SCHEMA(child, "fractionDigits")) || 11702 (IS_SCHEMA(child, "pattern")) || 11703 (IS_SCHEMA(child, "enumeration")) || 11704 (IS_SCHEMA(child, "whiteSpace")) || 11705 (IS_SCHEMA(child, "length")) || 11706 (IS_SCHEMA(child, "maxLength")) || 11707 (IS_SCHEMA(child, "minLength"))) { 11708 facet = xmlSchemaParseFacet(ctxt, schema, child); 11709 if (facet != NULL) { 11710 if (lastfacet == NULL) 11711 type->facets = facet; 11712 else 11713 lastfacet->next = facet; 11714 lastfacet = facet; 11715 lastfacet->next = NULL; 11716 } 11717 child = child->next; 11718 } 11719 /* 11720 * Create links for derivation and validation. 11721 */ 11722 if (type->facets != NULL) { 11723 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11724 11725 facet = type->facets; 11726 do { 11727 facetLink = (xmlSchemaFacetLinkPtr) 11728 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11729 if (facetLink == NULL) { 11730 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11731 xmlFree(facetLink); 11732 return (NULL); 11733 } 11734 facetLink->facet = facet; 11735 facetLink->next = NULL; 11736 if (lastFacetLink == NULL) 11737 type->facetSet = facetLink; 11738 else 11739 lastFacetLink->next = facetLink; 11740 lastFacetLink = facetLink; 11741 facet = facet->next; 11742 } while (facet != NULL); 11743 } 11744 } 11745 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11746 /* 11747 * Attribute uses/declarations. 11748 */ 11749 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11750 (xmlSchemaItemListPtr *) &(type->attrUses), 11751 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11752 return(NULL); 11753 /* 11754 * Attribute wildcard. 11755 */ 11756 if (IS_SCHEMA(child, "anyAttribute")) { 11757 type->attributeWildcard = 11758 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11759 child = child->next; 11760 } 11761 } 11762 if (child != NULL) { 11763 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11764 xmlSchemaPContentErr(ctxt, 11765 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11766 NULL, node, child, NULL, 11767 "annotation?, (group | all | choice | sequence)?, " 11768 "((attribute | attributeGroup)*, anyAttribute?))"); 11769 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11770 xmlSchemaPContentErr(ctxt, 11771 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11772 NULL, node, child, NULL, 11773 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11774 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11775 "length | minLength | maxLength | enumeration | whiteSpace | " 11776 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11777 } else { 11778 /* Simple type */ 11779 xmlSchemaPContentErr(ctxt, 11780 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11781 NULL, node, child, NULL, 11782 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11783 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11784 "length | minLength | maxLength | enumeration | whiteSpace | " 11785 "pattern)*))"); 11786 } 11787 } 11788 return (NULL); 11789 } 11790 11791 /** 11792 * xmlSchemaParseExtension: 11793 * @ctxt: a schema validation context 11794 * @schema: the schema being built 11795 * @node: a subtree containing XML Schema informations 11796 * 11797 * Parses an <extension>, which is found inside a 11798 * <simpleContent> or <complexContent>. 11799 * *WARNING* this interface is highly subject to change. 11800 * 11801 * TODO: Returns the type definition or NULL in case of error 11802 */ 11803 static xmlSchemaTypePtr 11804 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11805 xmlNodePtr node, xmlSchemaTypeType parentType) 11806 { 11807 xmlSchemaTypePtr type; 11808 xmlNodePtr child = NULL; 11809 xmlAttrPtr attr; 11810 11811 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11812 return (NULL); 11813 /* Not a component, don't create it. */ 11814 type = ctxt->ctxtType; 11815 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11816 11817 /* 11818 * Check for illegal attributes. 11819 */ 11820 attr = node->properties; 11821 while (attr != NULL) { 11822 if (attr->ns == NULL) { 11823 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11824 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11825 xmlSchemaPIllegalAttrErr(ctxt, 11826 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11827 } 11828 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11829 xmlSchemaPIllegalAttrErr(ctxt, 11830 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11831 } 11832 attr = attr->next; 11833 } 11834 11835 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11836 11837 /* 11838 * Attribute "base" - mandatory. 11839 */ 11840 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11841 "base", &(type->baseNs), &(type->base)) == 0) && 11842 (type->base == NULL)) { 11843 xmlSchemaPMissingAttrErr(ctxt, 11844 XML_SCHEMAP_S4S_ATTR_MISSING, 11845 NULL, node, "base", NULL); 11846 } 11847 /* 11848 * And now for the children... 11849 */ 11850 child = node->children; 11851 if (IS_SCHEMA(child, "annotation")) { 11852 /* 11853 * Add the annotation to the type ancestor. 11854 */ 11855 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11856 xmlSchemaParseAnnotation(ctxt, child, 1)); 11857 child = child->next; 11858 } 11859 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11860 /* 11861 * Corresponds to <complexType><complexContent><extension>... and: 11862 * 11863 * Model groups <all>, <choice>, <sequence> and <group>. 11864 */ 11865 if (IS_SCHEMA(child, "all")) { 11866 type->subtypes = (xmlSchemaTypePtr) 11867 xmlSchemaParseModelGroup(ctxt, schema, 11868 child, XML_SCHEMA_TYPE_ALL, 1); 11869 child = child->next; 11870 } else if (IS_SCHEMA(child, "choice")) { 11871 type->subtypes = (xmlSchemaTypePtr) 11872 xmlSchemaParseModelGroup(ctxt, schema, 11873 child, XML_SCHEMA_TYPE_CHOICE, 1); 11874 child = child->next; 11875 } else if (IS_SCHEMA(child, "sequence")) { 11876 type->subtypes = (xmlSchemaTypePtr) 11877 xmlSchemaParseModelGroup(ctxt, schema, 11878 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11879 child = child->next; 11880 } else if (IS_SCHEMA(child, "group")) { 11881 type->subtypes = (xmlSchemaTypePtr) 11882 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11883 /* 11884 * Note that the reference will be resolved in 11885 * xmlSchemaResolveTypeReferences(); 11886 */ 11887 child = child->next; 11888 } 11889 } 11890 if (child != NULL) { 11891 /* 11892 * Attribute uses/declarations. 11893 */ 11894 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11895 (xmlSchemaItemListPtr *) &(type->attrUses), 11896 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11897 return(NULL); 11898 /* 11899 * Attribute wildcard. 11900 */ 11901 if (IS_SCHEMA(child, "anyAttribute")) { 11902 ctxt->ctxtType->attributeWildcard = 11903 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11904 child = child->next; 11905 } 11906 } 11907 if (child != NULL) { 11908 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11909 /* Complex content extension. */ 11910 xmlSchemaPContentErr(ctxt, 11911 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11912 NULL, node, child, NULL, 11913 "(annotation?, ((group | all | choice | sequence)?, " 11914 "((attribute | attributeGroup)*, anyAttribute?)))"); 11915 } else { 11916 /* Simple content extension. */ 11917 xmlSchemaPContentErr(ctxt, 11918 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11919 NULL, node, child, NULL, 11920 "(annotation?, ((attribute | attributeGroup)*, " 11921 "anyAttribute?))"); 11922 } 11923 } 11924 return (NULL); 11925 } 11926 11927 /** 11928 * xmlSchemaParseSimpleContent: 11929 * @ctxt: a schema validation context 11930 * @schema: the schema being built 11931 * @node: a subtree containing XML Schema informations 11932 * 11933 * parse a XML schema SimpleContent definition 11934 * *WARNING* this interface is highly subject to change 11935 * 11936 * Returns the type definition or NULL in case of error 11937 */ 11938 static int 11939 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11940 xmlSchemaPtr schema, xmlNodePtr node, 11941 int *hasRestrictionOrExtension) 11942 { 11943 xmlSchemaTypePtr type; 11944 xmlNodePtr child = NULL; 11945 xmlAttrPtr attr; 11946 11947 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11948 (hasRestrictionOrExtension == NULL)) 11949 return (-1); 11950 *hasRestrictionOrExtension = 0; 11951 /* Not a component, don't create it. */ 11952 type = ctxt->ctxtType; 11953 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11954 /* 11955 * Check for illegal attributes. 11956 */ 11957 attr = node->properties; 11958 while (attr != NULL) { 11959 if (attr->ns == NULL) { 11960 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11961 xmlSchemaPIllegalAttrErr(ctxt, 11962 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11963 } 11964 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11965 xmlSchemaPIllegalAttrErr(ctxt, 11966 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11967 } 11968 attr = attr->next; 11969 } 11970 11971 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11972 11973 /* 11974 * And now for the children... 11975 */ 11976 child = node->children; 11977 if (IS_SCHEMA(child, "annotation")) { 11978 /* 11979 * Add the annotation to the complex type ancestor. 11980 */ 11981 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11982 xmlSchemaParseAnnotation(ctxt, child, 1)); 11983 child = child->next; 11984 } 11985 if (child == NULL) { 11986 xmlSchemaPContentErr(ctxt, 11987 XML_SCHEMAP_S4S_ELEM_MISSING, 11988 NULL, node, NULL, NULL, 11989 "(annotation?, (restriction | extension))"); 11990 } 11991 if (child == NULL) { 11992 xmlSchemaPContentErr(ctxt, 11993 XML_SCHEMAP_S4S_ELEM_MISSING, 11994 NULL, node, NULL, NULL, 11995 "(annotation?, (restriction | extension))"); 11996 } 11997 if (IS_SCHEMA(child, "restriction")) { 11998 xmlSchemaParseRestriction(ctxt, schema, child, 11999 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12000 (*hasRestrictionOrExtension) = 1; 12001 child = child->next; 12002 } else if (IS_SCHEMA(child, "extension")) { 12003 xmlSchemaParseExtension(ctxt, schema, child, 12004 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12005 (*hasRestrictionOrExtension) = 1; 12006 child = child->next; 12007 } 12008 if (child != NULL) { 12009 xmlSchemaPContentErr(ctxt, 12010 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12011 NULL, node, child, NULL, 12012 "(annotation?, (restriction | extension))"); 12013 } 12014 return (0); 12015 } 12016 12017 /** 12018 * xmlSchemaParseComplexContent: 12019 * @ctxt: a schema validation context 12020 * @schema: the schema being built 12021 * @node: a subtree containing XML Schema informations 12022 * 12023 * parse a XML schema ComplexContent definition 12024 * *WARNING* this interface is highly subject to change 12025 * 12026 * Returns the type definition or NULL in case of error 12027 */ 12028 static int 12029 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12030 xmlSchemaPtr schema, xmlNodePtr node, 12031 int *hasRestrictionOrExtension) 12032 { 12033 xmlSchemaTypePtr type; 12034 xmlNodePtr child = NULL; 12035 xmlAttrPtr attr; 12036 12037 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12038 (hasRestrictionOrExtension == NULL)) 12039 return (-1); 12040 *hasRestrictionOrExtension = 0; 12041 /* Not a component, don't create it. */ 12042 type = ctxt->ctxtType; 12043 /* 12044 * Check for illegal attributes. 12045 */ 12046 attr = node->properties; 12047 while (attr != NULL) { 12048 if (attr->ns == NULL) { 12049 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12050 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12051 { 12052 xmlSchemaPIllegalAttrErr(ctxt, 12053 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12054 } 12055 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12056 xmlSchemaPIllegalAttrErr(ctxt, 12057 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12058 } 12059 attr = attr->next; 12060 } 12061 12062 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12063 12064 /* 12065 * Set the 'mixed' on the complex type ancestor. 12066 */ 12067 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12068 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12069 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12070 } 12071 child = node->children; 12072 if (IS_SCHEMA(child, "annotation")) { 12073 /* 12074 * Add the annotation to the complex type ancestor. 12075 */ 12076 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12077 xmlSchemaParseAnnotation(ctxt, child, 1)); 12078 child = child->next; 12079 } 12080 if (child == NULL) { 12081 xmlSchemaPContentErr(ctxt, 12082 XML_SCHEMAP_S4S_ELEM_MISSING, 12083 NULL, node, NULL, 12084 NULL, "(annotation?, (restriction | extension))"); 12085 } 12086 if (child == NULL) { 12087 xmlSchemaPContentErr(ctxt, 12088 XML_SCHEMAP_S4S_ELEM_MISSING, 12089 NULL, node, NULL, 12090 NULL, "(annotation?, (restriction | extension))"); 12091 } 12092 if (IS_SCHEMA(child, "restriction")) { 12093 xmlSchemaParseRestriction(ctxt, schema, child, 12094 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12095 (*hasRestrictionOrExtension) = 1; 12096 child = child->next; 12097 } else if (IS_SCHEMA(child, "extension")) { 12098 xmlSchemaParseExtension(ctxt, schema, child, 12099 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12100 (*hasRestrictionOrExtension) = 1; 12101 child = child->next; 12102 } 12103 if (child != NULL) { 12104 xmlSchemaPContentErr(ctxt, 12105 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12106 NULL, node, child, 12107 NULL, "(annotation?, (restriction | extension))"); 12108 } 12109 return (0); 12110 } 12111 12112 /** 12113 * xmlSchemaParseComplexType: 12114 * @ctxt: a schema validation context 12115 * @schema: the schema being built 12116 * @node: a subtree containing XML Schema informations 12117 * 12118 * parse a XML schema Complex Type definition 12119 * *WARNING* this interface is highly subject to change 12120 * 12121 * Returns the type definition or NULL in case of error 12122 */ 12123 static xmlSchemaTypePtr 12124 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12125 xmlNodePtr node, int topLevel) 12126 { 12127 xmlSchemaTypePtr type, ctxtType; 12128 xmlNodePtr child = NULL; 12129 const xmlChar *name = NULL; 12130 xmlAttrPtr attr; 12131 const xmlChar *attrValue; 12132 #ifdef ENABLE_NAMED_LOCALS 12133 char buf[40]; 12134 #endif 12135 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12136 12137 12138 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12139 return (NULL); 12140 12141 ctxtType = ctxt->ctxtType; 12142 12143 if (topLevel) { 12144 attr = xmlSchemaGetPropNode(node, "name"); 12145 if (attr == NULL) { 12146 xmlSchemaPMissingAttrErr(ctxt, 12147 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12148 return (NULL); 12149 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12150 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12151 return (NULL); 12152 } 12153 } 12154 12155 if (topLevel == 0) { 12156 /* 12157 * Parse as local complex type definition. 12158 */ 12159 #ifdef ENABLE_NAMED_LOCALS 12160 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12161 type = xmlSchemaAddType(ctxt, schema, 12162 XML_SCHEMA_TYPE_COMPLEX, 12163 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12164 ctxt->targetNamespace, node, 0); 12165 #else 12166 type = xmlSchemaAddType(ctxt, schema, 12167 XML_SCHEMA_TYPE_COMPLEX, 12168 NULL, ctxt->targetNamespace, node, 0); 12169 #endif 12170 if (type == NULL) 12171 return (NULL); 12172 name = type->name; 12173 type->node = node; 12174 type->type = XML_SCHEMA_TYPE_COMPLEX; 12175 /* 12176 * TODO: We need the target namespace. 12177 */ 12178 } else { 12179 /* 12180 * Parse as global complex type definition. 12181 */ 12182 type = xmlSchemaAddType(ctxt, schema, 12183 XML_SCHEMA_TYPE_COMPLEX, 12184 name, ctxt->targetNamespace, node, 1); 12185 if (type == NULL) 12186 return (NULL); 12187 type->node = node; 12188 type->type = XML_SCHEMA_TYPE_COMPLEX; 12189 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12190 } 12191 type->targetNamespace = ctxt->targetNamespace; 12192 /* 12193 * Handle attributes. 12194 */ 12195 attr = node->properties; 12196 while (attr != NULL) { 12197 if (attr->ns == NULL) { 12198 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12199 /* 12200 * Attribute "id". 12201 */ 12202 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12203 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12204 /* 12205 * Attribute "mixed". 12206 */ 12207 if (xmlSchemaPGetBoolNodeValue(ctxt, 12208 NULL, (xmlNodePtr) attr)) 12209 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12210 } else if (topLevel) { 12211 /* 12212 * Attributes of global complex type definitions. 12213 */ 12214 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12215 /* Pass. */ 12216 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12217 /* 12218 * Attribute "abstract". 12219 */ 12220 if (xmlSchemaPGetBoolNodeValue(ctxt, 12221 NULL, (xmlNodePtr) attr)) 12222 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12223 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12224 /* 12225 * Attribute "final". 12226 */ 12227 attrValue = xmlSchemaGetNodeContent(ctxt, 12228 (xmlNodePtr) attr); 12229 if (xmlSchemaPValAttrBlockFinal(attrValue, 12230 &(type->flags), 12231 -1, 12232 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12233 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12234 -1, -1, -1) != 0) 12235 { 12236 xmlSchemaPSimpleTypeErr(ctxt, 12237 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12238 NULL, (xmlNodePtr) attr, NULL, 12239 "(#all | List of (extension | restriction))", 12240 attrValue, NULL, NULL, NULL); 12241 } else 12242 final = 1; 12243 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12244 /* 12245 * Attribute "block". 12246 */ 12247 attrValue = xmlSchemaGetNodeContent(ctxt, 12248 (xmlNodePtr) attr); 12249 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12250 -1, 12251 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12252 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12253 -1, -1, -1) != 0) { 12254 xmlSchemaPSimpleTypeErr(ctxt, 12255 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12256 NULL, (xmlNodePtr) attr, NULL, 12257 "(#all | List of (extension | restriction)) ", 12258 attrValue, NULL, NULL, NULL); 12259 } else 12260 block = 1; 12261 } else { 12262 xmlSchemaPIllegalAttrErr(ctxt, 12263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12264 } 12265 } else { 12266 xmlSchemaPIllegalAttrErr(ctxt, 12267 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12268 } 12269 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12270 xmlSchemaPIllegalAttrErr(ctxt, 12271 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12272 } 12273 attr = attr->next; 12274 } 12275 if (! block) { 12276 /* 12277 * Apply default "block" values. 12278 */ 12279 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12280 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12281 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12282 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12283 } 12284 if (! final) { 12285 /* 12286 * Apply default "block" values. 12287 */ 12288 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12289 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12290 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12291 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12292 } 12293 /* 12294 * And now for the children... 12295 */ 12296 child = node->children; 12297 if (IS_SCHEMA(child, "annotation")) { 12298 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12299 child = child->next; 12300 } 12301 ctxt->ctxtType = type; 12302 if (IS_SCHEMA(child, "simpleContent")) { 12303 /* 12304 * <complexType><simpleContent>... 12305 * 3.4.3 : 2.2 12306 * Specifying mixed='true' when the <simpleContent> 12307 * alternative is chosen has no effect 12308 */ 12309 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12310 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12311 xmlSchemaParseSimpleContent(ctxt, schema, child, 12312 &hasRestrictionOrExtension); 12313 child = child->next; 12314 } else if (IS_SCHEMA(child, "complexContent")) { 12315 /* 12316 * <complexType><complexContent>... 12317 */ 12318 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12319 xmlSchemaParseComplexContent(ctxt, schema, child, 12320 &hasRestrictionOrExtension); 12321 child = child->next; 12322 } else { 12323 /* 12324 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12325 * 12326 * SPEC 12327 * "...the third alternative (neither <simpleContent> nor 12328 * <complexContent>) is chosen. This case is understood as shorthand 12329 * for complex content restricting the `ur-type definition`, and the 12330 * details of the mappings should be modified as necessary. 12331 */ 12332 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12333 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12334 /* 12335 * Parse model groups. 12336 */ 12337 if (IS_SCHEMA(child, "all")) { 12338 type->subtypes = (xmlSchemaTypePtr) 12339 xmlSchemaParseModelGroup(ctxt, schema, child, 12340 XML_SCHEMA_TYPE_ALL, 1); 12341 child = child->next; 12342 } else if (IS_SCHEMA(child, "choice")) { 12343 type->subtypes = (xmlSchemaTypePtr) 12344 xmlSchemaParseModelGroup(ctxt, schema, child, 12345 XML_SCHEMA_TYPE_CHOICE, 1); 12346 child = child->next; 12347 } else if (IS_SCHEMA(child, "sequence")) { 12348 type->subtypes = (xmlSchemaTypePtr) 12349 xmlSchemaParseModelGroup(ctxt, schema, child, 12350 XML_SCHEMA_TYPE_SEQUENCE, 1); 12351 child = child->next; 12352 } else if (IS_SCHEMA(child, "group")) { 12353 type->subtypes = (xmlSchemaTypePtr) 12354 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12355 /* 12356 * Note that the reference will be resolved in 12357 * xmlSchemaResolveTypeReferences(); 12358 */ 12359 child = child->next; 12360 } 12361 /* 12362 * Parse attribute decls/refs. 12363 */ 12364 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12365 (xmlSchemaItemListPtr *) &(type->attrUses), 12366 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12367 return(NULL); 12368 /* 12369 * Parse attribute wildcard. 12370 */ 12371 if (IS_SCHEMA(child, "anyAttribute")) { 12372 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12373 child = child->next; 12374 } 12375 } 12376 if (child != NULL) { 12377 xmlSchemaPContentErr(ctxt, 12378 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12379 NULL, node, child, 12380 NULL, "(annotation?, (simpleContent | complexContent | " 12381 "((group | all | choice | sequence)?, ((attribute | " 12382 "attributeGroup)*, anyAttribute?))))"); 12383 } 12384 /* 12385 * REDEFINE: SPEC src-redefine (5) 12386 */ 12387 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12388 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12389 NULL, node, "This is a redefinition, thus the " 12390 "<complexType> must have a <restriction> or <extension> " 12391 "grand-child", NULL); 12392 } 12393 ctxt->ctxtType = ctxtType; 12394 return (type); 12395 } 12396 12397 /************************************************************************ 12398 * * 12399 * Validating using Schemas * 12400 * * 12401 ************************************************************************/ 12402 12403 /************************************************************************ 12404 * * 12405 * Reading/Writing Schemas * 12406 * * 12407 ************************************************************************/ 12408 12409 #if 0 /* Will be enabled if it is clear what options are needed. */ 12410 /** 12411 * xmlSchemaParserCtxtSetOptions: 12412 * @ctxt: a schema parser context 12413 * @options: a combination of xmlSchemaParserOption 12414 * 12415 * Sets the options to be used during the parse. 12416 * 12417 * Returns 0 in case of success, -1 in case of an 12418 * API error. 12419 */ 12420 static int 12421 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12422 int options) 12423 12424 { 12425 int i; 12426 12427 if (ctxt == NULL) 12428 return (-1); 12429 /* 12430 * WARNING: Change the start value if adding to the 12431 * xmlSchemaParseOption. 12432 */ 12433 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12434 if (options & 1<<i) { 12435 return (-1); 12436 } 12437 } 12438 ctxt->options = options; 12439 return (0); 12440 } 12441 12442 /** 12443 * xmlSchemaValidCtxtGetOptions: 12444 * @ctxt: a schema parser context 12445 * 12446 * Returns the option combination of the parser context. 12447 */ 12448 static int 12449 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12450 12451 { 12452 if (ctxt == NULL) 12453 return (-1); 12454 else 12455 return (ctxt->options); 12456 } 12457 #endif 12458 12459 /** 12460 * xmlSchemaNewParserCtxt: 12461 * @URL: the location of the schema 12462 * 12463 * Create an XML Schemas parse context for that file/resource expected 12464 * to contain an XML Schemas file. 12465 * 12466 * Returns the parser context or NULL in case of error 12467 */ 12468 xmlSchemaParserCtxtPtr 12469 xmlSchemaNewParserCtxt(const char *URL) 12470 { 12471 xmlSchemaParserCtxtPtr ret; 12472 12473 if (URL == NULL) 12474 return (NULL); 12475 12476 ret = xmlSchemaParserCtxtCreate(); 12477 if (ret == NULL) 12478 return(NULL); 12479 ret->dict = xmlDictCreate(); 12480 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12481 return (ret); 12482 } 12483 12484 /** 12485 * xmlSchemaNewMemParserCtxt: 12486 * @buffer: a pointer to a char array containing the schemas 12487 * @size: the size of the array 12488 * 12489 * Create an XML Schemas parse context for that memory buffer expected 12490 * to contain an XML Schemas file. 12491 * 12492 * Returns the parser context or NULL in case of error 12493 */ 12494 xmlSchemaParserCtxtPtr 12495 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12496 { 12497 xmlSchemaParserCtxtPtr ret; 12498 12499 if ((buffer == NULL) || (size <= 0)) 12500 return (NULL); 12501 ret = xmlSchemaParserCtxtCreate(); 12502 if (ret == NULL) 12503 return(NULL); 12504 ret->buffer = buffer; 12505 ret->size = size; 12506 ret->dict = xmlDictCreate(); 12507 return (ret); 12508 } 12509 12510 /** 12511 * xmlSchemaNewDocParserCtxt: 12512 * @doc: a preparsed document tree 12513 * 12514 * Create an XML Schemas parse context for that document. 12515 * NB. The document may be modified during the parsing process. 12516 * 12517 * Returns the parser context or NULL in case of error 12518 */ 12519 xmlSchemaParserCtxtPtr 12520 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12521 { 12522 xmlSchemaParserCtxtPtr ret; 12523 12524 if (doc == NULL) 12525 return (NULL); 12526 ret = xmlSchemaParserCtxtCreate(); 12527 if (ret == NULL) 12528 return(NULL); 12529 ret->doc = doc; 12530 ret->dict = xmlDictCreate(); 12531 /* The application has responsibility for the document */ 12532 ret->preserve = 1; 12533 12534 return (ret); 12535 } 12536 12537 /** 12538 * xmlSchemaFreeParserCtxt: 12539 * @ctxt: the schema parser context 12540 * 12541 * Free the resources associated to the schema parser context 12542 */ 12543 void 12544 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12545 { 12546 if (ctxt == NULL) 12547 return; 12548 if (ctxt->doc != NULL && !ctxt->preserve) 12549 xmlFreeDoc(ctxt->doc); 12550 if (ctxt->vctxt != NULL) { 12551 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12552 } 12553 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12554 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12555 ctxt->constructor = NULL; 12556 ctxt->ownsConstructor = 0; 12557 } 12558 if (ctxt->attrProhibs != NULL) 12559 xmlSchemaItemListFree(ctxt->attrProhibs); 12560 xmlDictFree(ctxt->dict); 12561 xmlFree(ctxt); 12562 } 12563 12564 /************************************************************************ 12565 * * 12566 * Building the content models * 12567 * * 12568 ************************************************************************/ 12569 12570 /** 12571 * xmlSchemaBuildContentModelForSubstGroup: 12572 * 12573 * Returns 1 if nillable, 0 otherwise 12574 */ 12575 static int 12576 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12577 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12578 { 12579 xmlAutomataStatePtr start, tmp; 12580 xmlSchemaElementPtr elemDecl, member; 12581 xmlSchemaSubstGroupPtr substGroup; 12582 int i; 12583 int ret = 0; 12584 12585 elemDecl = (xmlSchemaElementPtr) particle->children; 12586 /* 12587 * Wrap the substitution group with a CHOICE. 12588 */ 12589 start = pctxt->state; 12590 if (end == NULL) 12591 end = xmlAutomataNewState(pctxt->am); 12592 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12593 if (substGroup == NULL) { 12594 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12595 XML_SCHEMAP_INTERNAL, 12596 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12597 "declaration is marked having a subst. group but none " 12598 "available.\n", elemDecl->name, NULL); 12599 return(0); 12600 } 12601 if (counter >= 0) { 12602 /* 12603 * NOTE that we put the declaration in, even if it's abstract. 12604 * However, an error will be raised during *validation* if an element 12605 * information item shall be validated against an abstract element 12606 * declaration. 12607 */ 12608 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12609 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12610 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12611 /* 12612 * Add subst. group members. 12613 */ 12614 for (i = 0; i < substGroup->members->nbItems; i++) { 12615 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12616 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12617 member->name, member->targetNamespace, member); 12618 } 12619 } else if (particle->maxOccurs == 1) { 12620 /* 12621 * NOTE that we put the declaration in, even if it's abstract, 12622 */ 12623 xmlAutomataNewEpsilon(pctxt->am, 12624 xmlAutomataNewTransition2(pctxt->am, 12625 start, NULL, 12626 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12627 /* 12628 * Add subst. group members. 12629 */ 12630 for (i = 0; i < substGroup->members->nbItems; i++) { 12631 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12632 /* 12633 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12634 * was incorrectly used instead of xmlAutomataNewTransition2() 12635 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12636 * section in xmlSchemaBuildAContentModel() ). 12637 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12638 * intended for the above "counter" section originally. I.e., 12639 * check xs:all with subst-groups. 12640 * 12641 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12642 * member->name, member->targetNamespace, 12643 * 1, 1, member); 12644 */ 12645 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12646 member->name, member->targetNamespace, member); 12647 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12648 } 12649 } else { 12650 xmlAutomataStatePtr hop; 12651 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12652 UNBOUNDED : particle->maxOccurs - 1; 12653 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12654 12655 counter = 12656 xmlAutomataNewCounter(pctxt->am, minOccurs, 12657 maxOccurs); 12658 hop = xmlAutomataNewState(pctxt->am); 12659 12660 xmlAutomataNewEpsilon(pctxt->am, 12661 xmlAutomataNewTransition2(pctxt->am, 12662 start, NULL, 12663 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12664 hop); 12665 /* 12666 * Add subst. group members. 12667 */ 12668 for (i = 0; i < substGroup->members->nbItems; i++) { 12669 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12670 xmlAutomataNewEpsilon(pctxt->am, 12671 xmlAutomataNewTransition2(pctxt->am, 12672 start, NULL, 12673 member->name, member->targetNamespace, member), 12674 hop); 12675 } 12676 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12677 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12678 } 12679 if (particle->minOccurs == 0) { 12680 xmlAutomataNewEpsilon(pctxt->am, start, end); 12681 ret = 1; 12682 } 12683 pctxt->state = end; 12684 return(ret); 12685 } 12686 12687 /** 12688 * xmlSchemaBuildContentModelForElement: 12689 * 12690 * Returns 1 if nillable, 0 otherwise 12691 */ 12692 static int 12693 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12694 xmlSchemaParticlePtr particle) 12695 { 12696 int ret = 0; 12697 12698 if (((xmlSchemaElementPtr) particle->children)->flags & 12699 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12700 /* 12701 * Substitution groups. 12702 */ 12703 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12704 } else { 12705 xmlSchemaElementPtr elemDecl; 12706 xmlAutomataStatePtr start; 12707 12708 elemDecl = (xmlSchemaElementPtr) particle->children; 12709 12710 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12711 return(0); 12712 if (particle->maxOccurs == 1) { 12713 start = ctxt->state; 12714 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12715 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12716 } else if ((particle->maxOccurs >= UNBOUNDED) && 12717 (particle->minOccurs < 2)) { 12718 /* Special case. */ 12719 start = ctxt->state; 12720 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12721 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12722 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12723 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12724 } else { 12725 int counter; 12726 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12727 UNBOUNDED : particle->maxOccurs - 1; 12728 int minOccurs = particle->minOccurs < 1 ? 12729 0 : particle->minOccurs - 1; 12730 12731 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12732 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12733 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12734 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12735 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12736 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12737 NULL, counter); 12738 } 12739 if (particle->minOccurs == 0) { 12740 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12741 ret = 1; 12742 } 12743 } 12744 return(ret); 12745 } 12746 12747 /** 12748 * xmlSchemaBuildAContentModel: 12749 * @ctxt: the schema parser context 12750 * @particle: the particle component 12751 * @name: the complex type's name whose content is being built 12752 * 12753 * Create the automaton for the {content type} of a complex type. 12754 * 12755 * Returns 1 if the content is nillable, 0 otherwise 12756 */ 12757 static int 12758 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12759 xmlSchemaParticlePtr particle) 12760 { 12761 int ret = 0, tmp2; 12762 12763 if (particle == NULL) { 12764 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12765 return(1); 12766 } 12767 if (particle->children == NULL) { 12768 /* 12769 * Just return in this case. A missing "term" of the particle 12770 * might arise due to an invalid "term" component. 12771 */ 12772 return(1); 12773 } 12774 12775 switch (particle->children->type) { 12776 case XML_SCHEMA_TYPE_ANY: { 12777 xmlAutomataStatePtr start, end; 12778 xmlSchemaWildcardPtr wild; 12779 xmlSchemaWildcardNsPtr ns; 12780 12781 wild = (xmlSchemaWildcardPtr) particle->children; 12782 12783 start = pctxt->state; 12784 end = xmlAutomataNewState(pctxt->am); 12785 12786 if (particle->maxOccurs == 1) { 12787 if (wild->any == 1) { 12788 /* 12789 * We need to add both transitions: 12790 * 12791 * 1. the {"*", "*"} for elements in a namespace. 12792 */ 12793 pctxt->state = 12794 xmlAutomataNewTransition2(pctxt->am, 12795 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12796 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12797 /* 12798 * 2. the {"*"} for elements in no namespace. 12799 */ 12800 pctxt->state = 12801 xmlAutomataNewTransition2(pctxt->am, 12802 start, NULL, BAD_CAST "*", NULL, wild); 12803 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12804 12805 } else if (wild->nsSet != NULL) { 12806 ns = wild->nsSet; 12807 do { 12808 pctxt->state = start; 12809 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12810 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12811 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12812 ns = ns->next; 12813 } while (ns != NULL); 12814 12815 } else if (wild->negNsSet != NULL) { 12816 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12817 start, end, BAD_CAST "*", wild->negNsSet->value, 12818 wild); 12819 } 12820 } else { 12821 int counter; 12822 xmlAutomataStatePtr hop; 12823 int maxOccurs = 12824 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12825 particle->maxOccurs - 1; 12826 int minOccurs = 12827 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12828 12829 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12830 hop = xmlAutomataNewState(pctxt->am); 12831 if (wild->any == 1) { 12832 pctxt->state = 12833 xmlAutomataNewTransition2(pctxt->am, 12834 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12835 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12836 pctxt->state = 12837 xmlAutomataNewTransition2(pctxt->am, 12838 start, NULL, BAD_CAST "*", NULL, wild); 12839 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12840 } else if (wild->nsSet != NULL) { 12841 ns = wild->nsSet; 12842 do { 12843 pctxt->state = 12844 xmlAutomataNewTransition2(pctxt->am, 12845 start, NULL, BAD_CAST "*", ns->value, wild); 12846 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12847 ns = ns->next; 12848 } while (ns != NULL); 12849 12850 } else if (wild->negNsSet != NULL) { 12851 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12852 start, hop, BAD_CAST "*", wild->negNsSet->value, 12853 wild); 12854 } 12855 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12856 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12857 } 12858 if (particle->minOccurs == 0) { 12859 xmlAutomataNewEpsilon(pctxt->am, start, end); 12860 ret = 1; 12861 } 12862 pctxt->state = end; 12863 break; 12864 } 12865 case XML_SCHEMA_TYPE_ELEMENT: 12866 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12867 break; 12868 case XML_SCHEMA_TYPE_SEQUENCE:{ 12869 xmlSchemaTreeItemPtr sub; 12870 12871 ret = 1; 12872 /* 12873 * If max and min occurrences are default (1) then 12874 * simply iterate over the particles of the <sequence>. 12875 */ 12876 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12877 sub = particle->children->children; 12878 12879 while (sub != NULL) { 12880 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12881 (xmlSchemaParticlePtr) sub); 12882 if (tmp2 != 1) ret = 0; 12883 sub = sub->next; 12884 } 12885 } else { 12886 xmlAutomataStatePtr oldstate = pctxt->state; 12887 12888 if (particle->maxOccurs >= UNBOUNDED) { 12889 if (particle->minOccurs > 1) { 12890 xmlAutomataStatePtr tmp; 12891 int counter; 12892 12893 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12894 oldstate, NULL); 12895 oldstate = pctxt->state; 12896 12897 counter = xmlAutomataNewCounter(pctxt->am, 12898 particle->minOccurs - 1, UNBOUNDED); 12899 12900 sub = particle->children->children; 12901 while (sub != NULL) { 12902 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12903 (xmlSchemaParticlePtr) sub); 12904 if (tmp2 != 1) ret = 0; 12905 sub = sub->next; 12906 } 12907 tmp = pctxt->state; 12908 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12909 oldstate, counter); 12910 pctxt->state = 12911 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12912 NULL, counter); 12913 if (ret == 1) 12914 xmlAutomataNewEpsilon(pctxt->am, 12915 oldstate, pctxt->state); 12916 12917 } else { 12918 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12919 oldstate, NULL); 12920 oldstate = pctxt->state; 12921 12922 sub = particle->children->children; 12923 while (sub != NULL) { 12924 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12925 (xmlSchemaParticlePtr) sub); 12926 if (tmp2 != 1) ret = 0; 12927 sub = sub->next; 12928 } 12929 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12930 oldstate); 12931 /* 12932 * epsilon needed to block previous trans from 12933 * being allowed to enter back from another 12934 * construct 12935 */ 12936 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12937 pctxt->state, NULL); 12938 if (particle->minOccurs == 0) { 12939 xmlAutomataNewEpsilon(pctxt->am, 12940 oldstate, pctxt->state); 12941 ret = 1; 12942 } 12943 } 12944 } else if ((particle->maxOccurs > 1) 12945 || (particle->minOccurs > 1)) { 12946 xmlAutomataStatePtr tmp; 12947 int counter; 12948 12949 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12950 oldstate, NULL); 12951 oldstate = pctxt->state; 12952 12953 counter = xmlAutomataNewCounter(pctxt->am, 12954 particle->minOccurs - 1, 12955 particle->maxOccurs - 1); 12956 12957 sub = particle->children->children; 12958 while (sub != NULL) { 12959 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12960 (xmlSchemaParticlePtr) sub); 12961 if (tmp2 != 1) ret = 0; 12962 sub = sub->next; 12963 } 12964 tmp = pctxt->state; 12965 xmlAutomataNewCountedTrans(pctxt->am, 12966 tmp, oldstate, counter); 12967 pctxt->state = 12968 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12969 counter); 12970 if ((particle->minOccurs == 0) || (ret == 1)) { 12971 xmlAutomataNewEpsilon(pctxt->am, 12972 oldstate, pctxt->state); 12973 ret = 1; 12974 } 12975 } else { 12976 sub = particle->children->children; 12977 while (sub != NULL) { 12978 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12979 (xmlSchemaParticlePtr) sub); 12980 if (tmp2 != 1) ret = 0; 12981 sub = sub->next; 12982 } 12983 12984 /* 12985 * epsilon needed to block previous trans from 12986 * being allowed to enter back from another 12987 * construct 12988 */ 12989 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12990 pctxt->state, NULL); 12991 12992 if (particle->minOccurs == 0) { 12993 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12994 pctxt->state); 12995 ret = 1; 12996 } 12997 } 12998 } 12999 break; 13000 } 13001 case XML_SCHEMA_TYPE_CHOICE:{ 13002 xmlSchemaTreeItemPtr sub; 13003 xmlAutomataStatePtr start, end; 13004 13005 ret = 0; 13006 start = pctxt->state; 13007 end = xmlAutomataNewState(pctxt->am); 13008 13009 /* 13010 * iterate over the subtypes and remerge the end with an 13011 * epsilon transition 13012 */ 13013 if (particle->maxOccurs == 1) { 13014 sub = particle->children->children; 13015 while (sub != NULL) { 13016 pctxt->state = start; 13017 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13018 (xmlSchemaParticlePtr) sub); 13019 if (tmp2 == 1) ret = 1; 13020 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13021 sub = sub->next; 13022 } 13023 } else { 13024 int counter; 13025 xmlAutomataStatePtr hop, base; 13026 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13027 UNBOUNDED : particle->maxOccurs - 1; 13028 int minOccurs = 13029 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13030 13031 /* 13032 * use a counter to keep track of the number of transitions 13033 * which went through the choice. 13034 */ 13035 counter = 13036 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13037 hop = xmlAutomataNewState(pctxt->am); 13038 base = xmlAutomataNewState(pctxt->am); 13039 13040 sub = particle->children->children; 13041 while (sub != NULL) { 13042 pctxt->state = base; 13043 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13044 (xmlSchemaParticlePtr) sub); 13045 if (tmp2 == 1) ret = 1; 13046 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13047 sub = sub->next; 13048 } 13049 xmlAutomataNewEpsilon(pctxt->am, start, base); 13050 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13051 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13052 if (ret == 1) 13053 xmlAutomataNewEpsilon(pctxt->am, base, end); 13054 } 13055 if (particle->minOccurs == 0) { 13056 xmlAutomataNewEpsilon(pctxt->am, start, end); 13057 ret = 1; 13058 } 13059 pctxt->state = end; 13060 break; 13061 } 13062 case XML_SCHEMA_TYPE_ALL:{ 13063 xmlAutomataStatePtr start, tmp; 13064 xmlSchemaParticlePtr sub; 13065 xmlSchemaElementPtr elemDecl; 13066 13067 ret = 1; 13068 13069 sub = (xmlSchemaParticlePtr) particle->children->children; 13070 if (sub == NULL) 13071 break; 13072 13073 ret = 0; 13074 13075 start = pctxt->state; 13076 tmp = xmlAutomataNewState(pctxt->am); 13077 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13078 pctxt->state = tmp; 13079 while (sub != NULL) { 13080 pctxt->state = tmp; 13081 13082 elemDecl = (xmlSchemaElementPtr) sub->children; 13083 if (elemDecl == NULL) { 13084 PERROR_INT("xmlSchemaBuildAContentModel", 13085 "<element> particle has no term"); 13086 return(ret); 13087 }; 13088 /* 13089 * NOTE: The {max occurs} of all the particles in the 13090 * {particles} of the group must be 0 or 1; this is 13091 * already ensured during the parse of the content of 13092 * <all>. 13093 */ 13094 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13095 int counter; 13096 13097 /* 13098 * This is an abstract group, we need to share 13099 * the same counter for all the element transitions 13100 * derived from the group 13101 */ 13102 counter = xmlAutomataNewCounter(pctxt->am, 13103 sub->minOccurs, sub->maxOccurs); 13104 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13105 sub, counter, pctxt->state); 13106 } else { 13107 if ((sub->minOccurs == 1) && 13108 (sub->maxOccurs == 1)) { 13109 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13110 pctxt->state, 13111 elemDecl->name, 13112 elemDecl->targetNamespace, 13113 1, 1, elemDecl); 13114 } else if ((sub->minOccurs == 0) && 13115 (sub->maxOccurs == 1)) { 13116 13117 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13118 pctxt->state, 13119 elemDecl->name, 13120 elemDecl->targetNamespace, 13121 0, 13122 1, 13123 elemDecl); 13124 } 13125 } 13126 sub = (xmlSchemaParticlePtr) sub->next; 13127 } 13128 pctxt->state = 13129 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13130 if (particle->minOccurs == 0) { 13131 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13132 ret = 1; 13133 } 13134 break; 13135 } 13136 case XML_SCHEMA_TYPE_GROUP: 13137 /* 13138 * If we hit a model group definition, then this means that 13139 * it was empty, thus was not substituted for the containing 13140 * model group. Just do nothing in this case. 13141 * TODO: But the group should be substituted and not occur at 13142 * all in the content model at this point. Fix this. 13143 */ 13144 ret = 1; 13145 break; 13146 default: 13147 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13148 "xmlSchemaBuildAContentModel", 13149 "found unexpected term of type '%s' in content model", 13150 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13151 return(ret); 13152 } 13153 return(ret); 13154 } 13155 13156 /** 13157 * xmlSchemaBuildContentModel: 13158 * @ctxt: the schema parser context 13159 * @type: the complex type definition 13160 * @name: the element name 13161 * 13162 * Builds the content model of the complex type. 13163 */ 13164 static void 13165 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13166 xmlSchemaParserCtxtPtr ctxt) 13167 { 13168 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13169 (type->contModel != NULL) || 13170 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13171 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13172 return; 13173 13174 #ifdef DEBUG_CONTENT 13175 xmlGenericError(xmlGenericErrorContext, 13176 "Building content model for %s\n", name); 13177 #endif 13178 ctxt->am = NULL; 13179 ctxt->am = xmlNewAutomata(); 13180 if (ctxt->am == NULL) { 13181 xmlGenericError(xmlGenericErrorContext, 13182 "Cannot create automata for complex type %s\n", type->name); 13183 return; 13184 } 13185 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13186 /* 13187 * Build the automaton. 13188 */ 13189 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13190 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13191 type->contModel = xmlAutomataCompile(ctxt->am); 13192 if (type->contModel == NULL) { 13193 xmlSchemaPCustomErr(ctxt, 13194 XML_SCHEMAP_INTERNAL, 13195 WXS_BASIC_CAST type, type->node, 13196 "Failed to compile the content model", NULL); 13197 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13198 xmlSchemaPCustomErr(ctxt, 13199 XML_SCHEMAP_NOT_DETERMINISTIC, 13200 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13201 WXS_BASIC_CAST type, type->node, 13202 "The content model is not determinist", NULL); 13203 } else { 13204 #ifdef DEBUG_CONTENT_REGEXP 13205 xmlGenericError(xmlGenericErrorContext, 13206 "Content model of %s:\n", type->name); 13207 xmlRegexpPrint(stderr, type->contModel); 13208 #endif 13209 } 13210 ctxt->state = NULL; 13211 xmlFreeAutomata(ctxt->am); 13212 ctxt->am = NULL; 13213 } 13214 13215 /** 13216 * xmlSchemaResolveElementReferences: 13217 * @elem: the schema element context 13218 * @ctxt: the schema parser context 13219 * 13220 * Resolves the references of an element declaration 13221 * or particle, which has an element declaration as it's 13222 * term. 13223 */ 13224 static void 13225 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13226 xmlSchemaParserCtxtPtr ctxt) 13227 { 13228 if ((ctxt == NULL) || (elemDecl == NULL) || 13229 ((elemDecl != NULL) && 13230 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13231 return; 13232 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13233 13234 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13235 xmlSchemaTypePtr type; 13236 13237 /* (type definition) ... otherwise the type definition `resolved` 13238 * to by the `actual value` of the type [attribute] ... 13239 */ 13240 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13241 elemDecl->namedTypeNs); 13242 if (type == NULL) { 13243 xmlSchemaPResCompAttrErr(ctxt, 13244 XML_SCHEMAP_SRC_RESOLVE, 13245 WXS_BASIC_CAST elemDecl, elemDecl->node, 13246 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13247 XML_SCHEMA_TYPE_BASIC, "type definition"); 13248 } else 13249 elemDecl->subtypes = type; 13250 } 13251 if (elemDecl->substGroup != NULL) { 13252 xmlSchemaElementPtr substHead; 13253 13254 /* 13255 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13256 * substitutionGroup? 13257 */ 13258 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13259 elemDecl->substGroupNs); 13260 if (substHead == NULL) { 13261 xmlSchemaPResCompAttrErr(ctxt, 13262 XML_SCHEMAP_SRC_RESOLVE, 13263 WXS_BASIC_CAST elemDecl, NULL, 13264 "substitutionGroup", elemDecl->substGroup, 13265 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13266 } else { 13267 xmlSchemaResolveElementReferences(substHead, ctxt); 13268 /* 13269 * Set the "substitution group affiliation". 13270 * NOTE that now we use the "refDecl" field for this. 13271 */ 13272 WXS_SUBST_HEAD(elemDecl) = substHead; 13273 /* 13274 * The type definitions is set to: 13275 * SPEC "...the {type definition} of the element 13276 * declaration `resolved` to by the `actual value` 13277 * of the substitutionGroup [attribute], if present" 13278 */ 13279 if (elemDecl->subtypes == NULL) 13280 elemDecl->subtypes = substHead->subtypes; 13281 } 13282 } 13283 /* 13284 * SPEC "The definition of anyType serves as the default type definition 13285 * for element declarations whose XML representation does not specify one." 13286 */ 13287 if ((elemDecl->subtypes == NULL) && 13288 (elemDecl->namedType == NULL) && 13289 (elemDecl->substGroup == NULL)) 13290 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13291 } 13292 13293 /** 13294 * xmlSchemaResolveUnionMemberTypes: 13295 * @ctxt: the schema parser context 13296 * @type: the schema simple type definition 13297 * 13298 * Checks and builds the "member type definitions" property of the union 13299 * simple type. This handles part (1), part (2) is done in 13300 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13301 * 13302 * Returns -1 in case of an internal error, 0 otherwise. 13303 */ 13304 static int 13305 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13306 xmlSchemaTypePtr type) 13307 { 13308 13309 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13310 xmlSchemaTypePtr memberType; 13311 13312 /* 13313 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13314 * define the explicit members as the type definitions `resolved` 13315 * to by the items in the `actual value` of the memberTypes [attribute], 13316 * if any, followed by the type definitions corresponding to the 13317 * <simpleType>s among the [children] of <union>, if any." 13318 */ 13319 /* 13320 * Resolve references. 13321 */ 13322 link = type->memberTypes; 13323 lastLink = NULL; 13324 while (link != NULL) { 13325 const xmlChar *name, *nsName; 13326 13327 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13328 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13329 13330 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13331 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13332 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13333 WXS_BASIC_CAST type, type->node, "memberTypes", 13334 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13335 /* 13336 * Remove the member type link. 13337 */ 13338 if (lastLink == NULL) 13339 type->memberTypes = link->next; 13340 else 13341 lastLink->next = link->next; 13342 newLink = link; 13343 link = link->next; 13344 xmlFree(newLink); 13345 } else { 13346 link->type = memberType; 13347 lastLink = link; 13348 link = link->next; 13349 } 13350 } 13351 /* 13352 * Add local simple types, 13353 */ 13354 memberType = type->subtypes; 13355 while (memberType != NULL) { 13356 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13357 if (link == NULL) { 13358 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13359 return (-1); 13360 } 13361 link->type = memberType; 13362 link->next = NULL; 13363 if (lastLink == NULL) 13364 type->memberTypes = link; 13365 else 13366 lastLink->next = link; 13367 lastLink = link; 13368 memberType = memberType->next; 13369 } 13370 return (0); 13371 } 13372 13373 /** 13374 * xmlSchemaIsDerivedFromBuiltInType: 13375 * @ctxt: the schema parser context 13376 * @type: the type definition 13377 * @valType: the value type 13378 * 13379 * 13380 * Returns 1 if the type has the given value type, or 13381 * is derived from such a type. 13382 */ 13383 static int 13384 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13385 { 13386 if (type == NULL) 13387 return (0); 13388 if (WXS_IS_COMPLEX(type)) 13389 return (0); 13390 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13391 if (type->builtInType == valType) 13392 return(1); 13393 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13394 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13395 return (0); 13396 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13397 } 13398 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13399 } 13400 13401 #if 0 13402 /** 13403 * xmlSchemaIsDerivedFromBuiltInType: 13404 * @ctxt: the schema parser context 13405 * @type: the type definition 13406 * @valType: the value type 13407 * 13408 * 13409 * Returns 1 if the type has the given value type, or 13410 * is derived from such a type. 13411 */ 13412 static int 13413 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13414 { 13415 if (type == NULL) 13416 return (0); 13417 if (WXS_IS_COMPLEX(type)) 13418 return (0); 13419 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13420 if (type->builtInType == valType) 13421 return(1); 13422 return (0); 13423 } else 13424 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13425 13426 return (0); 13427 } 13428 13429 static xmlSchemaTypePtr 13430 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13431 { 13432 if (type == NULL) 13433 return (NULL); 13434 if (WXS_IS_COMPLEX(type)) 13435 return (NULL); 13436 if (type->type == XML_SCHEMA_TYPE_BASIC) 13437 return(type); 13438 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13439 } 13440 #endif 13441 13442 /** 13443 * xmlSchemaGetPrimitiveType: 13444 * @type: the simpleType definition 13445 * 13446 * Returns the primitive type of the given type or 13447 * NULL in case of error. 13448 */ 13449 static xmlSchemaTypePtr 13450 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13451 { 13452 13453 while (type != NULL) { 13454 /* 13455 * Note that anySimpleType is actually not a primitive type 13456 * but we need that here. 13457 */ 13458 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13459 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13460 return (type); 13461 type = type->baseType; 13462 } 13463 13464 return (NULL); 13465 } 13466 13467 #if 0 13468 /** 13469 * xmlSchemaGetBuiltInTypeAncestor: 13470 * @type: the simpleType definition 13471 * 13472 * Returns the primitive type of the given type or 13473 * NULL in case of error. 13474 */ 13475 static xmlSchemaTypePtr 13476 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13477 { 13478 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13479 return (0); 13480 while (type != NULL) { 13481 if (type->type == XML_SCHEMA_TYPE_BASIC) 13482 return (type); 13483 type = type->baseType; 13484 } 13485 13486 return (NULL); 13487 } 13488 #endif 13489 13490 /** 13491 * xmlSchemaCloneWildcardNsConstraints: 13492 * @ctxt: the schema parser context 13493 * @dest: the destination wildcard 13494 * @source: the source wildcard 13495 * 13496 * Clones the namespace constraints of source 13497 * and assigns them to dest. 13498 * Returns -1 on internal error, 0 otherwise. 13499 */ 13500 static int 13501 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13502 xmlSchemaWildcardPtr dest, 13503 xmlSchemaWildcardPtr source) 13504 { 13505 xmlSchemaWildcardNsPtr cur, tmp, last; 13506 13507 if ((source == NULL) || (dest == NULL)) 13508 return(-1); 13509 dest->any = source->any; 13510 cur = source->nsSet; 13511 last = NULL; 13512 while (cur != NULL) { 13513 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13514 if (tmp == NULL) 13515 return(-1); 13516 tmp->value = cur->value; 13517 if (last == NULL) 13518 dest->nsSet = tmp; 13519 else 13520 last->next = tmp; 13521 last = tmp; 13522 cur = cur->next; 13523 } 13524 if (dest->negNsSet != NULL) 13525 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13526 if (source->negNsSet != NULL) { 13527 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13528 if (dest->negNsSet == NULL) 13529 return(-1); 13530 dest->negNsSet->value = source->negNsSet->value; 13531 } else 13532 dest->negNsSet = NULL; 13533 return(0); 13534 } 13535 13536 /** 13537 * xmlSchemaUnionWildcards: 13538 * @ctxt: the schema parser context 13539 * @completeWild: the first wildcard 13540 * @curWild: the second wildcard 13541 * 13542 * Unions the namespace constraints of the given wildcards. 13543 * @completeWild will hold the resulting union. 13544 * Returns a positive error code on failure, -1 in case of an 13545 * internal error, 0 otherwise. 13546 */ 13547 static int 13548 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13549 xmlSchemaWildcardPtr completeWild, 13550 xmlSchemaWildcardPtr curWild) 13551 { 13552 xmlSchemaWildcardNsPtr cur, curB, tmp; 13553 13554 /* 13555 * 1 If O1 and O2 are the same value, then that value must be the 13556 * value. 13557 */ 13558 if ((completeWild->any == curWild->any) && 13559 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13560 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13561 13562 if ((completeWild->negNsSet == NULL) || 13563 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13564 13565 if (completeWild->nsSet != NULL) { 13566 int found = 0; 13567 13568 /* 13569 * Check equality of sets. 13570 */ 13571 cur = completeWild->nsSet; 13572 while (cur != NULL) { 13573 found = 0; 13574 curB = curWild->nsSet; 13575 while (curB != NULL) { 13576 if (cur->value == curB->value) { 13577 found = 1; 13578 break; 13579 } 13580 curB = curB->next; 13581 } 13582 if (!found) 13583 break; 13584 cur = cur->next; 13585 } 13586 if (found) 13587 return(0); 13588 } else 13589 return(0); 13590 } 13591 } 13592 /* 13593 * 2 If either O1 or O2 is any, then any must be the value 13594 */ 13595 if (completeWild->any != curWild->any) { 13596 if (completeWild->any == 0) { 13597 completeWild->any = 1; 13598 if (completeWild->nsSet != NULL) { 13599 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13600 completeWild->nsSet = NULL; 13601 } 13602 if (completeWild->negNsSet != NULL) { 13603 xmlFree(completeWild->negNsSet); 13604 completeWild->negNsSet = NULL; 13605 } 13606 } 13607 return (0); 13608 } 13609 /* 13610 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13611 * then the union of those sets must be the value. 13612 */ 13613 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13614 int found; 13615 xmlSchemaWildcardNsPtr start; 13616 13617 cur = curWild->nsSet; 13618 start = completeWild->nsSet; 13619 while (cur != NULL) { 13620 found = 0; 13621 curB = start; 13622 while (curB != NULL) { 13623 if (cur->value == curB->value) { 13624 found = 1; 13625 break; 13626 } 13627 curB = curB->next; 13628 } 13629 if (!found) { 13630 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13631 if (tmp == NULL) 13632 return (-1); 13633 tmp->value = cur->value; 13634 tmp->next = completeWild->nsSet; 13635 completeWild->nsSet = tmp; 13636 } 13637 cur = cur->next; 13638 } 13639 13640 return(0); 13641 } 13642 /* 13643 * 4 If the two are negations of different values (namespace names 13644 * or `absent`), then a pair of not and `absent` must be the value. 13645 */ 13646 if ((completeWild->negNsSet != NULL) && 13647 (curWild->negNsSet != NULL) && 13648 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13649 completeWild->negNsSet->value = NULL; 13650 13651 return(0); 13652 } 13653 /* 13654 * 5. 13655 */ 13656 if (((completeWild->negNsSet != NULL) && 13657 (completeWild->negNsSet->value != NULL) && 13658 (curWild->nsSet != NULL)) || 13659 ((curWild->negNsSet != NULL) && 13660 (curWild->negNsSet->value != NULL) && 13661 (completeWild->nsSet != NULL))) { 13662 13663 int nsFound, absentFound = 0; 13664 13665 if (completeWild->nsSet != NULL) { 13666 cur = completeWild->nsSet; 13667 curB = curWild->negNsSet; 13668 } else { 13669 cur = curWild->nsSet; 13670 curB = completeWild->negNsSet; 13671 } 13672 nsFound = 0; 13673 while (cur != NULL) { 13674 if (cur->value == NULL) 13675 absentFound = 1; 13676 else if (cur->value == curB->value) 13677 nsFound = 1; 13678 if (nsFound && absentFound) 13679 break; 13680 cur = cur->next; 13681 } 13682 13683 if (nsFound && absentFound) { 13684 /* 13685 * 5.1 If the set S includes both the negated namespace 13686 * name and `absent`, then any must be the value. 13687 */ 13688 completeWild->any = 1; 13689 if (completeWild->nsSet != NULL) { 13690 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13691 completeWild->nsSet = NULL; 13692 } 13693 if (completeWild->negNsSet != NULL) { 13694 xmlFree(completeWild->negNsSet); 13695 completeWild->negNsSet = NULL; 13696 } 13697 } else if (nsFound && (!absentFound)) { 13698 /* 13699 * 5.2 If the set S includes the negated namespace name 13700 * but not `absent`, then a pair of not and `absent` must 13701 * be the value. 13702 */ 13703 if (completeWild->nsSet != NULL) { 13704 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13705 completeWild->nsSet = NULL; 13706 } 13707 if (completeWild->negNsSet == NULL) { 13708 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13709 if (completeWild->negNsSet == NULL) 13710 return (-1); 13711 } 13712 completeWild->negNsSet->value = NULL; 13713 } else if ((!nsFound) && absentFound) { 13714 /* 13715 * 5.3 If the set S includes `absent` but not the negated 13716 * namespace name, then the union is not expressible. 13717 */ 13718 xmlSchemaPErr(ctxt, completeWild->node, 13719 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13720 "The union of the wildcard is not expressible.\n", 13721 NULL, NULL); 13722 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13723 } else if ((!nsFound) && (!absentFound)) { 13724 /* 13725 * 5.4 If the set S does not include either the negated namespace 13726 * name or `absent`, then whichever of O1 or O2 is a pair of not 13727 * and a namespace name must be the value. 13728 */ 13729 if (completeWild->negNsSet == NULL) { 13730 if (completeWild->nsSet != NULL) { 13731 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13732 completeWild->nsSet = NULL; 13733 } 13734 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13735 if (completeWild->negNsSet == NULL) 13736 return (-1); 13737 completeWild->negNsSet->value = curWild->negNsSet->value; 13738 } 13739 } 13740 return (0); 13741 } 13742 /* 13743 * 6. 13744 */ 13745 if (((completeWild->negNsSet != NULL) && 13746 (completeWild->negNsSet->value == NULL) && 13747 (curWild->nsSet != NULL)) || 13748 ((curWild->negNsSet != NULL) && 13749 (curWild->negNsSet->value == NULL) && 13750 (completeWild->nsSet != NULL))) { 13751 13752 if (completeWild->nsSet != NULL) { 13753 cur = completeWild->nsSet; 13754 } else { 13755 cur = curWild->nsSet; 13756 } 13757 while (cur != NULL) { 13758 if (cur->value == NULL) { 13759 /* 13760 * 6.1 If the set S includes `absent`, then any must be the 13761 * value. 13762 */ 13763 completeWild->any = 1; 13764 if (completeWild->nsSet != NULL) { 13765 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13766 completeWild->nsSet = NULL; 13767 } 13768 if (completeWild->negNsSet != NULL) { 13769 xmlFree(completeWild->negNsSet); 13770 completeWild->negNsSet = NULL; 13771 } 13772 return (0); 13773 } 13774 cur = cur->next; 13775 } 13776 if (completeWild->negNsSet == NULL) { 13777 /* 13778 * 6.2 If the set S does not include `absent`, then a pair of not 13779 * and `absent` must be the value. 13780 */ 13781 if (completeWild->nsSet != NULL) { 13782 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13783 completeWild->nsSet = NULL; 13784 } 13785 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13786 if (completeWild->negNsSet == NULL) 13787 return (-1); 13788 completeWild->negNsSet->value = NULL; 13789 } 13790 return (0); 13791 } 13792 return (0); 13793 13794 } 13795 13796 /** 13797 * xmlSchemaIntersectWildcards: 13798 * @ctxt: the schema parser context 13799 * @completeWild: the first wildcard 13800 * @curWild: the second wildcard 13801 * 13802 * Intersects the namespace constraints of the given wildcards. 13803 * @completeWild will hold the resulting intersection. 13804 * Returns a positive error code on failure, -1 in case of an 13805 * internal error, 0 otherwise. 13806 */ 13807 static int 13808 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13809 xmlSchemaWildcardPtr completeWild, 13810 xmlSchemaWildcardPtr curWild) 13811 { 13812 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13813 13814 /* 13815 * 1 If O1 and O2 are the same value, then that value must be the 13816 * value. 13817 */ 13818 if ((completeWild->any == curWild->any) && 13819 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13820 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13821 13822 if ((completeWild->negNsSet == NULL) || 13823 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13824 13825 if (completeWild->nsSet != NULL) { 13826 int found = 0; 13827 13828 /* 13829 * Check equality of sets. 13830 */ 13831 cur = completeWild->nsSet; 13832 while (cur != NULL) { 13833 found = 0; 13834 curB = curWild->nsSet; 13835 while (curB != NULL) { 13836 if (cur->value == curB->value) { 13837 found = 1; 13838 break; 13839 } 13840 curB = curB->next; 13841 } 13842 if (!found) 13843 break; 13844 cur = cur->next; 13845 } 13846 if (found) 13847 return(0); 13848 } else 13849 return(0); 13850 } 13851 } 13852 /* 13853 * 2 If either O1 or O2 is any, then the other must be the value. 13854 */ 13855 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13856 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13857 return(-1); 13858 return(0); 13859 } 13860 /* 13861 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13862 * name or `absent`) and the other is a set of (namespace names or 13863 * `absent`), then that set, minus the negated value if it was in 13864 * the set, minus `absent` if it was in the set, must be the value. 13865 */ 13866 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13867 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13868 const xmlChar *neg; 13869 13870 if (completeWild->nsSet == NULL) { 13871 neg = completeWild->negNsSet->value; 13872 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13873 return(-1); 13874 } else 13875 neg = curWild->negNsSet->value; 13876 /* 13877 * Remove absent and negated. 13878 */ 13879 prev = NULL; 13880 cur = completeWild->nsSet; 13881 while (cur != NULL) { 13882 if (cur->value == NULL) { 13883 if (prev == NULL) 13884 completeWild->nsSet = cur->next; 13885 else 13886 prev->next = cur->next; 13887 xmlFree(cur); 13888 break; 13889 } 13890 prev = cur; 13891 cur = cur->next; 13892 } 13893 if (neg != NULL) { 13894 prev = NULL; 13895 cur = completeWild->nsSet; 13896 while (cur != NULL) { 13897 if (cur->value == neg) { 13898 if (prev == NULL) 13899 completeWild->nsSet = cur->next; 13900 else 13901 prev->next = cur->next; 13902 xmlFree(cur); 13903 break; 13904 } 13905 prev = cur; 13906 cur = cur->next; 13907 } 13908 } 13909 13910 return(0); 13911 } 13912 /* 13913 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13914 * then the intersection of those sets must be the value. 13915 */ 13916 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13917 int found; 13918 13919 cur = completeWild->nsSet; 13920 prev = NULL; 13921 while (cur != NULL) { 13922 found = 0; 13923 curB = curWild->nsSet; 13924 while (curB != NULL) { 13925 if (cur->value == curB->value) { 13926 found = 1; 13927 break; 13928 } 13929 curB = curB->next; 13930 } 13931 if (!found) { 13932 if (prev == NULL) 13933 completeWild->nsSet = cur->next; 13934 else 13935 prev->next = cur->next; 13936 tmp = cur->next; 13937 xmlFree(cur); 13938 cur = tmp; 13939 continue; 13940 } 13941 prev = cur; 13942 cur = cur->next; 13943 } 13944 13945 return(0); 13946 } 13947 /* 5 If the two are negations of different namespace names, 13948 * then the intersection is not expressible 13949 */ 13950 if ((completeWild->negNsSet != NULL) && 13951 (curWild->negNsSet != NULL) && 13952 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13953 (completeWild->negNsSet->value != NULL) && 13954 (curWild->negNsSet->value != NULL)) { 13955 13956 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13957 "The intersection of the wildcard is not expressible.\n", 13958 NULL, NULL); 13959 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13960 } 13961 /* 13962 * 6 If the one is a negation of a namespace name and the other 13963 * is a negation of `absent`, then the one which is the negation 13964 * of a namespace name must be the value. 13965 */ 13966 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13967 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13968 (completeWild->negNsSet->value == NULL)) { 13969 completeWild->negNsSet->value = curWild->negNsSet->value; 13970 } 13971 return(0); 13972 } 13973 13974 /** 13975 * xmlSchemaIsWildcardNsConstraintSubset: 13976 * @ctxt: the schema parser context 13977 * @sub: the first wildcard 13978 * @super: the second wildcard 13979 * 13980 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13981 * 13982 * Returns 0 if the namespace constraint of @sub is an intensional 13983 * subset of @super, 1 otherwise. 13984 */ 13985 static int 13986 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13987 xmlSchemaWildcardPtr super) 13988 { 13989 /* 13990 * 1 super must be any. 13991 */ 13992 if (super->any) 13993 return (0); 13994 /* 13995 * 2.1 sub must be a pair of not and a namespace name or `absent`. 13996 * 2.2 super must be a pair of not and the same value. 13997 */ 13998 if ((sub->negNsSet != NULL) && 13999 (super->negNsSet != NULL) && 14000 (sub->negNsSet->value == super->negNsSet->value)) 14001 return (0); 14002 /* 14003 * 3.1 sub must be a set whose members are either namespace names or `absent`. 14004 */ 14005 if (sub->nsSet != NULL) { 14006 /* 14007 * 3.2.1 super must be the same set or a superset thereof. 14008 */ 14009 if (super->nsSet != NULL) { 14010 xmlSchemaWildcardNsPtr cur, curB; 14011 int found = 0; 14012 14013 cur = sub->nsSet; 14014 while (cur != NULL) { 14015 found = 0; 14016 curB = super->nsSet; 14017 while (curB != NULL) { 14018 if (cur->value == curB->value) { 14019 found = 1; 14020 break; 14021 } 14022 curB = curB->next; 14023 } 14024 if (!found) 14025 return (1); 14026 cur = cur->next; 14027 } 14028 if (found) 14029 return (0); 14030 } else if (super->negNsSet != NULL) { 14031 xmlSchemaWildcardNsPtr cur; 14032 /* 14033 * 3.2.2 super must be a pair of not and a namespace name or 14034 * `absent` and that value must not be in sub's set. 14035 */ 14036 cur = sub->nsSet; 14037 while (cur != NULL) { 14038 if (cur->value == super->negNsSet->value) 14039 return (1); 14040 cur = cur->next; 14041 } 14042 return (0); 14043 } 14044 } 14045 return (1); 14046 } 14047 14048 static int 14049 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14050 int *fixed, 14051 const xmlChar **value, 14052 xmlSchemaValPtr *val) 14053 { 14054 *fixed = 0; 14055 *value = NULL; 14056 if (val != 0) 14057 *val = NULL; 14058 14059 if (attruse->defValue != NULL) { 14060 *value = attruse->defValue; 14061 if (val != NULL) 14062 *val = attruse->defVal; 14063 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14064 *fixed = 1; 14065 return(1); 14066 } else if ((attruse->attrDecl != NULL) && 14067 (attruse->attrDecl->defValue != NULL)) { 14068 *value = attruse->attrDecl->defValue; 14069 if (val != NULL) 14070 *val = attruse->attrDecl->defVal; 14071 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14072 *fixed = 1; 14073 return(1); 14074 } 14075 return(0); 14076 } 14077 /** 14078 * xmlSchemaCheckCVCWildcardNamespace: 14079 * @wild: the wildcard 14080 * @ns: the namespace 14081 * 14082 * Validation Rule: Wildcard allows Namespace Name 14083 * (cvc-wildcard-namespace) 14084 * 14085 * Returns 0 if the given namespace matches the wildcard, 14086 * 1 otherwise and -1 on API errors. 14087 */ 14088 static int 14089 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14090 const xmlChar* ns) 14091 { 14092 if (wild == NULL) 14093 return(-1); 14094 14095 if (wild->any) 14096 return(0); 14097 else if (wild->nsSet != NULL) { 14098 xmlSchemaWildcardNsPtr cur; 14099 14100 cur = wild->nsSet; 14101 while (cur != NULL) { 14102 if (xmlStrEqual(cur->value, ns)) 14103 return(0); 14104 cur = cur->next; 14105 } 14106 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14107 (!xmlStrEqual(wild->negNsSet->value, ns))) 14108 return(0); 14109 14110 return(1); 14111 } 14112 14113 #define XML_SCHEMA_ACTION_DERIVE 0 14114 #define XML_SCHEMA_ACTION_REDEFINE 1 14115 14116 #define WXS_ACTION_STR(a) \ 14117 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14118 14119 /* 14120 * Schema Component Constraint: 14121 * Derivation Valid (Restriction, Complex) 14122 * derivation-ok-restriction (2) - (4) 14123 * 14124 * ATTENTION: 14125 * In XML Schema 1.1 this will be: 14126 * Validation Rule: 14127 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14128 * 14129 */ 14130 static int 14131 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14132 int action, 14133 xmlSchemaBasicItemPtr item, 14134 xmlSchemaBasicItemPtr baseItem, 14135 xmlSchemaItemListPtr uses, 14136 xmlSchemaItemListPtr baseUses, 14137 xmlSchemaWildcardPtr wild, 14138 xmlSchemaWildcardPtr baseWild) 14139 { 14140 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14141 int i, j, found; /* err = 0; */ 14142 const xmlChar *bEffValue; 14143 int effFixed; 14144 14145 if (uses != NULL) { 14146 for (i = 0; i < uses->nbItems; i++) { 14147 cur = uses->items[i]; 14148 found = 0; 14149 if (baseUses == NULL) 14150 goto not_found; 14151 for (j = 0; j < baseUses->nbItems; j++) { 14152 bcur = baseUses->items[j]; 14153 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14154 WXS_ATTRUSE_DECL_NAME(bcur)) && 14155 (WXS_ATTRUSE_DECL_TNS(cur) == 14156 WXS_ATTRUSE_DECL_TNS(bcur))) 14157 { 14158 /* 14159 * (2.1) "If there is an attribute use in the {attribute 14160 * uses} of the {base type definition} (call this B) whose 14161 * {attribute declaration} has the same {name} and {target 14162 * namespace}, then all of the following must be true:" 14163 */ 14164 found = 1; 14165 14166 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14167 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14168 { 14169 xmlChar *str = NULL; 14170 /* 14171 * (2.1.1) "one of the following must be true:" 14172 * (2.1.1.1) "B's {required} is false." 14173 * (2.1.1.2) "R's {required} is true." 14174 */ 14175 xmlSchemaPAttrUseErr4(pctxt, 14176 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14177 WXS_ITEM_NODE(item), item, cur, 14178 "The 'optional' attribute use is inconsistent " 14179 "with the corresponding 'required' attribute use of " 14180 "the %s %s", 14181 WXS_ACTION_STR(action), 14182 xmlSchemaGetComponentDesignation(&str, baseItem), 14183 NULL, NULL); 14184 FREE_AND_NULL(str); 14185 /* err = pctxt->err; */ 14186 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14187 WXS_ATTRUSE_TYPEDEF(cur), 14188 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14189 { 14190 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14191 14192 /* 14193 * SPEC (2.1.2) "R's {attribute declaration}'s 14194 * {type definition} must be validly derived from 14195 * B's {type definition} given the empty set as 14196 * defined in Type Derivation OK (Simple) ($3.14.6)." 14197 */ 14198 xmlSchemaPAttrUseErr4(pctxt, 14199 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14200 WXS_ITEM_NODE(item), item, cur, 14201 "The attribute declaration's %s " 14202 "is not validly derived from " 14203 "the corresponding %s of the " 14204 "attribute declaration in the %s %s", 14205 xmlSchemaGetComponentDesignation(&strA, 14206 WXS_ATTRUSE_TYPEDEF(cur)), 14207 xmlSchemaGetComponentDesignation(&strB, 14208 WXS_ATTRUSE_TYPEDEF(bcur)), 14209 WXS_ACTION_STR(action), 14210 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14211 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14212 FREE_AND_NULL(strA); 14213 FREE_AND_NULL(strB); 14214 FREE_AND_NULL(strC); 14215 /* err = pctxt->err; */ 14216 } else { 14217 /* 14218 * 2.1.3 [Definition:] Let the effective value 14219 * constraint of an attribute use be its {value 14220 * constraint}, if present, otherwise its {attribute 14221 * declaration}'s {value constraint} . 14222 */ 14223 xmlSchemaGetEffectiveValueConstraint(bcur, 14224 &effFixed, &bEffValue, NULL); 14225 /* 14226 * 2.1.3 ... one of the following must be true 14227 * 14228 * 2.1.3.1 B's `effective value constraint` is 14229 * `absent` or default. 14230 */ 14231 if ((bEffValue != NULL) && 14232 (effFixed == 1)) { 14233 const xmlChar *rEffValue = NULL; 14234 14235 xmlSchemaGetEffectiveValueConstraint(bcur, 14236 &effFixed, &rEffValue, NULL); 14237 /* 14238 * 2.1.3.2 R's `effective value constraint` is 14239 * fixed with the same string as B's. 14240 * MAYBE TODO: Compare the computed values. 14241 * Hmm, it says "same string" so 14242 * string-equality might really be sufficient. 14243 */ 14244 if ((effFixed == 0) || 14245 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14246 { 14247 xmlChar *str = NULL; 14248 14249 xmlSchemaPAttrUseErr4(pctxt, 14250 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14251 WXS_ITEM_NODE(item), item, cur, 14252 "The effective value constraint of the " 14253 "attribute use is inconsistent with " 14254 "its correspondent in the %s %s", 14255 WXS_ACTION_STR(action), 14256 xmlSchemaGetComponentDesignation(&str, 14257 baseItem), 14258 NULL, NULL); 14259 FREE_AND_NULL(str); 14260 /* err = pctxt->err; */ 14261 } 14262 } 14263 } 14264 break; 14265 } 14266 } 14267 not_found: 14268 if (!found) { 14269 /* 14270 * (2.2) "otherwise the {base type definition} must have an 14271 * {attribute wildcard} and the {target namespace} of the 14272 * R's {attribute declaration} must be `valid` with respect 14273 * to that wildcard, as defined in Wildcard allows Namespace 14274 * Name ($3.10.4)." 14275 */ 14276 if ((baseWild == NULL) || 14277 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14278 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14279 { 14280 xmlChar *str = NULL; 14281 14282 xmlSchemaPAttrUseErr4(pctxt, 14283 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14284 WXS_ITEM_NODE(item), item, cur, 14285 "Neither a matching attribute use, " 14286 "nor a matching wildcard exists in the %s %s", 14287 WXS_ACTION_STR(action), 14288 xmlSchemaGetComponentDesignation(&str, baseItem), 14289 NULL, NULL); 14290 FREE_AND_NULL(str); 14291 /* err = pctxt->err; */ 14292 } 14293 } 14294 } 14295 } 14296 /* 14297 * SPEC derivation-ok-restriction (3): 14298 * (3) "For each attribute use in the {attribute uses} of the {base type 14299 * definition} whose {required} is true, there must be an attribute 14300 * use with an {attribute declaration} with the same {name} and 14301 * {target namespace} as its {attribute declaration} in the {attribute 14302 * uses} of the complex type definition itself whose {required} is true. 14303 */ 14304 if (baseUses != NULL) { 14305 for (j = 0; j < baseUses->nbItems; j++) { 14306 bcur = baseUses->items[j]; 14307 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14308 continue; 14309 found = 0; 14310 if (uses != NULL) { 14311 for (i = 0; i < uses->nbItems; i++) { 14312 cur = uses->items[i]; 14313 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14314 WXS_ATTRUSE_DECL_NAME(bcur)) && 14315 (WXS_ATTRUSE_DECL_TNS(cur) == 14316 WXS_ATTRUSE_DECL_TNS(bcur))) { 14317 found = 1; 14318 break; 14319 } 14320 } 14321 } 14322 if (!found) { 14323 xmlChar *strA = NULL, *strB = NULL; 14324 14325 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14326 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14327 NULL, item, 14328 "A matching attribute use for the " 14329 "'required' %s of the %s %s is missing", 14330 xmlSchemaGetComponentDesignation(&strA, bcur), 14331 WXS_ACTION_STR(action), 14332 xmlSchemaGetComponentDesignation(&strB, baseItem), 14333 NULL); 14334 FREE_AND_NULL(strA); 14335 FREE_AND_NULL(strB); 14336 } 14337 } 14338 } 14339 /* 14340 * derivation-ok-restriction (4) 14341 */ 14342 if (wild != NULL) { 14343 /* 14344 * (4) "If there is an {attribute wildcard}, all of the 14345 * following must be true:" 14346 */ 14347 if (baseWild == NULL) { 14348 xmlChar *str = NULL; 14349 14350 /* 14351 * (4.1) "The {base type definition} must also have one." 14352 */ 14353 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14354 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14355 NULL, item, 14356 "The %s has an attribute wildcard, " 14357 "but the %s %s '%s' does not have one", 14358 WXS_ITEM_TYPE_NAME(item), 14359 WXS_ACTION_STR(action), 14360 WXS_ITEM_TYPE_NAME(baseItem), 14361 xmlSchemaGetComponentQName(&str, baseItem)); 14362 FREE_AND_NULL(str); 14363 return(pctxt->err); 14364 } else if ((baseWild->any == 0) && 14365 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14366 { 14367 xmlChar *str = NULL; 14368 /* 14369 * (4.2) "The complex type definition's {attribute wildcard}'s 14370 * {namespace constraint} must be a subset of the {base type 14371 * definition}'s {attribute wildcard}'s {namespace constraint}, 14372 * as defined by Wildcard Subset ($3.10.6)." 14373 */ 14374 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14375 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14376 NULL, item, 14377 "The attribute wildcard is not a valid " 14378 "subset of the wildcard in the %s %s '%s'", 14379 WXS_ACTION_STR(action), 14380 WXS_ITEM_TYPE_NAME(baseItem), 14381 xmlSchemaGetComponentQName(&str, baseItem), 14382 NULL); 14383 FREE_AND_NULL(str); 14384 return(pctxt->err); 14385 } 14386 /* 4.3 Unless the {base type definition} is the `ur-type 14387 * definition`, the complex type definition's {attribute 14388 * wildcard}'s {process contents} must be identical to or 14389 * stronger than the {base type definition}'s {attribute 14390 * wildcard}'s {process contents}, where strict is stronger 14391 * than lax is stronger than skip. 14392 */ 14393 if ((! WXS_IS_ANYTYPE(baseItem)) && 14394 (wild->processContents < baseWild->processContents)) { 14395 xmlChar *str = NULL; 14396 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14397 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14398 NULL, baseItem, 14399 "The {process contents} of the attribute wildcard is " 14400 "weaker than the one in the %s %s '%s'", 14401 WXS_ACTION_STR(action), 14402 WXS_ITEM_TYPE_NAME(baseItem), 14403 xmlSchemaGetComponentQName(&str, baseItem), 14404 NULL); 14405 FREE_AND_NULL(str) 14406 return(pctxt->err); 14407 } 14408 } 14409 return(0); 14410 } 14411 14412 14413 static int 14414 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14415 xmlSchemaBasicItemPtr item, 14416 xmlSchemaWildcardPtr *completeWild, 14417 xmlSchemaItemListPtr list, 14418 xmlSchemaItemListPtr prohibs); 14419 /** 14420 * xmlSchemaFixupTypeAttributeUses: 14421 * @ctxt: the schema parser context 14422 * @type: the complex type definition 14423 * 14424 * 14425 * Builds the wildcard and the attribute uses on the given complex type. 14426 * Returns -1 if an internal error occurs, 0 otherwise. 14427 * 14428 * ATTENTION TODO: Experimentally this uses pointer comparisons for 14429 * strings, so recheck this if we start to hardcode some schemata, since 14430 * they might not be in the same dict. 14431 * NOTE: It is allowed to "extend" the xs:anyType type. 14432 */ 14433 static int 14434 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14435 xmlSchemaTypePtr type) 14436 { 14437 xmlSchemaTypePtr baseType = NULL; 14438 xmlSchemaAttributeUsePtr use; 14439 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14440 14441 if (type->baseType == NULL) { 14442 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14443 "no base type"); 14444 return (-1); 14445 } 14446 baseType = type->baseType; 14447 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14448 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14449 return(-1); 14450 14451 uses = type->attrUses; 14452 baseUses = baseType->attrUses; 14453 /* 14454 * Expand attribute group references. And build the 'complete' 14455 * wildcard, i.e. intersect multiple wildcards. 14456 * Move attribute prohibitions into a separate list. 14457 */ 14458 if (uses != NULL) { 14459 if (WXS_IS_RESTRICTION(type)) { 14460 /* 14461 * This one will transfer all attr. prohibitions 14462 * into pctxt->attrProhibs. 14463 */ 14464 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14465 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14466 pctxt->attrProhibs) == -1) 14467 { 14468 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14469 "failed to expand attributes"); 14470 } 14471 if (pctxt->attrProhibs->nbItems != 0) 14472 prohibs = pctxt->attrProhibs; 14473 } else { 14474 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14475 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14476 NULL) == -1) 14477 { 14478 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14479 "failed to expand attributes"); 14480 } 14481 } 14482 } 14483 /* 14484 * Inherit the attribute uses of the base type. 14485 */ 14486 if (baseUses != NULL) { 14487 int i, j; 14488 xmlSchemaAttributeUseProhibPtr pro; 14489 14490 if (WXS_IS_RESTRICTION(type)) { 14491 int usesCount; 14492 xmlSchemaAttributeUsePtr tmp; 14493 14494 if (uses != NULL) 14495 usesCount = uses->nbItems; 14496 else 14497 usesCount = 0; 14498 14499 /* Restriction. */ 14500 for (i = 0; i < baseUses->nbItems; i++) { 14501 use = baseUses->items[i]; 14502 if (prohibs) { 14503 /* 14504 * Filter out prohibited uses. 14505 */ 14506 for (j = 0; j < prohibs->nbItems; j++) { 14507 pro = prohibs->items[j]; 14508 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14509 (WXS_ATTRUSE_DECL_TNS(use) == 14510 pro->targetNamespace)) 14511 { 14512 goto inherit_next; 14513 } 14514 } 14515 } 14516 if (usesCount) { 14517 /* 14518 * Filter out existing uses. 14519 */ 14520 for (j = 0; j < usesCount; j++) { 14521 tmp = uses->items[j]; 14522 if ((WXS_ATTRUSE_DECL_NAME(use) == 14523 WXS_ATTRUSE_DECL_NAME(tmp)) && 14524 (WXS_ATTRUSE_DECL_TNS(use) == 14525 WXS_ATTRUSE_DECL_TNS(tmp))) 14526 { 14527 goto inherit_next; 14528 } 14529 } 14530 } 14531 if (uses == NULL) { 14532 type->attrUses = xmlSchemaItemListCreate(); 14533 if (type->attrUses == NULL) 14534 goto exit_failure; 14535 uses = type->attrUses; 14536 } 14537 xmlSchemaItemListAddSize(uses, 2, use); 14538 inherit_next: {} 14539 } 14540 } else { 14541 /* Extension. */ 14542 for (i = 0; i < baseUses->nbItems; i++) { 14543 use = baseUses->items[i]; 14544 if (uses == NULL) { 14545 type->attrUses = xmlSchemaItemListCreate(); 14546 if (type->attrUses == NULL) 14547 goto exit_failure; 14548 uses = type->attrUses; 14549 } 14550 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14551 } 14552 } 14553 } 14554 /* 14555 * Shrink attr. uses. 14556 */ 14557 if (uses) { 14558 if (uses->nbItems == 0) { 14559 xmlSchemaItemListFree(uses); 14560 type->attrUses = NULL; 14561 } 14562 /* 14563 * TODO: We could shrink the size of the array 14564 * to fit the actual number of items. 14565 */ 14566 } 14567 /* 14568 * Compute the complete wildcard. 14569 */ 14570 if (WXS_IS_EXTENSION(type)) { 14571 if (baseType->attributeWildcard != NULL) { 14572 /* 14573 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14574 * the appropriate case among the following:" 14575 */ 14576 if (type->attributeWildcard != NULL) { 14577 /* 14578 * Union the complete wildcard with the base wildcard. 14579 * SPEC {attribute wildcard} 14580 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14581 * and {annotation} are those of the `complete wildcard`, 14582 * and whose {namespace constraint} is the intensional union 14583 * of the {namespace constraint} of the `complete wildcard` 14584 * and of the `base wildcard`, as defined in Attribute 14585 * Wildcard Union ($3.10.6)." 14586 */ 14587 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14588 baseType->attributeWildcard) == -1) 14589 goto exit_failure; 14590 } else { 14591 /* 14592 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14593 * then the `base wildcard`." 14594 */ 14595 type->attributeWildcard = baseType->attributeWildcard; 14596 } 14597 } else { 14598 /* 14599 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14600 * `complete wildcard`" 14601 * NOOP 14602 */ 14603 } 14604 } else { 14605 /* 14606 * SPEC {attribute wildcard} 14607 * (3.1) "If the <restriction> alternative is chosen, then the 14608 * `complete wildcard`;" 14609 * NOOP 14610 */ 14611 } 14612 14613 return (0); 14614 14615 exit_failure: 14616 return(-1); 14617 } 14618 14619 /** 14620 * xmlSchemaTypeFinalContains: 14621 * @schema: the schema 14622 * @type: the type definition 14623 * @final: the final 14624 * 14625 * Evaluates if a type definition contains the given "final". 14626 * This does take "finalDefault" into account as well. 14627 * 14628 * Returns 1 if the type does contain the given "final", 14629 * 0 otherwise. 14630 */ 14631 static int 14632 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14633 { 14634 if (type == NULL) 14635 return (0); 14636 if (type->flags & final) 14637 return (1); 14638 else 14639 return (0); 14640 } 14641 14642 /** 14643 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14644 * @type: the Union Simple Type 14645 * 14646 * Returns a list of member types of @type if existing, 14647 * returns NULL otherwise. 14648 */ 14649 static xmlSchemaTypeLinkPtr 14650 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14651 { 14652 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14653 if (type->memberTypes != NULL) 14654 return (type->memberTypes); 14655 else 14656 type = type->baseType; 14657 } 14658 return (NULL); 14659 } 14660 14661 /** 14662 * xmlSchemaGetParticleTotalRangeMin: 14663 * @particle: the particle 14664 * 14665 * Schema Component Constraint: Effective Total Range 14666 * (all and sequence) + (choice) 14667 * 14668 * Returns the minimum Effective Total Range. 14669 */ 14670 static int 14671 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14672 { 14673 if ((particle->children == NULL) || 14674 (particle->minOccurs == 0)) 14675 return (0); 14676 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14677 int min = -1, cur; 14678 xmlSchemaParticlePtr part = 14679 (xmlSchemaParticlePtr) particle->children->children; 14680 14681 if (part == NULL) 14682 return (0); 14683 while (part != NULL) { 14684 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14685 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14686 cur = part->minOccurs; 14687 else 14688 cur = xmlSchemaGetParticleTotalRangeMin(part); 14689 if (cur == 0) 14690 return (0); 14691 if ((min > cur) || (min == -1)) 14692 min = cur; 14693 part = (xmlSchemaParticlePtr) part->next; 14694 } 14695 return (particle->minOccurs * min); 14696 } else { 14697 /* <all> and <sequence> */ 14698 int sum = 0; 14699 xmlSchemaParticlePtr part = 14700 (xmlSchemaParticlePtr) particle->children->children; 14701 14702 if (part == NULL) 14703 return (0); 14704 do { 14705 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14706 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14707 sum += part->minOccurs; 14708 else 14709 sum += xmlSchemaGetParticleTotalRangeMin(part); 14710 part = (xmlSchemaParticlePtr) part->next; 14711 } while (part != NULL); 14712 return (particle->minOccurs * sum); 14713 } 14714 } 14715 14716 #if 0 14717 /** 14718 * xmlSchemaGetParticleTotalRangeMax: 14719 * @particle: the particle 14720 * 14721 * Schema Component Constraint: Effective Total Range 14722 * (all and sequence) + (choice) 14723 * 14724 * Returns the maximum Effective Total Range. 14725 */ 14726 static int 14727 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14728 { 14729 if ((particle->children == NULL) || 14730 (particle->children->children == NULL)) 14731 return (0); 14732 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14733 int max = -1, 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 ((max < cur) || (max == -1)) 14748 max = cur; 14749 } 14750 /* TODO: Handle overflows? */ 14751 return (particle->maxOccurs * max); 14752 } else { 14753 /* <all> and <sequence> */ 14754 int sum = 0, cur; 14755 xmlSchemaParticlePtr part = 14756 (xmlSchemaParticlePtr) particle->children->children; 14757 14758 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14759 if (part->children == NULL) 14760 continue; 14761 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14762 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14763 cur = part->maxOccurs; 14764 else 14765 cur = xmlSchemaGetParticleTotalRangeMax(part); 14766 if (cur == UNBOUNDED) 14767 return (UNBOUNDED); 14768 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14769 return (UNBOUNDED); 14770 sum += cur; 14771 } 14772 /* TODO: Handle overflows? */ 14773 return (particle->maxOccurs * sum); 14774 } 14775 } 14776 #endif 14777 14778 /** 14779 * xmlSchemaIsParticleEmptiable: 14780 * @particle: the particle 14781 * 14782 * Schema Component Constraint: Particle Emptiable 14783 * Checks whether the given particle is emptiable. 14784 * 14785 * Returns 1 if emptiable, 0 otherwise. 14786 */ 14787 static int 14788 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14789 { 14790 /* 14791 * SPEC (1) "Its {min occurs} is 0." 14792 */ 14793 if ((particle == NULL) || (particle->minOccurs == 0) || 14794 (particle->children == NULL)) 14795 return (1); 14796 /* 14797 * SPEC (2) "Its {term} is a group and the minimum part of the 14798 * effective total range of that group, [...] is 0." 14799 */ 14800 if (WXS_IS_MODEL_GROUP(particle->children)) { 14801 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14802 return (1); 14803 } 14804 return (0); 14805 } 14806 14807 /** 14808 * xmlSchemaCheckCOSSTDerivedOK: 14809 * @actxt: a context 14810 * @type: the derived simple type definition 14811 * @baseType: the base type definition 14812 * @subset: the subset of ('restriction', etc.) 14813 * 14814 * Schema Component Constraint: 14815 * Type Derivation OK (Simple) (cos-st-derived-OK) 14816 * 14817 * Checks whether @type can be validly 14818 * derived from @baseType. 14819 * 14820 * Returns 0 on success, an positive error code otherwise. 14821 */ 14822 static int 14823 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14824 xmlSchemaTypePtr type, 14825 xmlSchemaTypePtr baseType, 14826 int subset) 14827 { 14828 /* 14829 * 1 They are the same type definition. 14830 * TODO: The identity check might have to be more complex than this. 14831 */ 14832 if (type == baseType) 14833 return (0); 14834 /* 14835 * 2.1 restriction is not in the subset, or in the {final} 14836 * of its own {base type definition}; 14837 * 14838 * NOTE that this will be used also via "xsi:type". 14839 * 14840 * TODO: Revise this, it looks strange. How can the "type" 14841 * not be fixed or *in* fixing? 14842 */ 14843 if (WXS_IS_TYPE_NOT_FIXED(type)) 14844 if (xmlSchemaTypeFixup(type, actxt) == -1) 14845 return(-1); 14846 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14847 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14848 return(-1); 14849 if ((subset & SUBSET_RESTRICTION) || 14850 (xmlSchemaTypeFinalContains(type->baseType, 14851 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14852 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14853 } 14854 /* 2.2 */ 14855 if (type->baseType == baseType) { 14856 /* 14857 * 2.2.1 D's `base type definition` is B. 14858 */ 14859 return (0); 14860 } 14861 /* 14862 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14863 * and is validly derived from B given the subset, as defined by this 14864 * constraint. 14865 */ 14866 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14867 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14868 baseType, subset) == 0)) { 14869 return (0); 14870 } 14871 /* 14872 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14873 * definition`. 14874 */ 14875 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14876 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14877 return (0); 14878 } 14879 /* 14880 * 2.2.4 B's {variety} is union and D is validly derived from a type 14881 * definition in B's {member type definitions} given the subset, as 14882 * defined by this constraint. 14883 * 14884 * NOTE: This seems not to involve built-in types, since there is no 14885 * built-in Union Simple Type. 14886 */ 14887 if (WXS_IS_UNION(baseType)) { 14888 xmlSchemaTypeLinkPtr cur; 14889 14890 cur = baseType->memberTypes; 14891 while (cur != NULL) { 14892 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14893 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14894 return(-1); 14895 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14896 type, cur->type, subset) == 0) 14897 { 14898 /* 14899 * It just has to be validly derived from at least one 14900 * member-type. 14901 */ 14902 return (0); 14903 } 14904 cur = cur->next; 14905 } 14906 } 14907 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14908 } 14909 14910 /** 14911 * xmlSchemaCheckTypeDefCircularInternal: 14912 * @pctxt: the schema parser context 14913 * @ctxtType: the type definition 14914 * @ancestor: an ancestor of @ctxtType 14915 * 14916 * Checks st-props-correct (2) + ct-props-correct (3). 14917 * Circular type definitions are not allowed. 14918 * 14919 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14920 * circular, 0 otherwise. 14921 */ 14922 static int 14923 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14924 xmlSchemaTypePtr ctxtType, 14925 xmlSchemaTypePtr ancestor) 14926 { 14927 int ret; 14928 14929 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14930 return (0); 14931 14932 if (ctxtType == ancestor) { 14933 xmlSchemaPCustomErr(pctxt, 14934 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14935 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14936 "The definition is circular", NULL); 14937 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14938 } 14939 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14940 /* 14941 * Avoid inifinite recursion on circular types not yet checked. 14942 */ 14943 return (0); 14944 } 14945 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14946 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14947 ancestor->baseType); 14948 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14949 return (ret); 14950 } 14951 14952 /** 14953 * xmlSchemaCheckTypeDefCircular: 14954 * @item: the complex/simple type definition 14955 * @ctxt: the parser context 14956 * @name: the name 14957 * 14958 * Checks for circular type definitions. 14959 */ 14960 static void 14961 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14962 xmlSchemaParserCtxtPtr ctxt) 14963 { 14964 if ((item == NULL) || 14965 (item->type == XML_SCHEMA_TYPE_BASIC) || 14966 (item->baseType == NULL)) 14967 return; 14968 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14969 item->baseType); 14970 } 14971 14972 /* 14973 * Simple Type Definition Representation OK (src-simple-type) 4 14974 * 14975 * "4 Circular union type definition is disallowed. That is, if the 14976 * <union> alternative is chosen, there must not be any entries in the 14977 * memberTypes [attribute] at any depth which resolve to the component 14978 * corresponding to the <simpleType>." 14979 * 14980 * Note that this should work on the *representation* of a component, 14981 * thus assumes any union types in the member types not being yet 14982 * substituted. At this stage we need the variety of the types 14983 * to be already computed. 14984 */ 14985 static int 14986 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14987 xmlSchemaTypePtr ctxType, 14988 xmlSchemaTypeLinkPtr members) 14989 { 14990 xmlSchemaTypeLinkPtr member; 14991 xmlSchemaTypePtr memberType; 14992 14993 member = members; 14994 while (member != NULL) { 14995 memberType = member->type; 14996 while ((memberType != NULL) && 14997 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14998 if (memberType == ctxType) { 14999 xmlSchemaPCustomErr(pctxt, 15000 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 15001 WXS_BASIC_CAST ctxType, NULL, 15002 "The union type definition is circular", NULL); 15003 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 15004 } 15005 if ((WXS_IS_UNION(memberType)) && 15006 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 15007 { 15008 int res; 15009 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 15010 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 15011 ctxType, 15012 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 15013 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 15014 if (res != 0) 15015 return(res); 15016 } 15017 memberType = memberType->baseType; 15018 } 15019 member = member->next; 15020 } 15021 return(0); 15022 } 15023 15024 static int 15025 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15026 xmlSchemaTypePtr type) 15027 { 15028 if (! WXS_IS_UNION(type)) 15029 return(0); 15030 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15031 type->memberTypes)); 15032 } 15033 15034 /** 15035 * xmlSchemaResolveTypeReferences: 15036 * @item: the complex/simple type definition 15037 * @ctxt: the parser context 15038 * @name: the name 15039 * 15040 * Resolves type definition references 15041 */ 15042 static void 15043 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15044 xmlSchemaParserCtxtPtr ctxt) 15045 { 15046 if (typeDef == NULL) 15047 return; 15048 15049 /* 15050 * Resolve the base type. 15051 */ 15052 if (typeDef->baseType == NULL) { 15053 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15054 typeDef->base, typeDef->baseNs); 15055 if (typeDef->baseType == NULL) { 15056 xmlSchemaPResCompAttrErr(ctxt, 15057 XML_SCHEMAP_SRC_RESOLVE, 15058 WXS_BASIC_CAST typeDef, typeDef->node, 15059 "base", typeDef->base, typeDef->baseNs, 15060 XML_SCHEMA_TYPE_SIMPLE, NULL); 15061 return; 15062 } 15063 } 15064 if (WXS_IS_SIMPLE(typeDef)) { 15065 if (WXS_IS_UNION(typeDef)) { 15066 /* 15067 * Resolve the memberTypes. 15068 */ 15069 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15070 return; 15071 } else if (WXS_IS_LIST(typeDef)) { 15072 /* 15073 * Resolve the itemType. 15074 */ 15075 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15076 15077 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15078 typeDef->base, typeDef->baseNs); 15079 15080 if ((typeDef->subtypes == NULL) || 15081 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15082 { 15083 typeDef->subtypes = NULL; 15084 xmlSchemaPResCompAttrErr(ctxt, 15085 XML_SCHEMAP_SRC_RESOLVE, 15086 WXS_BASIC_CAST typeDef, typeDef->node, 15087 "itemType", typeDef->base, typeDef->baseNs, 15088 XML_SCHEMA_TYPE_SIMPLE, NULL); 15089 } 15090 } 15091 return; 15092 } 15093 } 15094 /* 15095 * The ball of letters below means, that if we have a particle 15096 * which has a QName-helper component as its {term}, we want 15097 * to resolve it... 15098 */ 15099 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15100 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15101 XML_SCHEMA_TYPE_PARTICLE) && 15102 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15103 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15104 XML_SCHEMA_EXTRA_QNAMEREF)) 15105 { 15106 xmlSchemaQNameRefPtr ref = 15107 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15108 xmlSchemaModelGroupDefPtr groupDef; 15109 15110 /* 15111 * URGENT TODO: Test this. 15112 */ 15113 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15114 /* 15115 * Resolve the MG definition reference. 15116 */ 15117 groupDef = 15118 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15119 ref->itemType, ref->name, ref->targetNamespace); 15120 if (groupDef == NULL) { 15121 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15122 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15123 "ref", ref->name, ref->targetNamespace, ref->itemType, 15124 NULL); 15125 /* Remove the particle. */ 15126 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15127 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15128 /* Remove the particle. */ 15129 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15130 else { 15131 /* 15132 * Assign the MG definition's {model group} to the 15133 * particle's {term}. 15134 */ 15135 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15136 15137 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15138 /* 15139 * SPEC cos-all-limited (1.2) 15140 * "1.2 the {term} property of a particle with 15141 * {max occurs}=1 which is part of a pair which constitutes 15142 * the {content type} of a complex type definition." 15143 */ 15144 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15145 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15146 /* TODO: error code */ 15147 XML_SCHEMAP_COS_ALL_LIMITED, 15148 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15149 "The particle's {max occurs} must be 1, since the " 15150 "reference resolves to an 'all' model group", 15151 NULL, NULL); 15152 } 15153 } 15154 } 15155 } 15156 } 15157 15158 15159 15160 /** 15161 * xmlSchemaCheckSTPropsCorrect: 15162 * @ctxt: the schema parser context 15163 * @type: the simple type definition 15164 * 15165 * Checks st-props-correct. 15166 * 15167 * Returns 0 if the properties are correct, 15168 * if not, a positive error code and -1 on internal 15169 * errors. 15170 */ 15171 static int 15172 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15173 xmlSchemaTypePtr type) 15174 { 15175 xmlSchemaTypePtr baseType = type->baseType; 15176 xmlChar *str = NULL; 15177 15178 /* STATE: error funcs converted. */ 15179 /* 15180 * Schema Component Constraint: Simple Type Definition Properties Correct 15181 * 15182 * NOTE: This is somehow redundant, since we actually built a simple type 15183 * to have all the needed information; this acts as an self test. 15184 */ 15185 /* Base type: If the datatype has been `derived` by `restriction` 15186 * then the Simple Type Definition component from which it is `derived`, 15187 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15188 */ 15189 if (baseType == NULL) { 15190 /* 15191 * TODO: Think about: "modulo the impact of Missing 15192 * Sub-components ($5.3)." 15193 */ 15194 xmlSchemaPCustomErr(ctxt, 15195 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15196 WXS_BASIC_CAST type, NULL, 15197 "No base type existent", NULL); 15198 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15199 15200 } 15201 if (! WXS_IS_SIMPLE(baseType)) { 15202 xmlSchemaPCustomErr(ctxt, 15203 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15204 WXS_BASIC_CAST type, NULL, 15205 "The base type '%s' is not a simple type", 15206 xmlSchemaGetComponentQName(&str, baseType)); 15207 FREE_AND_NULL(str) 15208 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15209 } 15210 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15211 (WXS_IS_RESTRICTION(type) == 0) && 15212 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15213 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15214 xmlSchemaPCustomErr(ctxt, 15215 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15216 WXS_BASIC_CAST type, NULL, 15217 "A type, derived by list or union, must have " 15218 "the simple ur-type definition as base type, not '%s'", 15219 xmlSchemaGetComponentQName(&str, baseType)); 15220 FREE_AND_NULL(str) 15221 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15222 } 15223 /* 15224 * Variety: One of {atomic, list, union}. 15225 */ 15226 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15227 (! WXS_IS_LIST(type))) { 15228 xmlSchemaPCustomErr(ctxt, 15229 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15230 WXS_BASIC_CAST type, NULL, 15231 "The variety is absent", NULL); 15232 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15233 } 15234 /* TODO: Finish this. Hmm, is this finished? */ 15235 15236 /* 15237 * 3 The {final} of the {base type definition} must not contain restriction. 15238 */ 15239 if (xmlSchemaTypeFinalContains(baseType, 15240 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15241 xmlSchemaPCustomErr(ctxt, 15242 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15243 WXS_BASIC_CAST type, NULL, 15244 "The 'final' of its base type '%s' must not contain " 15245 "'restriction'", 15246 xmlSchemaGetComponentQName(&str, baseType)); 15247 FREE_AND_NULL(str) 15248 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15249 } 15250 15251 /* 15252 * 2 All simple type definitions must be derived ultimately from the `simple 15253 * ur-type definition` (so circular definitions are disallowed). That is, it 15254 * must be possible to reach a built-in primitive datatype or the `simple 15255 * ur-type definition` by repeatedly following the {base type definition}. 15256 * 15257 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15258 */ 15259 return (0); 15260 } 15261 15262 /** 15263 * xmlSchemaCheckCOSSTRestricts: 15264 * @ctxt: the schema parser context 15265 * @type: the simple type definition 15266 * 15267 * Schema Component Constraint: 15268 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15269 15270 * Checks if the given @type (simpleType) is derived validly by restriction. 15271 * STATUS: 15272 * 15273 * Returns -1 on internal errors, 0 if the type is validly derived, 15274 * a positive error code otherwise. 15275 */ 15276 static int 15277 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15278 xmlSchemaTypePtr type) 15279 { 15280 xmlChar *str = NULL; 15281 15282 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15283 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15284 "given type is not a user-derived simpleType"); 15285 return (-1); 15286 } 15287 15288 if (WXS_IS_ATOMIC(type)) { 15289 xmlSchemaTypePtr primitive; 15290 /* 15291 * 1.1 The {base type definition} must be an atomic simple 15292 * type definition or a built-in primitive datatype. 15293 */ 15294 if (! WXS_IS_ATOMIC(type->baseType)) { 15295 xmlSchemaPCustomErr(pctxt, 15296 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15297 WXS_BASIC_CAST type, NULL, 15298 "The base type '%s' is not an atomic simple type", 15299 xmlSchemaGetComponentQName(&str, type->baseType)); 15300 FREE_AND_NULL(str) 15301 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15302 } 15303 /* 1.2 The {final} of the {base type definition} must not contain 15304 * restriction. 15305 */ 15306 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15307 if (xmlSchemaTypeFinalContains(type->baseType, 15308 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15309 xmlSchemaPCustomErr(pctxt, 15310 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15311 WXS_BASIC_CAST type, NULL, 15312 "The final of its base type '%s' must not contain 'restriction'", 15313 xmlSchemaGetComponentQName(&str, type->baseType)); 15314 FREE_AND_NULL(str) 15315 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15316 } 15317 15318 /* 15319 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15320 * type definition}, as specified in the appropriate subsection of 3.2 15321 * Primitive datatypes. 15322 */ 15323 if (type->facets != NULL) { 15324 xmlSchemaFacetPtr facet; 15325 int ok = 1; 15326 15327 primitive = xmlSchemaGetPrimitiveType(type); 15328 if (primitive == NULL) { 15329 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15330 "failed to get primitive type"); 15331 return (-1); 15332 } 15333 facet = type->facets; 15334 do { 15335 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15336 ok = 0; 15337 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15338 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15339 type, primitive, facet); 15340 } 15341 facet = facet->next; 15342 } while (facet != NULL); 15343 if (ok == 0) 15344 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15345 } 15346 /* 15347 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15348 * of the {base type definition} (call this BF),then the DF's {value} 15349 * must be a valid restriction of BF's {value} as defined in 15350 * [XML Schemas: Datatypes]." 15351 * 15352 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15353 * xmlSchemaDeriveAndValidateFacets() 15354 */ 15355 } else if (WXS_IS_LIST(type)) { 15356 xmlSchemaTypePtr itemType = NULL; 15357 15358 itemType = type->subtypes; 15359 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15360 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15361 "failed to evaluate the item type"); 15362 return (-1); 15363 } 15364 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15365 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15366 /* 15367 * 2.1 The {item type definition} must have a {variety} of atomic or 15368 * union (in which case all the {member type definitions} 15369 * must be atomic). 15370 */ 15371 if ((! WXS_IS_ATOMIC(itemType)) && 15372 (! WXS_IS_UNION(itemType))) { 15373 xmlSchemaPCustomErr(pctxt, 15374 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15375 WXS_BASIC_CAST type, NULL, 15376 "The item type '%s' does not have a variety of atomic or union", 15377 xmlSchemaGetComponentQName(&str, itemType)); 15378 FREE_AND_NULL(str) 15379 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15380 } else if (WXS_IS_UNION(itemType)) { 15381 xmlSchemaTypeLinkPtr member; 15382 15383 member = itemType->memberTypes; 15384 while (member != NULL) { 15385 if (! WXS_IS_ATOMIC(member->type)) { 15386 xmlSchemaPCustomErr(pctxt, 15387 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15388 WXS_BASIC_CAST type, NULL, 15389 "The item type is a union type, but the " 15390 "member type '%s' of this item type is not atomic", 15391 xmlSchemaGetComponentQName(&str, member->type)); 15392 FREE_AND_NULL(str) 15393 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15394 } 15395 member = member->next; 15396 } 15397 } 15398 15399 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15400 xmlSchemaFacetPtr facet; 15401 /* 15402 * This is the case if we have: <simpleType><list .. 15403 */ 15404 /* 15405 * 2.3.1 15406 * 2.3.1.1 The {final} of the {item type definition} must not 15407 * contain list. 15408 */ 15409 if (xmlSchemaTypeFinalContains(itemType, 15410 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15411 xmlSchemaPCustomErr(pctxt, 15412 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15413 WXS_BASIC_CAST type, NULL, 15414 "The final of its item type '%s' must not contain 'list'", 15415 xmlSchemaGetComponentQName(&str, itemType)); 15416 FREE_AND_NULL(str) 15417 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15418 } 15419 /* 15420 * 2.3.1.2 The {facets} must only contain the whiteSpace 15421 * facet component. 15422 * OPTIMIZE TODO: the S4S already disallows any facet 15423 * to be specified. 15424 */ 15425 if (type->facets != NULL) { 15426 facet = type->facets; 15427 do { 15428 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15429 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15430 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15431 type, facet); 15432 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15433 } 15434 facet = facet->next; 15435 } while (facet != NULL); 15436 } 15437 /* 15438 * MAYBE TODO: (Hmm, not really) Datatypes states: 15439 * A `list` datatype can be `derived` from an `atomic` datatype 15440 * whose `lexical space` allows space (such as string or anyURI)or 15441 * a `union` datatype any of whose {member type definitions}'s 15442 * `lexical space` allows space. 15443 */ 15444 } else { 15445 /* 15446 * This is the case if we have: <simpleType><restriction ... 15447 * I.e. the variety of "list" is inherited. 15448 */ 15449 /* 15450 * 2.3.2 15451 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15452 */ 15453 if (! WXS_IS_LIST(type->baseType)) { 15454 xmlSchemaPCustomErr(pctxt, 15455 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15456 WXS_BASIC_CAST type, NULL, 15457 "The base type '%s' must be a list type", 15458 xmlSchemaGetComponentQName(&str, type->baseType)); 15459 FREE_AND_NULL(str) 15460 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15461 } 15462 /* 15463 * 2.3.2.2 The {final} of the {base type definition} must not 15464 * contain restriction. 15465 */ 15466 if (xmlSchemaTypeFinalContains(type->baseType, 15467 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15468 xmlSchemaPCustomErr(pctxt, 15469 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15470 WXS_BASIC_CAST type, NULL, 15471 "The 'final' of the base type '%s' must not contain 'restriction'", 15472 xmlSchemaGetComponentQName(&str, type->baseType)); 15473 FREE_AND_NULL(str) 15474 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15475 } 15476 /* 15477 * 2.3.2.3 The {item type definition} must be validly derived 15478 * from the {base type definition}'s {item type definition} given 15479 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15480 */ 15481 { 15482 xmlSchemaTypePtr baseItemType; 15483 15484 baseItemType = type->baseType->subtypes; 15485 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15486 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15487 "failed to eval the item type of a base type"); 15488 return (-1); 15489 } 15490 if ((itemType != baseItemType) && 15491 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15492 baseItemType, 0) != 0)) { 15493 xmlChar *strBIT = NULL, *strBT = NULL; 15494 xmlSchemaPCustomErrExt(pctxt, 15495 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15496 WXS_BASIC_CAST type, NULL, 15497 "The item type '%s' is not validly derived from " 15498 "the item type '%s' of the base type '%s'", 15499 xmlSchemaGetComponentQName(&str, itemType), 15500 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15501 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15502 15503 FREE_AND_NULL(str) 15504 FREE_AND_NULL(strBIT) 15505 FREE_AND_NULL(strBT) 15506 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15507 } 15508 } 15509 15510 if (type->facets != NULL) { 15511 xmlSchemaFacetPtr facet; 15512 int ok = 1; 15513 /* 15514 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15515 * and enumeration facet components are allowed among the {facets}. 15516 */ 15517 facet = type->facets; 15518 do { 15519 switch (facet->type) { 15520 case XML_SCHEMA_FACET_LENGTH: 15521 case XML_SCHEMA_FACET_MINLENGTH: 15522 case XML_SCHEMA_FACET_MAXLENGTH: 15523 case XML_SCHEMA_FACET_WHITESPACE: 15524 /* 15525 * TODO: 2.5.1.2 List datatypes 15526 * The value of `whiteSpace` is fixed to the value collapse. 15527 */ 15528 case XML_SCHEMA_FACET_PATTERN: 15529 case XML_SCHEMA_FACET_ENUMERATION: 15530 break; 15531 default: { 15532 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15533 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15534 type, facet); 15535 /* 15536 * We could return, but it's nicer to report all 15537 * invalid facets. 15538 */ 15539 ok = 0; 15540 } 15541 } 15542 facet = facet->next; 15543 } while (facet != NULL); 15544 if (ok == 0) 15545 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15546 /* 15547 * SPEC (2.3.2.5) (same as 1.3.2) 15548 * 15549 * NOTE (2.3.2.5) This is currently done in 15550 * xmlSchemaDeriveAndValidateFacets() 15551 */ 15552 } 15553 } 15554 } else if (WXS_IS_UNION(type)) { 15555 /* 15556 * 3.1 The {member type definitions} must all have {variety} of 15557 * atomic or list. 15558 */ 15559 xmlSchemaTypeLinkPtr member; 15560 15561 member = type->memberTypes; 15562 while (member != NULL) { 15563 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15564 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15565 15566 if ((! WXS_IS_ATOMIC(member->type)) && 15567 (! WXS_IS_LIST(member->type))) { 15568 xmlSchemaPCustomErr(pctxt, 15569 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15570 WXS_BASIC_CAST type, NULL, 15571 "The member type '%s' is neither an atomic, nor a list type", 15572 xmlSchemaGetComponentQName(&str, member->type)); 15573 FREE_AND_NULL(str) 15574 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15575 } 15576 member = member->next; 15577 } 15578 /* 15579 * 3.3.1 If the {base type definition} is the `simple ur-type 15580 * definition` 15581 */ 15582 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15583 /* 15584 * 3.3.1.1 All of the {member type definitions} must have a 15585 * {final} which does not contain union. 15586 */ 15587 member = type->memberTypes; 15588 while (member != NULL) { 15589 if (xmlSchemaTypeFinalContains(member->type, 15590 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15591 xmlSchemaPCustomErr(pctxt, 15592 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15593 WXS_BASIC_CAST type, NULL, 15594 "The 'final' of member type '%s' contains 'union'", 15595 xmlSchemaGetComponentQName(&str, member->type)); 15596 FREE_AND_NULL(str) 15597 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15598 } 15599 member = member->next; 15600 } 15601 /* 15602 * 3.3.1.2 The {facets} must be empty. 15603 */ 15604 if (type->facetSet != NULL) { 15605 xmlSchemaPCustomErr(pctxt, 15606 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15607 WXS_BASIC_CAST type, NULL, 15608 "No facets allowed", NULL); 15609 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15610 } 15611 } else { 15612 /* 15613 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15614 * I.e. the variety of "list" is inherited. 15615 */ 15616 if (! WXS_IS_UNION(type->baseType)) { 15617 xmlSchemaPCustomErr(pctxt, 15618 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15619 WXS_BASIC_CAST type, NULL, 15620 "The base type '%s' is not a union type", 15621 xmlSchemaGetComponentQName(&str, type->baseType)); 15622 FREE_AND_NULL(str) 15623 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15624 } 15625 /* 15626 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15627 */ 15628 if (xmlSchemaTypeFinalContains(type->baseType, 15629 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15630 xmlSchemaPCustomErr(pctxt, 15631 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15632 WXS_BASIC_CAST type, NULL, 15633 "The 'final' of its base type '%s' must not contain 'restriction'", 15634 xmlSchemaGetComponentQName(&str, type->baseType)); 15635 FREE_AND_NULL(str) 15636 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15637 } 15638 /* 15639 * 3.3.2.3 The {member type definitions}, in order, must be validly 15640 * derived from the corresponding type definitions in the {base 15641 * type definition}'s {member type definitions} given the empty set, 15642 * as defined in Type Derivation OK (Simple) ($3.14.6). 15643 */ 15644 { 15645 xmlSchemaTypeLinkPtr baseMember; 15646 15647 /* 15648 * OPTIMIZE: if the type is restricting, it has no local defined 15649 * member types and inherits the member types of the base type; 15650 * thus a check for equality can be skipped. 15651 */ 15652 /* 15653 * Even worse: I cannot see a scenario where a restricting 15654 * union simple type can have other member types as the member 15655 * types of it's base type. This check seems not necessary with 15656 * respect to the derivation process in libxml2. 15657 * But necessary if constructing types with an API. 15658 */ 15659 if (type->memberTypes != NULL) { 15660 member = type->memberTypes; 15661 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15662 if ((member == NULL) && (baseMember != NULL)) { 15663 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15664 "different number of member types in base"); 15665 } 15666 while (member != NULL) { 15667 if (baseMember == NULL) { 15668 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15669 "different number of member types in base"); 15670 } else if ((member->type != baseMember->type) && 15671 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15672 member->type, baseMember->type, 0) != 0)) { 15673 xmlChar *strBMT = NULL, *strBT = NULL; 15674 15675 xmlSchemaPCustomErrExt(pctxt, 15676 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15677 WXS_BASIC_CAST type, NULL, 15678 "The member type %s is not validly " 15679 "derived from its corresponding member " 15680 "type %s of the base type %s", 15681 xmlSchemaGetComponentQName(&str, member->type), 15682 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15683 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15684 FREE_AND_NULL(str) 15685 FREE_AND_NULL(strBMT) 15686 FREE_AND_NULL(strBT) 15687 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15688 } 15689 member = member->next; 15690 if (baseMember != NULL) 15691 baseMember = baseMember->next; 15692 } 15693 } 15694 } 15695 /* 15696 * 3.3.2.4 Only pattern and enumeration facet components are 15697 * allowed among the {facets}. 15698 */ 15699 if (type->facets != NULL) { 15700 xmlSchemaFacetPtr facet; 15701 int ok = 1; 15702 15703 facet = type->facets; 15704 do { 15705 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15706 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15707 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15708 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15709 type, facet); 15710 ok = 0; 15711 } 15712 facet = facet->next; 15713 } while (facet != NULL); 15714 if (ok == 0) 15715 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15716 15717 } 15718 /* 15719 * SPEC (3.3.2.5) (same as 1.3.2) 15720 * 15721 * NOTE (3.3.2.5) This is currently done in 15722 * xmlSchemaDeriveAndValidateFacets() 15723 */ 15724 } 15725 } 15726 15727 return (0); 15728 } 15729 15730 /** 15731 * xmlSchemaCheckSRCSimpleType: 15732 * @ctxt: the schema parser context 15733 * @type: the simple type definition 15734 * 15735 * Checks crc-simple-type constraints. 15736 * 15737 * Returns 0 if the constraints are satisfied, 15738 * if not a positive error code and -1 on internal 15739 * errors. 15740 */ 15741 #if 0 15742 static int 15743 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15744 xmlSchemaTypePtr type) 15745 { 15746 /* 15747 * src-simple-type.1 The corresponding simple type definition, if any, 15748 * must satisfy the conditions set out in Constraints on Simple Type 15749 * Definition Schema Components ($3.14.6). 15750 */ 15751 if (WXS_IS_RESTRICTION(type)) { 15752 /* 15753 * src-simple-type.2 "If the <restriction> alternative is chosen, 15754 * either it must have a base [attribute] or a <simpleType> among its 15755 * [children], but not both." 15756 * NOTE: This is checked in the parse function of <restriction>. 15757 */ 15758 /* 15759 * 15760 */ 15761 } else if (WXS_IS_LIST(type)) { 15762 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15763 * an itemType [attribute] or a <simpleType> among its [children], 15764 * but not both." 15765 * 15766 * NOTE: This is checked in the parse function of <list>. 15767 */ 15768 } else if (WXS_IS_UNION(type)) { 15769 /* 15770 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15771 */ 15772 } 15773 return (0); 15774 } 15775 #endif 15776 15777 static int 15778 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15779 { 15780 if (ctxt->vctxt == NULL) { 15781 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15782 if (ctxt->vctxt == NULL) { 15783 xmlSchemaPErr(ctxt, NULL, 15784 XML_SCHEMAP_INTERNAL, 15785 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15786 "failed to create a temp. validation context.\n", 15787 NULL, NULL); 15788 return (-1); 15789 } 15790 /* TODO: Pass user data. */ 15791 xmlSchemaSetValidErrors(ctxt->vctxt, 15792 ctxt->error, ctxt->warning, ctxt->errCtxt); 15793 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15794 ctxt->serror, ctxt->errCtxt); 15795 } 15796 return (0); 15797 } 15798 15799 static int 15800 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15801 xmlNodePtr node, 15802 xmlSchemaTypePtr type, 15803 const xmlChar *value, 15804 xmlSchemaValPtr *retVal, 15805 int fireErrors, 15806 int normalize, 15807 int isNormalized); 15808 15809 /** 15810 * xmlSchemaParseCheckCOSValidDefault: 15811 * @pctxt: the schema parser context 15812 * @type: the simple type definition 15813 * @value: the default value 15814 * @node: an optional node (the holder of the value) 15815 * 15816 * Schema Component Constraint: Element Default Valid (Immediate) 15817 * (cos-valid-default) 15818 * This will be used by the parser only. For the validator there's 15819 * an other version. 15820 * 15821 * Returns 0 if the constraints are satisfied, 15822 * if not, a positive error code and -1 on internal 15823 * errors. 15824 */ 15825 static int 15826 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15827 xmlNodePtr node, 15828 xmlSchemaTypePtr type, 15829 const xmlChar *value, 15830 xmlSchemaValPtr *val) 15831 { 15832 int ret = 0; 15833 15834 /* 15835 * cos-valid-default: 15836 * Schema Component Constraint: Element Default Valid (Immediate) 15837 * For a string to be a valid default with respect to a type 15838 * definition the appropriate case among the following must be true: 15839 */ 15840 if WXS_IS_COMPLEX(type) { 15841 /* 15842 * Complex type. 15843 * 15844 * SPEC (2.1) "its {content type} must be a simple type definition 15845 * or mixed." 15846 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15847 * type}'s particle must be `emptiable` as defined by 15848 * Particle Emptiable ($3.9.6)." 15849 */ 15850 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15851 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15852 /* NOTE that this covers (2.2.2) as well. */ 15853 xmlSchemaPCustomErr(pctxt, 15854 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15855 WXS_BASIC_CAST type, type->node, 15856 "For a string to be a valid default, the type definition " 15857 "must be a simple type or a complex type with mixed content " 15858 "and a particle emptiable", NULL); 15859 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15860 } 15861 } 15862 /* 15863 * 1 If the type definition is a simple type definition, then the string 15864 * must be `valid` with respect to that definition as defined by String 15865 * Valid ($3.14.4). 15866 * 15867 * AND 15868 * 15869 * 2.2.1 If the {content type} is a simple type definition, then the 15870 * string must be `valid` with respect to that simple type definition 15871 * as defined by String Valid ($3.14.4). 15872 */ 15873 if (WXS_IS_SIMPLE(type)) 15874 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15875 type, value, val, 1, 1, 0); 15876 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15877 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15878 type->contentTypeDef, value, val, 1, 1, 0); 15879 else 15880 return (ret); 15881 15882 if (ret < 0) { 15883 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15884 "calling xmlSchemaVCheckCVCSimpleType()"); 15885 } 15886 15887 return (ret); 15888 } 15889 15890 /** 15891 * xmlSchemaCheckCTPropsCorrect: 15892 * @ctxt: the schema parser context 15893 * @type: the complex type definition 15894 * 15895 *.(4.6) Constraints on Complex Type Definition Schema Components 15896 * Schema Component Constraint: 15897 * Complex Type Definition Properties Correct (ct-props-correct) 15898 * STATUS: (seems) complete 15899 * 15900 * Returns 0 if the constraints are satisfied, a positive 15901 * error code if not and -1 if an internal error occurred. 15902 */ 15903 static int 15904 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15905 xmlSchemaTypePtr type) 15906 { 15907 /* 15908 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15909 * 15910 * SPEC (1) "The values of the properties of a complex type definition must 15911 * be as described in the property tableau in The Complex Type Definition 15912 * Schema Component ($3.4.1), modulo the impact of Missing 15913 * Sub-components ($5.3)." 15914 */ 15915 if ((type->baseType != NULL) && 15916 (WXS_IS_SIMPLE(type->baseType)) && 15917 (WXS_IS_EXTENSION(type) == 0)) { 15918 /* 15919 * SPEC (2) "If the {base type definition} is a simple type definition, 15920 * the {derivation method} must be extension." 15921 */ 15922 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15923 XML_SCHEMAP_SRC_CT_1, 15924 NULL, WXS_BASIC_CAST type, 15925 "If the base type is a simple type, the derivation method must be " 15926 "'extension'", NULL, NULL); 15927 return (XML_SCHEMAP_SRC_CT_1); 15928 } 15929 /* 15930 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15931 * definition`. That is, it must be possible to reach the `ur-type 15932 * definition` by repeatedly following the {base type definition}." 15933 * 15934 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15935 */ 15936 /* 15937 * NOTE that (4) and (5) need the following: 15938 * - attribute uses need to be already inherited (apply attr. prohibitions) 15939 * - attribute group references need to be expanded already 15940 * - simple types need to be typefixed already 15941 */ 15942 if (type->attrUses && 15943 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15944 { 15945 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15946 xmlSchemaAttributeUsePtr use, tmp; 15947 int i, j, hasId = 0; 15948 15949 for (i = uses->nbItems -1; i >= 0; i--) { 15950 use = uses->items[i]; 15951 15952 /* 15953 * SPEC ct-props-correct 15954 * (4) "Two distinct attribute declarations in the 15955 * {attribute uses} must not have identical {name}s and 15956 * {target namespace}s." 15957 */ 15958 if (i > 0) { 15959 for (j = i -1; j >= 0; j--) { 15960 tmp = uses->items[j]; 15961 if ((WXS_ATTRUSE_DECL_NAME(use) == 15962 WXS_ATTRUSE_DECL_NAME(tmp)) && 15963 (WXS_ATTRUSE_DECL_TNS(use) == 15964 WXS_ATTRUSE_DECL_TNS(tmp))) 15965 { 15966 xmlChar *str = NULL; 15967 15968 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15969 XML_SCHEMAP_AG_PROPS_CORRECT, 15970 NULL, WXS_BASIC_CAST type, 15971 "Duplicate %s", 15972 xmlSchemaGetComponentDesignation(&str, use), 15973 NULL); 15974 FREE_AND_NULL(str); 15975 /* 15976 * Remove the duplicate. 15977 */ 15978 if (xmlSchemaItemListRemove(uses, i) == -1) 15979 goto exit_failure; 15980 goto next_use; 15981 } 15982 } 15983 } 15984 /* 15985 * SPEC ct-props-correct 15986 * (5) "Two distinct attribute declarations in the 15987 * {attribute uses} must not have {type definition}s which 15988 * are or are derived from ID." 15989 */ 15990 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15991 if (xmlSchemaIsDerivedFromBuiltInType( 15992 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15993 { 15994 if (hasId) { 15995 xmlChar *str = NULL; 15996 15997 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15998 XML_SCHEMAP_AG_PROPS_CORRECT, 15999 NULL, WXS_BASIC_CAST type, 16000 "There must not exist more than one attribute " 16001 "declaration of type 'xs:ID' " 16002 "(or derived from 'xs:ID'). The %s violates this " 16003 "constraint", 16004 xmlSchemaGetComponentDesignation(&str, use), 16005 NULL); 16006 FREE_AND_NULL(str); 16007 if (xmlSchemaItemListRemove(uses, i) == -1) 16008 goto exit_failure; 16009 } 16010 16011 hasId = 1; 16012 } 16013 } 16014 next_use: {} 16015 } 16016 } 16017 return (0); 16018 exit_failure: 16019 return(-1); 16020 } 16021 16022 static int 16023 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16024 xmlSchemaTypePtr typeB) 16025 { 16026 /* 16027 * TODO: This should implement component-identity 16028 * in the future. 16029 */ 16030 if ((typeA == NULL) || (typeB == NULL)) 16031 return (0); 16032 return (typeA == typeB); 16033 } 16034 16035 /** 16036 * xmlSchemaCheckCOSCTDerivedOK: 16037 * @ctxt: the schema parser context 16038 * @type: the to-be derived complex type definition 16039 * @baseType: the base complex type definition 16040 * @set: the given set 16041 * 16042 * Schema Component Constraint: 16043 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16044 * 16045 * STATUS: completed 16046 * 16047 * Returns 0 if the constraints are satisfied, or 1 16048 * if not. 16049 */ 16050 static int 16051 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16052 xmlSchemaTypePtr type, 16053 xmlSchemaTypePtr baseType, 16054 int set) 16055 { 16056 int equal = xmlSchemaAreEqualTypes(type, baseType); 16057 /* TODO: Error codes. */ 16058 /* 16059 * SPEC "For a complex type definition (call it D, for derived) 16060 * to be validly derived from a type definition (call this 16061 * B, for base) given a subset of {extension, restriction} 16062 * all of the following must be true:" 16063 */ 16064 if (! equal) { 16065 /* 16066 * SPEC (1) "If B and D are not the same type definition, then the 16067 * {derivation method} of D must not be in the subset." 16068 */ 16069 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16070 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16071 return (1); 16072 } else { 16073 /* 16074 * SPEC (2.1) "B and D must be the same type definition." 16075 */ 16076 return (0); 16077 } 16078 /* 16079 * SPEC (2.2) "B must be D's {base type definition}." 16080 */ 16081 if (type->baseType == baseType) 16082 return (0); 16083 /* 16084 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16085 * definition`." 16086 */ 16087 if (WXS_IS_ANYTYPE(type->baseType)) 16088 return (1); 16089 16090 if (WXS_IS_COMPLEX(type->baseType)) { 16091 /* 16092 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16093 * must be validly derived from B given the subset as defined by this 16094 * constraint." 16095 */ 16096 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16097 baseType, set)); 16098 } else { 16099 /* 16100 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16101 * must be validly derived from B given the subset as defined in Type 16102 * Derivation OK (Simple) ($3.14.6). 16103 */ 16104 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16105 baseType, set)); 16106 } 16107 } 16108 16109 /** 16110 * xmlSchemaCheckCOSDerivedOK: 16111 * @type: the derived simple type definition 16112 * @baseType: the base type definition 16113 * 16114 * Calls: 16115 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16116 * 16117 * Checks whether @type can be validly derived from @baseType. 16118 * 16119 * Returns 0 on success, an positive error code otherwise. 16120 */ 16121 static int 16122 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16123 xmlSchemaTypePtr type, 16124 xmlSchemaTypePtr baseType, 16125 int set) 16126 { 16127 if (WXS_IS_SIMPLE(type)) 16128 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16129 else 16130 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16131 } 16132 16133 /** 16134 * xmlSchemaCheckCOSCTExtends: 16135 * @ctxt: the schema parser context 16136 * @type: the complex type definition 16137 * 16138 * (3.4.6) Constraints on Complex Type Definition Schema Components 16139 * Schema Component Constraint: 16140 * Derivation Valid (Extension) (cos-ct-extends) 16141 * 16142 * STATUS: 16143 * missing: 16144 * (1.5) 16145 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16146 * 16147 * Returns 0 if the constraints are satisfied, a positive 16148 * error code if not and -1 if an internal error occurred. 16149 */ 16150 static int 16151 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16152 xmlSchemaTypePtr type) 16153 { 16154 xmlSchemaTypePtr base = type->baseType; 16155 /* 16156 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16157 * temporarily only. 16158 */ 16159 /* 16160 * SPEC (1) "If the {base type definition} is a complex type definition, 16161 * then all of the following must be true:" 16162 */ 16163 if (WXS_IS_COMPLEX(base)) { 16164 /* 16165 * SPEC (1.1) "The {final} of the {base type definition} must not 16166 * contain extension." 16167 */ 16168 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16169 xmlSchemaPCustomErr(ctxt, 16170 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16171 WXS_BASIC_CAST type, NULL, 16172 "The 'final' of the base type definition " 16173 "contains 'extension'", NULL); 16174 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16175 } 16176 16177 /* 16178 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16179 * since they are automatically satisfied through the 16180 * inheriting mechanism. 16181 * Note that even if redefining components, the inheriting mechanism 16182 * is used. 16183 */ 16184 #if 0 16185 /* 16186 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16187 * uses} 16188 * of the complex type definition itself, that is, for every attribute 16189 * use in the {attribute uses} of the {base type definition}, there 16190 * must be an attribute use in the {attribute uses} of the complex 16191 * type definition itself whose {attribute declaration} has the same 16192 * {name}, {target namespace} and {type definition} as its attribute 16193 * declaration" 16194 */ 16195 if (base->attrUses != NULL) { 16196 int i, j, found; 16197 xmlSchemaAttributeUsePtr use, buse; 16198 16199 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16200 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16201 found = 0; 16202 if (type->attrUses != NULL) { 16203 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16204 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16205 { 16206 if ((WXS_ATTRUSE_DECL_NAME(use) == 16207 WXS_ATTRUSE_DECL_NAME(buse)) && 16208 (WXS_ATTRUSE_DECL_TNS(use) == 16209 WXS_ATTRUSE_DECL_TNS(buse)) && 16210 (WXS_ATTRUSE_TYPEDEF(use) == 16211 WXS_ATTRUSE_TYPEDEF(buse)) 16212 { 16213 found = 1; 16214 break; 16215 } 16216 } 16217 } 16218 if (! found) { 16219 xmlChar *str = NULL; 16220 16221 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16222 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16223 NULL, WXS_BASIC_CAST type, 16224 /* 16225 * TODO: The report does not indicate that also the 16226 * type needs to be the same. 16227 */ 16228 "This type is missing a matching correspondent " 16229 "for its {base type}'s %s in its {attribute uses}", 16230 xmlSchemaGetComponentDesignation(&str, 16231 buse->children), 16232 NULL); 16233 FREE_AND_NULL(str) 16234 } 16235 } 16236 } 16237 /* 16238 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16239 * definition must also have one, and the base type definition's 16240 * {attribute wildcard}'s {namespace constraint} must be a subset 16241 * of the complex type definition's {attribute wildcard}'s {namespace 16242 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16243 */ 16244 16245 /* 16246 * MAYBE TODO: Enable if ever needed. But this will be needed only 16247 * if created the type via a schema construction API. 16248 */ 16249 if (base->attributeWildcard != NULL) { 16250 if (type->attributeWildcard == NULL) { 16251 xmlChar *str = NULL; 16252 16253 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16254 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16255 NULL, type, 16256 "The base %s has an attribute wildcard, " 16257 "but this type is missing an attribute wildcard", 16258 xmlSchemaGetComponentDesignation(&str, base)); 16259 FREE_AND_NULL(str) 16260 16261 } else if (xmlSchemaCheckCOSNSSubset( 16262 base->attributeWildcard, type->attributeWildcard)) 16263 { 16264 xmlChar *str = NULL; 16265 16266 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16267 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16268 NULL, type, 16269 "The attribute wildcard is not a valid " 16270 "superset of the one in the base %s", 16271 xmlSchemaGetComponentDesignation(&str, base)); 16272 FREE_AND_NULL(str) 16273 } 16274 } 16275 #endif 16276 /* 16277 * SPEC (1.4) "One of the following must be true:" 16278 */ 16279 if ((type->contentTypeDef != NULL) && 16280 (type->contentTypeDef == base->contentTypeDef)) { 16281 /* 16282 * SPEC (1.4.1) "The {content type} of the {base type definition} 16283 * and the {content type} of the complex type definition itself 16284 * must be the same simple type definition" 16285 * PASS 16286 */ 16287 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16288 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16289 /* 16290 * SPEC (1.4.2) "The {content type} of both the {base type 16291 * definition} and the complex type definition itself must 16292 * be empty." 16293 * PASS 16294 */ 16295 } else { 16296 /* 16297 * SPEC (1.4.3) "All of the following must be true:" 16298 */ 16299 if (type->subtypes == NULL) { 16300 /* 16301 * SPEC 1.4.3.1 The {content type} of the complex type 16302 * definition itself must specify a particle. 16303 */ 16304 xmlSchemaPCustomErr(ctxt, 16305 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16306 WXS_BASIC_CAST type, NULL, 16307 "The content type must specify a particle", NULL); 16308 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16309 } 16310 /* 16311 * SPEC (1.4.3.2) "One of the following must be true:" 16312 */ 16313 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16314 /* 16315 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16316 * definition} must be empty. 16317 * PASS 16318 */ 16319 } else { 16320 /* 16321 * SPEC (1.4.3.2.2) "All of the following must be true:" 16322 */ 16323 if ((type->contentType != base->contentType) || 16324 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16325 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16326 /* 16327 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16328 * or both must be element-only." 16329 */ 16330 xmlSchemaPCustomErr(ctxt, 16331 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16332 WXS_BASIC_CAST type, NULL, 16333 "The content type of both, the type and its base " 16334 "type, must either 'mixed' or 'element-only'", NULL); 16335 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16336 } 16337 /* 16338 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16339 * complex type definition must be a `valid extension` 16340 * of the {base type definition}'s particle, as defined 16341 * in Particle Valid (Extension) ($3.9.6)." 16342 * 16343 * NOTE that we won't check "Particle Valid (Extension)", 16344 * since it is ensured by the derivation process in 16345 * xmlSchemaTypeFixup(). We need to implement this when heading 16346 * for a construction API 16347 * TODO: !! This is needed to be checked if redefining a type !! 16348 */ 16349 } 16350 /* 16351 * URGENT TODO (1.5) 16352 */ 16353 } 16354 } else { 16355 /* 16356 * SPEC (2) "If the {base type definition} is a simple type definition, 16357 * then all of the following must be true:" 16358 */ 16359 if (type->contentTypeDef != base) { 16360 /* 16361 * SPEC (2.1) "The {content type} must be the same simple type 16362 * definition." 16363 */ 16364 xmlSchemaPCustomErr(ctxt, 16365 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16366 WXS_BASIC_CAST type, NULL, 16367 "The content type must be the simple base type", NULL); 16368 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16369 } 16370 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16371 /* 16372 * SPEC (2.2) "The {final} of the {base type definition} must not 16373 * contain extension" 16374 * NOTE that this is the same as (1.1). 16375 */ 16376 xmlSchemaPCustomErr(ctxt, 16377 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16378 WXS_BASIC_CAST type, NULL, 16379 "The 'final' of the base type definition " 16380 "contains 'extension'", NULL); 16381 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16382 } 16383 } 16384 return (0); 16385 } 16386 16387 /** 16388 * xmlSchemaCheckDerivationOKRestriction: 16389 * @ctxt: the schema parser context 16390 * @type: the complex type definition 16391 * 16392 * (3.4.6) Constraints on Complex Type Definition Schema Components 16393 * Schema Component Constraint: 16394 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16395 * 16396 * STATUS: 16397 * missing: 16398 * (5.4.2) ??? 16399 * 16400 * ATTENTION: 16401 * In XML Schema 1.1 this will be: 16402 * Validation Rule: Checking complex type subsumption 16403 * 16404 * Returns 0 if the constraints are satisfied, a positive 16405 * error code if not and -1 if an internal error occurred. 16406 */ 16407 static int 16408 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16409 xmlSchemaTypePtr type) 16410 { 16411 xmlSchemaTypePtr base; 16412 16413 /* 16414 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16415 * temporarily only. 16416 */ 16417 base = type->baseType; 16418 if (! WXS_IS_COMPLEX(base)) { 16419 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16420 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16421 type->node, WXS_BASIC_CAST type, 16422 "The base type must be a complex type", NULL, NULL); 16423 return(ctxt->err); 16424 } 16425 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16426 /* 16427 * SPEC (1) "The {base type definition} must be a complex type 16428 * definition whose {final} does not contain restriction." 16429 */ 16430 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16431 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16432 type->node, WXS_BASIC_CAST type, 16433 "The 'final' of the base type definition " 16434 "contains 'restriction'", NULL, NULL); 16435 return (ctxt->err); 16436 } 16437 /* 16438 * SPEC (2), (3) and (4) 16439 * Those are handled in a separate function, since the 16440 * same constraints are needed for redefinition of 16441 * attribute groups as well. 16442 */ 16443 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16444 XML_SCHEMA_ACTION_DERIVE, 16445 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16446 type->attrUses, base->attrUses, 16447 type->attributeWildcard, 16448 base->attributeWildcard) == -1) 16449 { 16450 return(-1); 16451 } 16452 /* 16453 * SPEC (5) "One of the following must be true:" 16454 */ 16455 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16456 /* 16457 * SPEC (5.1) "The {base type definition} must be the 16458 * `ur-type definition`." 16459 * PASS 16460 */ 16461 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16462 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16463 /* 16464 * SPEC (5.2.1) "The {content type} of the complex type definition 16465 * must be a simple type definition" 16466 * 16467 * SPEC (5.2.2) "One of the following must be true:" 16468 */ 16469 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16470 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16471 { 16472 int err; 16473 /* 16474 * SPEC (5.2.2.1) "The {content type} of the {base type 16475 * definition} must be a simple type definition from which 16476 * the {content type} is validly derived given the empty 16477 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16478 * 16479 * ATTENTION TODO: This seems not needed if the type implicitly 16480 * derived from the base type. 16481 * 16482 */ 16483 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16484 type->contentTypeDef, base->contentTypeDef, 0); 16485 if (err != 0) { 16486 xmlChar *strA = NULL, *strB = NULL; 16487 16488 if (err == -1) 16489 return(-1); 16490 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16491 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16492 NULL, WXS_BASIC_CAST type, 16493 "The {content type} %s is not validly derived from the " 16494 "base type's {content type} %s", 16495 xmlSchemaGetComponentDesignation(&strA, 16496 type->contentTypeDef), 16497 xmlSchemaGetComponentDesignation(&strB, 16498 base->contentTypeDef)); 16499 FREE_AND_NULL(strA); 16500 FREE_AND_NULL(strB); 16501 return(ctxt->err); 16502 } 16503 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16504 (xmlSchemaIsParticleEmptiable( 16505 (xmlSchemaParticlePtr) base->subtypes))) { 16506 /* 16507 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16508 * and have a particle which is `emptiable` as defined in 16509 * Particle Emptiable ($3.9.6)." 16510 * PASS 16511 */ 16512 } else { 16513 xmlSchemaPCustomErr(ctxt, 16514 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16515 WXS_BASIC_CAST type, NULL, 16516 "The content type of the base type must be either " 16517 "a simple type or 'mixed' and an emptiable particle", NULL); 16518 return (ctxt->err); 16519 } 16520 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16521 /* 16522 * SPEC (5.3.1) "The {content type} of the complex type itself must 16523 * be empty" 16524 */ 16525 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16526 /* 16527 * SPEC (5.3.2.1) "The {content type} of the {base type 16528 * definition} must also be empty." 16529 * PASS 16530 */ 16531 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16532 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16533 xmlSchemaIsParticleEmptiable( 16534 (xmlSchemaParticlePtr) base->subtypes)) { 16535 /* 16536 * SPEC (5.3.2.2) "The {content type} of the {base type 16537 * definition} must be elementOnly or mixed and have a particle 16538 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16539 * PASS 16540 */ 16541 } else { 16542 xmlSchemaPCustomErr(ctxt, 16543 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16544 WXS_BASIC_CAST type, NULL, 16545 "The content type of the base type must be either " 16546 "empty or 'mixed' (or 'elements-only') and an emptiable " 16547 "particle", NULL); 16548 return (ctxt->err); 16549 } 16550 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16551 WXS_HAS_MIXED_CONTENT(type)) { 16552 /* 16553 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16554 * itself must be element-only" 16555 */ 16556 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16557 /* 16558 * SPEC (5.4.1.2) "The {content type} of the complex type 16559 * definition itself and of the {base type definition} must be 16560 * mixed" 16561 */ 16562 xmlSchemaPCustomErr(ctxt, 16563 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16564 WXS_BASIC_CAST type, NULL, 16565 "If the content type is 'mixed', then the content type of the " 16566 "base type must also be 'mixed'", NULL); 16567 return (ctxt->err); 16568 } 16569 /* 16570 * SPEC (5.4.2) "The particle of the complex type definition itself 16571 * must be a `valid restriction` of the particle of the {content 16572 * type} of the {base type definition} as defined in Particle Valid 16573 * (Restriction) ($3.9.6). 16574 * 16575 * URGENT TODO: (5.4.2) 16576 */ 16577 } else { 16578 xmlSchemaPCustomErr(ctxt, 16579 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16580 WXS_BASIC_CAST type, NULL, 16581 "The type is not a valid restriction of its base type", NULL); 16582 return (ctxt->err); 16583 } 16584 return (0); 16585 } 16586 16587 /** 16588 * xmlSchemaCheckCTComponent: 16589 * @ctxt: the schema parser context 16590 * @type: the complex type definition 16591 * 16592 * (3.4.6) Constraints on Complex Type Definition Schema Components 16593 * 16594 * Returns 0 if the constraints are satisfied, a positive 16595 * error code if not and -1 if an internal error occurred. 16596 */ 16597 static int 16598 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16599 xmlSchemaTypePtr type) 16600 { 16601 int ret; 16602 /* 16603 * Complex Type Definition Properties Correct 16604 */ 16605 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16606 if (ret != 0) 16607 return (ret); 16608 if (WXS_IS_EXTENSION(type)) 16609 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16610 else 16611 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16612 return (ret); 16613 } 16614 16615 /** 16616 * xmlSchemaCheckSRCCT: 16617 * @ctxt: the schema parser context 16618 * @type: the complex type definition 16619 * 16620 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16621 * Schema Representation Constraint: 16622 * Complex Type Definition Representation OK (src-ct) 16623 * 16624 * Returns 0 if the constraints are satisfied, a positive 16625 * error code if not and -1 if an internal error occurred. 16626 */ 16627 static int 16628 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16629 xmlSchemaTypePtr type) 16630 { 16631 xmlSchemaTypePtr base; 16632 int ret = 0; 16633 16634 /* 16635 * TODO: Adjust the error codes here, as I used 16636 * XML_SCHEMAP_SRC_CT_1 only yet. 16637 */ 16638 base = type->baseType; 16639 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16640 /* 16641 * 1 If the <complexContent> alternative is chosen, the type definition 16642 * `resolved` to by the `actual value` of the base [attribute] 16643 * must be a complex type definition; 16644 */ 16645 if (! WXS_IS_COMPLEX(base)) { 16646 xmlChar *str = NULL; 16647 xmlSchemaPCustomErr(ctxt, 16648 XML_SCHEMAP_SRC_CT_1, 16649 WXS_BASIC_CAST type, type->node, 16650 "If using <complexContent>, the base type is expected to be " 16651 "a complex type. The base type '%s' is a simple type", 16652 xmlSchemaFormatQName(&str, base->targetNamespace, 16653 base->name)); 16654 FREE_AND_NULL(str) 16655 return (XML_SCHEMAP_SRC_CT_1); 16656 } 16657 } else { 16658 /* 16659 * SPEC 16660 * 2 If the <simpleContent> alternative is chosen, all of the 16661 * following must be true: 16662 * 2.1 The type definition `resolved` to by the `actual value` of the 16663 * base [attribute] must be one of the following: 16664 */ 16665 if (WXS_IS_SIMPLE(base)) { 16666 if (WXS_IS_EXTENSION(type) == 0) { 16667 xmlChar *str = NULL; 16668 /* 16669 * 2.1.3 only if the <extension> alternative is also 16670 * chosen, a simple type definition. 16671 */ 16672 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16673 xmlSchemaPCustomErr(ctxt, 16674 XML_SCHEMAP_SRC_CT_1, 16675 WXS_BASIC_CAST type, NULL, 16676 "If using <simpleContent> and <restriction>, the base " 16677 "type must be a complex type. The base type '%s' is " 16678 "a simple type", 16679 xmlSchemaFormatQName(&str, base->targetNamespace, 16680 base->name)); 16681 FREE_AND_NULL(str) 16682 return (XML_SCHEMAP_SRC_CT_1); 16683 } 16684 } else { 16685 /* Base type is a complex type. */ 16686 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16687 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16688 /* 16689 * 2.1.1 a complex type definition whose {content type} is a 16690 * simple type definition; 16691 * PASS 16692 */ 16693 if (base->contentTypeDef == NULL) { 16694 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16695 WXS_BASIC_CAST type, NULL, 16696 "Internal error: xmlSchemaCheckSRCCT, " 16697 "'%s', base type has no content type", 16698 type->name); 16699 return (-1); 16700 } 16701 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16702 (WXS_IS_RESTRICTION(type))) { 16703 16704 /* 16705 * 2.1.2 only if the <restriction> alternative is also 16706 * chosen, a complex type definition whose {content type} 16707 * is mixed and a particle emptiable. 16708 */ 16709 if (! xmlSchemaIsParticleEmptiable( 16710 (xmlSchemaParticlePtr) base->subtypes)) { 16711 ret = XML_SCHEMAP_SRC_CT_1; 16712 } else 16713 /* 16714 * Attention: at this point the <simpleType> child is in 16715 * ->contentTypeDef (put there during parsing). 16716 */ 16717 if (type->contentTypeDef == NULL) { 16718 xmlChar *str = NULL; 16719 /* 16720 * 2.2 If clause 2.1.2 above is satisfied, then there 16721 * must be a <simpleType> among the [children] of 16722 * <restriction>. 16723 */ 16724 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16725 xmlSchemaPCustomErr(ctxt, 16726 XML_SCHEMAP_SRC_CT_1, 16727 WXS_BASIC_CAST type, NULL, 16728 "A <simpleType> is expected among the children " 16729 "of <restriction>, if <simpleContent> is used and " 16730 "the base type '%s' is a complex type", 16731 xmlSchemaFormatQName(&str, base->targetNamespace, 16732 base->name)); 16733 FREE_AND_NULL(str) 16734 return (XML_SCHEMAP_SRC_CT_1); 16735 } 16736 } else { 16737 ret = XML_SCHEMAP_SRC_CT_1; 16738 } 16739 } 16740 if (ret > 0) { 16741 xmlChar *str = NULL; 16742 if (WXS_IS_RESTRICTION(type)) { 16743 xmlSchemaPCustomErr(ctxt, 16744 XML_SCHEMAP_SRC_CT_1, 16745 WXS_BASIC_CAST type, NULL, 16746 "If <simpleContent> and <restriction> is used, the " 16747 "base type must be a simple type or a complex type with " 16748 "mixed content and particle emptiable. The base type " 16749 "'%s' is none of those", 16750 xmlSchemaFormatQName(&str, base->targetNamespace, 16751 base->name)); 16752 } else { 16753 xmlSchemaPCustomErr(ctxt, 16754 XML_SCHEMAP_SRC_CT_1, 16755 WXS_BASIC_CAST type, NULL, 16756 "If <simpleContent> and <extension> is used, the " 16757 "base type must be a simple type. The base type '%s' " 16758 "is a complex type", 16759 xmlSchemaFormatQName(&str, base->targetNamespace, 16760 base->name)); 16761 } 16762 FREE_AND_NULL(str) 16763 } 16764 } 16765 /* 16766 * SPEC (3) "The corresponding complex type definition component must 16767 * satisfy the conditions set out in Constraints on Complex Type 16768 * Definition Schema Components ($3.4.6);" 16769 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16770 */ 16771 /* 16772 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16773 * above for {attribute wildcard} is satisfied, the intensional 16774 * intersection must be expressible, as defined in Attribute Wildcard 16775 * Intersection ($3.10.6). 16776 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16777 */ 16778 return (ret); 16779 } 16780 16781 #ifdef ENABLE_PARTICLE_RESTRICTION 16782 /** 16783 * xmlSchemaCheckParticleRangeOK: 16784 * @ctxt: the schema parser context 16785 * @type: the complex type definition 16786 * 16787 * (3.9.6) Constraints on Particle Schema Components 16788 * Schema Component Constraint: 16789 * Occurrence Range OK (range-ok) 16790 * 16791 * STATUS: complete 16792 * 16793 * Returns 0 if the constraints are satisfied, a positive 16794 * error code if not and -1 if an internal error occurred. 16795 */ 16796 static int 16797 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16798 int bmin, int bmax) 16799 { 16800 if (rmin < bmin) 16801 return (1); 16802 if ((bmax != UNBOUNDED) && 16803 (rmax > bmax)) 16804 return (1); 16805 return (0); 16806 } 16807 16808 /** 16809 * xmlSchemaCheckRCaseNameAndTypeOK: 16810 * @ctxt: the schema parser context 16811 * @r: the restricting element declaration particle 16812 * @b: the base element declaration particle 16813 * 16814 * (3.9.6) Constraints on Particle Schema Components 16815 * Schema Component Constraint: 16816 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16817 * (rcase-NameAndTypeOK) 16818 * 16819 * STATUS: 16820 * MISSING (3.2.3) 16821 * CLARIFY: (3.2.2) 16822 * 16823 * Returns 0 if the constraints are satisfied, a positive 16824 * error code if not and -1 if an internal error occurred. 16825 */ 16826 static int 16827 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16828 xmlSchemaParticlePtr r, 16829 xmlSchemaParticlePtr b) 16830 { 16831 xmlSchemaElementPtr elemR, elemB; 16832 16833 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16834 elemR = (xmlSchemaElementPtr) r->children; 16835 elemB = (xmlSchemaElementPtr) b->children; 16836 /* 16837 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16838 * the same." 16839 */ 16840 if ((elemR != elemB) && 16841 ((! xmlStrEqual(elemR->name, elemB->name)) || 16842 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16843 return (1); 16844 /* 16845 * SPEC (2) "R's occurrence range is a valid restriction of B's 16846 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16847 */ 16848 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16849 b->minOccurs, b->maxOccurs) != 0) 16850 return (1); 16851 /* 16852 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16853 * {scope} are global." 16854 */ 16855 if (elemR == elemB) 16856 return (0); 16857 /* 16858 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16859 */ 16860 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16861 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16862 return (1); 16863 /* 16864 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16865 * or is not fixed, or R's declaration's {value constraint} is fixed 16866 * with the same value." 16867 */ 16868 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16869 ((elemR->value == NULL) || 16870 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16871 /* TODO: Equality of the initial value or normalized or canonical? */ 16872 (! xmlStrEqual(elemR->value, elemB->value)))) 16873 return (1); 16874 /* 16875 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16876 * definitions} is a subset of B's declaration's {identity-constraint 16877 * definitions}, if any." 16878 */ 16879 if (elemB->idcs != NULL) { 16880 /* TODO */ 16881 } 16882 /* 16883 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16884 * superset of B's declaration's {disallowed substitutions}." 16885 */ 16886 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16887 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16888 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16889 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16890 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16891 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16892 return (1); 16893 /* 16894 * SPEC (3.2.5) "R's {type definition} is validly derived given 16895 * {extension, list, union} from B's {type definition}" 16896 * 16897 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16898 * set, if the corresponding constraints handle "restriction" and 16899 * "extension" only? 16900 * 16901 */ 16902 { 16903 int set = 0; 16904 16905 set |= SUBSET_EXTENSION; 16906 set |= SUBSET_LIST; 16907 set |= SUBSET_UNION; 16908 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16909 elemB->subtypes, set) != 0) 16910 return (1); 16911 } 16912 return (0); 16913 } 16914 16915 /** 16916 * xmlSchemaCheckRCaseNSCompat: 16917 * @ctxt: the schema parser context 16918 * @r: the restricting element declaration particle 16919 * @b: the base wildcard particle 16920 * 16921 * (3.9.6) Constraints on Particle Schema Components 16922 * Schema Component Constraint: 16923 * Particle Derivation OK (Elt:Any -- NSCompat) 16924 * (rcase-NSCompat) 16925 * 16926 * STATUS: complete 16927 * 16928 * Returns 0 if the constraints are satisfied, a positive 16929 * error code if not and -1 if an internal error occurred. 16930 */ 16931 static int 16932 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16933 xmlSchemaParticlePtr r, 16934 xmlSchemaParticlePtr b) 16935 { 16936 /* TODO:Error codes (rcase-NSCompat). */ 16937 /* 16938 * SPEC "For an element declaration particle to be a `valid restriction` 16939 * of a wildcard particle all of the following must be true:" 16940 * 16941 * SPEC (1) "The element declaration's {target namespace} is `valid` 16942 * with respect to the wildcard's {namespace constraint} as defined by 16943 * Wildcard allows Namespace Name ($3.10.4)." 16944 */ 16945 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16946 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16947 return (1); 16948 /* 16949 * SPEC (2) "R's occurrence range is a valid restriction of B's 16950 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16951 */ 16952 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16953 b->minOccurs, b->maxOccurs) != 0) 16954 return (1); 16955 16956 return (0); 16957 } 16958 16959 /** 16960 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16961 * @ctxt: the schema parser context 16962 * @r: the restricting element declaration particle 16963 * @b: the base model group particle 16964 * 16965 * (3.9.6) Constraints on Particle Schema Components 16966 * Schema Component Constraint: 16967 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16968 * (rcase-RecurseAsIfGroup) 16969 * 16970 * STATUS: TODO 16971 * 16972 * Returns 0 if the constraints are satisfied, a positive 16973 * error code if not and -1 if an internal error occurred. 16974 */ 16975 static int 16976 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16977 xmlSchemaParticlePtr r, 16978 xmlSchemaParticlePtr b) 16979 { 16980 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16981 TODO 16982 return (0); 16983 } 16984 16985 /** 16986 * xmlSchemaCheckRCaseNSSubset: 16987 * @ctxt: the schema parser context 16988 * @r: the restricting wildcard particle 16989 * @b: the base wildcard particle 16990 * 16991 * (3.9.6) Constraints on Particle Schema Components 16992 * Schema Component Constraint: 16993 * Particle Derivation OK (Any:Any -- NSSubset) 16994 * (rcase-NSSubset) 16995 * 16996 * STATUS: complete 16997 * 16998 * Returns 0 if the constraints are satisfied, a positive 16999 * error code if not and -1 if an internal error occurred. 17000 */ 17001 static int 17002 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 17003 xmlSchemaParticlePtr r, 17004 xmlSchemaParticlePtr b, 17005 int isAnyTypeBase) 17006 { 17007 /* TODO: Error codes (rcase-NSSubset). */ 17008 /* 17009 * SPEC (1) "R's occurrence range is a valid restriction of B's 17010 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17011 */ 17012 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17013 b->minOccurs, b->maxOccurs)) 17014 return (1); 17015 /* 17016 * SPEC (2) "R's {namespace constraint} must be an intensional subset 17017 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 17018 */ 17019 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 17020 (xmlSchemaWildcardPtr) b->children)) 17021 return (1); 17022 /* 17023 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17024 * definition`, R's {process contents} must be identical to or stronger 17025 * than B's {process contents}, where strict is stronger than lax is 17026 * stronger than skip." 17027 */ 17028 if (! isAnyTypeBase) { 17029 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17030 ((xmlSchemaWildcardPtr) b->children)->processContents) 17031 return (1); 17032 } 17033 17034 return (0); 17035 } 17036 17037 /** 17038 * xmlSchemaCheckCOSParticleRestrict: 17039 * @ctxt: the schema parser context 17040 * @type: the complex type definition 17041 * 17042 * (3.9.6) Constraints on Particle Schema Components 17043 * Schema Component Constraint: 17044 * Particle Valid (Restriction) (cos-particle-restrict) 17045 * 17046 * STATUS: TODO 17047 * 17048 * Returns 0 if the constraints are satisfied, a positive 17049 * error code if not and -1 if an internal error occurred. 17050 */ 17051 static int 17052 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17053 xmlSchemaParticlePtr r, 17054 xmlSchemaParticlePtr b) 17055 { 17056 int ret = 0; 17057 17058 /*part = WXS_TYPE_PARTICLE(type); 17059 basePart = WXS_TYPE_PARTICLE(base); 17060 */ 17061 17062 TODO 17063 17064 /* 17065 * SPEC (1) "They are the same particle." 17066 */ 17067 if (r == b) 17068 return (0); 17069 17070 17071 return (0); 17072 } 17073 17074 #if 0 17075 /** 17076 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17077 * @ctxt: the schema parser context 17078 * @r: the model group particle 17079 * @b: the base wildcard particle 17080 * 17081 * (3.9.6) Constraints on Particle Schema Components 17082 * Schema Component Constraint: 17083 * Particle Derivation OK (All/Choice/Sequence:Any -- 17084 * NSRecurseCheckCardinality) 17085 * (rcase-NSRecurseCheckCardinality) 17086 * 17087 * STATUS: TODO: subst-groups 17088 * 17089 * Returns 0 if the constraints are satisfied, a positive 17090 * error code if not and -1 if an internal error occurred. 17091 */ 17092 static int 17093 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17094 xmlSchemaParticlePtr r, 17095 xmlSchemaParticlePtr b) 17096 { 17097 xmlSchemaParticlePtr part; 17098 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17099 if ((r->children == NULL) || (r->children->children == NULL)) 17100 return (-1); 17101 /* 17102 * SPEC "For a group particle to be a `valid restriction` of a 17103 * wildcard particle..." 17104 * 17105 * SPEC (1) "Every member of the {particles} of the group is a `valid 17106 * restriction` of the wildcard as defined by 17107 * Particle Valid (Restriction) ($3.9.6)." 17108 */ 17109 part = (xmlSchemaParticlePtr) r->children->children; 17110 do { 17111 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17112 return (1); 17113 part = (xmlSchemaParticlePtr) part->next; 17114 } while (part != NULL); 17115 /* 17116 * SPEC (2) "The effective total range of the group [...] is a 17117 * valid restriction of B's occurrence range as defined by 17118 * Occurrence Range OK ($3.9.6)." 17119 */ 17120 if (xmlSchemaCheckParticleRangeOK( 17121 xmlSchemaGetParticleTotalRangeMin(r), 17122 xmlSchemaGetParticleTotalRangeMax(r), 17123 b->minOccurs, b->maxOccurs) != 0) 17124 return (1); 17125 return (0); 17126 } 17127 #endif 17128 17129 /** 17130 * xmlSchemaCheckRCaseRecurse: 17131 * @ctxt: the schema parser context 17132 * @r: the <all> or <sequence> model group particle 17133 * @b: the base <all> or <sequence> model group particle 17134 * 17135 * (3.9.6) Constraints on Particle Schema Components 17136 * Schema Component Constraint: 17137 * Particle Derivation OK (All:All,Sequence:Sequence -- 17138 Recurse) 17139 * (rcase-Recurse) 17140 * 17141 * STATUS: ? 17142 * TODO: subst-groups 17143 * 17144 * Returns 0 if the constraints are satisfied, a positive 17145 * error code if not and -1 if an internal error occurred. 17146 */ 17147 static int 17148 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17149 xmlSchemaParticlePtr r, 17150 xmlSchemaParticlePtr b) 17151 { 17152 /* xmlSchemaParticlePtr part; */ 17153 /* TODO: Error codes (rcase-Recurse). */ 17154 if ((r->children == NULL) || (b->children == NULL) || 17155 (r->children->type != b->children->type)) 17156 return (-1); 17157 /* 17158 * SPEC "For an all or sequence group particle to be a `valid 17159 * restriction` of another group particle with the same {compositor}..." 17160 * 17161 * SPEC (1) "R's occurrence range is a valid restriction of B's 17162 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17163 */ 17164 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17165 b->minOccurs, b->maxOccurs)) 17166 return (1); 17167 17168 17169 return (0); 17170 } 17171 17172 #endif 17173 17174 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17175 xmlSchemaPCustomErrExt(pctxt, \ 17176 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17177 WXS_BASIC_CAST fac1, fac1->node, \ 17178 "It is an error for both '%s' and '%s' to be specified on the "\ 17179 "same type definition", \ 17180 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17181 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17182 17183 #define FACET_RESTR_ERR(fac1, msg) \ 17184 xmlSchemaPCustomErr(pctxt, \ 17185 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17186 WXS_BASIC_CAST fac1, fac1->node, \ 17187 msg, NULL); 17188 17189 #define FACET_RESTR_FIXED_ERR(fac) \ 17190 xmlSchemaPCustomErr(pctxt, \ 17191 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17192 WXS_BASIC_CAST fac, fac->node, \ 17193 "The base type's facet is 'fixed', thus the value must not " \ 17194 "differ", NULL); 17195 17196 static void 17197 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17198 xmlSchemaFacetPtr facet1, 17199 xmlSchemaFacetPtr facet2, 17200 int lessGreater, 17201 int orEqual, 17202 int ofBase) 17203 { 17204 xmlChar *msg = NULL; 17205 17206 msg = xmlStrdup(BAD_CAST "'"); 17207 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17208 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17209 if (lessGreater == 0) 17210 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17211 if (lessGreater == 1) 17212 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17213 else 17214 msg = xmlStrcat(msg, BAD_CAST " less than"); 17215 17216 if (orEqual) 17217 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17218 msg = xmlStrcat(msg, BAD_CAST " '"); 17219 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17220 if (ofBase) 17221 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17222 else 17223 msg = xmlStrcat(msg, BAD_CAST "'"); 17224 17225 xmlSchemaPCustomErr(pctxt, 17226 XML_SCHEMAP_INVALID_FACET_VALUE, 17227 WXS_BASIC_CAST facet1, NULL, 17228 (const char *) msg, NULL); 17229 17230 if (msg != NULL) 17231 xmlFree(msg); 17232 } 17233 17234 /* 17235 * xmlSchemaDeriveAndValidateFacets: 17236 * 17237 * Schema Component Constraint: Simple Type Restriction (Facets) 17238 * (st-restrict-facets) 17239 */ 17240 static int 17241 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17242 xmlSchemaTypePtr type) 17243 { 17244 xmlSchemaTypePtr base = type->baseType; 17245 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17246 xmlSchemaFacetPtr facet, bfacet, 17247 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17248 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17249 fmininc = NULL, fmaxinc = NULL, 17250 fminexc = NULL, fmaxexc = NULL, 17251 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17252 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17253 bfmininc = NULL, bfmaxinc = NULL, 17254 bfminexc = NULL, bfmaxexc = NULL; 17255 int res; /* err = 0, fixedErr; */ 17256 17257 /* 17258 * SPEC st-restrict-facets 1: 17259 * "The {variety} of R is the same as that of B." 17260 */ 17261 /* 17262 * SPEC st-restrict-facets 2: 17263 * "If {variety} is atomic, the {primitive type definition} 17264 * of R is the same as that of B." 17265 * 17266 * NOTE: we leave 1 & 2 out for now, since this will be 17267 * satisfied by the derivation process. 17268 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17269 */ 17270 /* 17271 * SPEC st-restrict-facets 3: 17272 * "The {facets} of R are the union of S and the {facets} 17273 * of B, eliminating duplicates. To eliminate duplicates, 17274 * when a facet of the same kind occurs in both S and the 17275 * {facets} of B, the one in the {facets} of B is not 17276 * included, with the exception of enumeration and pattern 17277 * facets, for which multiple occurrences with distinct values 17278 * are allowed." 17279 */ 17280 17281 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17282 return (0); 17283 17284 last = type->facetSet; 17285 if (last != NULL) 17286 while (last->next != NULL) 17287 last = last->next; 17288 17289 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17290 facet = cur->facet; 17291 switch (facet->type) { 17292 case XML_SCHEMA_FACET_LENGTH: 17293 flength = facet; break; 17294 case XML_SCHEMA_FACET_MINLENGTH: 17295 fminlen = facet; break; 17296 case XML_SCHEMA_FACET_MININCLUSIVE: 17297 fmininc = facet; break; 17298 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17299 fminexc = facet; break; 17300 case XML_SCHEMA_FACET_MAXLENGTH: 17301 fmaxlen = facet; break; 17302 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17303 fmaxinc = facet; break; 17304 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17305 fmaxexc = facet; break; 17306 case XML_SCHEMA_FACET_TOTALDIGITS: 17307 ftotdig = facet; break; 17308 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17309 ffracdig = facet; break; 17310 default: 17311 break; 17312 } 17313 } 17314 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17315 facet = cur->facet; 17316 switch (facet->type) { 17317 case XML_SCHEMA_FACET_LENGTH: 17318 bflength = facet; break; 17319 case XML_SCHEMA_FACET_MINLENGTH: 17320 bfminlen = facet; break; 17321 case XML_SCHEMA_FACET_MININCLUSIVE: 17322 bfmininc = facet; break; 17323 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17324 bfminexc = facet; break; 17325 case XML_SCHEMA_FACET_MAXLENGTH: 17326 bfmaxlen = facet; break; 17327 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17328 bfmaxinc = facet; break; 17329 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17330 bfmaxexc = facet; break; 17331 case XML_SCHEMA_FACET_TOTALDIGITS: 17332 bftotdig = facet; break; 17333 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17334 bffracdig = facet; break; 17335 default: 17336 break; 17337 } 17338 } 17339 /* 17340 * length and minLength or maxLength (2.2) + (3.2) 17341 */ 17342 if (flength && (fminlen || fmaxlen)) { 17343 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17344 "either of 'minLength' or 'maxLength' to be specified on " 17345 "the same type definition") 17346 } 17347 /* 17348 * Mutual exclusions in the same derivation step. 17349 */ 17350 if ((fmaxinc) && (fmaxexc)) { 17351 /* 17352 * SCC "maxInclusive and maxExclusive" 17353 */ 17354 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17355 } 17356 if ((fmininc) && (fminexc)) { 17357 /* 17358 * SCC "minInclusive and minExclusive" 17359 */ 17360 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17361 } 17362 17363 if (flength && bflength) { 17364 /* 17365 * SCC "length valid restriction" 17366 * The values have to be equal. 17367 */ 17368 res = xmlSchemaCompareValues(flength->val, bflength->val); 17369 if (res == -2) 17370 goto internal_error; 17371 if (res != 0) 17372 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17373 if ((res != 0) && (bflength->fixed)) { 17374 FACET_RESTR_FIXED_ERR(flength) 17375 } 17376 17377 } 17378 if (fminlen && bfminlen) { 17379 /* 17380 * SCC "minLength valid restriction" 17381 * minLength >= BASE minLength 17382 */ 17383 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17384 if (res == -2) 17385 goto internal_error; 17386 if (res == -1) 17387 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17388 if ((res != 0) && (bfminlen->fixed)) { 17389 FACET_RESTR_FIXED_ERR(fminlen) 17390 } 17391 } 17392 if (fmaxlen && bfmaxlen) { 17393 /* 17394 * SCC "maxLength valid restriction" 17395 * maxLength <= BASE minLength 17396 */ 17397 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17398 if (res == -2) 17399 goto internal_error; 17400 if (res == 1) 17401 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17402 if ((res != 0) && (bfmaxlen->fixed)) { 17403 FACET_RESTR_FIXED_ERR(fmaxlen) 17404 } 17405 } 17406 /* 17407 * SCC "length and minLength or maxLength" 17408 */ 17409 if (! flength) 17410 flength = bflength; 17411 if (flength) { 17412 if (! fminlen) 17413 fminlen = bfminlen; 17414 if (fminlen) { 17415 /* (1.1) length >= minLength */ 17416 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17417 if (res == -2) 17418 goto internal_error; 17419 if (res == -1) 17420 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17421 } 17422 if (! fmaxlen) 17423 fmaxlen = bfmaxlen; 17424 if (fmaxlen) { 17425 /* (2.1) length <= maxLength */ 17426 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17427 if (res == -2) 17428 goto internal_error; 17429 if (res == 1) 17430 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17431 } 17432 } 17433 if (fmaxinc) { 17434 /* 17435 * "maxInclusive" 17436 */ 17437 if (fmininc) { 17438 /* SCC "maxInclusive >= minInclusive" */ 17439 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17440 if (res == -2) 17441 goto internal_error; 17442 if (res == -1) { 17443 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17444 } 17445 } 17446 /* 17447 * SCC "maxInclusive valid restriction" 17448 */ 17449 if (bfmaxinc) { 17450 /* maxInclusive <= BASE maxInclusive */ 17451 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17452 if (res == -2) 17453 goto internal_error; 17454 if (res == 1) 17455 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17456 if ((res != 0) && (bfmaxinc->fixed)) { 17457 FACET_RESTR_FIXED_ERR(fmaxinc) 17458 } 17459 } 17460 if (bfmaxexc) { 17461 /* maxInclusive < BASE maxExclusive */ 17462 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17463 if (res == -2) 17464 goto internal_error; 17465 if (res != -1) { 17466 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17467 } 17468 } 17469 if (bfmininc) { 17470 /* maxInclusive >= BASE minInclusive */ 17471 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17472 if (res == -2) 17473 goto internal_error; 17474 if (res == -1) { 17475 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17476 } 17477 } 17478 if (bfminexc) { 17479 /* maxInclusive > BASE minExclusive */ 17480 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17481 if (res == -2) 17482 goto internal_error; 17483 if (res != 1) { 17484 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17485 } 17486 } 17487 } 17488 if (fmaxexc) { 17489 /* 17490 * "maxExclusive >= minExclusive" 17491 */ 17492 if (fminexc) { 17493 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17494 if (res == -2) 17495 goto internal_error; 17496 if (res == -1) { 17497 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17498 } 17499 } 17500 /* 17501 * "maxExclusive valid restriction" 17502 */ 17503 if (bfmaxexc) { 17504 /* maxExclusive <= BASE maxExclusive */ 17505 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17506 if (res == -2) 17507 goto internal_error; 17508 if (res == 1) { 17509 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17510 } 17511 if ((res != 0) && (bfmaxexc->fixed)) { 17512 FACET_RESTR_FIXED_ERR(fmaxexc) 17513 } 17514 } 17515 if (bfmaxinc) { 17516 /* maxExclusive <= BASE maxInclusive */ 17517 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17518 if (res == -2) 17519 goto internal_error; 17520 if (res == 1) { 17521 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17522 } 17523 } 17524 if (bfmininc) { 17525 /* maxExclusive > BASE minInclusive */ 17526 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17527 if (res == -2) 17528 goto internal_error; 17529 if (res != 1) { 17530 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17531 } 17532 } 17533 if (bfminexc) { 17534 /* maxExclusive > BASE minExclusive */ 17535 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17536 if (res == -2) 17537 goto internal_error; 17538 if (res != 1) { 17539 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17540 } 17541 } 17542 } 17543 if (fminexc) { 17544 /* 17545 * "minExclusive < maxInclusive" 17546 */ 17547 if (fmaxinc) { 17548 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17549 if (res == -2) 17550 goto internal_error; 17551 if (res != -1) { 17552 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17553 } 17554 } 17555 /* 17556 * "minExclusive valid restriction" 17557 */ 17558 if (bfminexc) { 17559 /* minExclusive >= BASE minExclusive */ 17560 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17561 if (res == -2) 17562 goto internal_error; 17563 if (res == -1) { 17564 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17565 } 17566 if ((res != 0) && (bfminexc->fixed)) { 17567 FACET_RESTR_FIXED_ERR(fminexc) 17568 } 17569 } 17570 if (bfmaxinc) { 17571 /* minExclusive <= BASE maxInclusive */ 17572 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17573 if (res == -2) 17574 goto internal_error; 17575 if (res == 1) { 17576 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17577 } 17578 } 17579 if (bfmininc) { 17580 /* minExclusive >= BASE minInclusive */ 17581 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17582 if (res == -2) 17583 goto internal_error; 17584 if (res == -1) { 17585 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17586 } 17587 } 17588 if (bfmaxexc) { 17589 /* minExclusive < BASE maxExclusive */ 17590 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17591 if (res == -2) 17592 goto internal_error; 17593 if (res != -1) { 17594 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17595 } 17596 } 17597 } 17598 if (fmininc) { 17599 /* 17600 * "minInclusive < maxExclusive" 17601 */ 17602 if (fmaxexc) { 17603 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17604 if (res == -2) 17605 goto internal_error; 17606 if (res != -1) { 17607 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17608 } 17609 } 17610 /* 17611 * "minExclusive valid restriction" 17612 */ 17613 if (bfmininc) { 17614 /* minInclusive >= BASE minInclusive */ 17615 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17616 if (res == -2) 17617 goto internal_error; 17618 if (res == -1) { 17619 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17620 } 17621 if ((res != 0) && (bfmininc->fixed)) { 17622 FACET_RESTR_FIXED_ERR(fmininc) 17623 } 17624 } 17625 if (bfmaxinc) { 17626 /* minInclusive <= BASE maxInclusive */ 17627 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17628 if (res == -2) 17629 goto internal_error; 17630 if (res == 1) { 17631 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17632 } 17633 } 17634 if (bfminexc) { 17635 /* minInclusive > BASE minExclusive */ 17636 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17637 if (res == -2) 17638 goto internal_error; 17639 if (res != 1) 17640 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17641 } 17642 if (bfmaxexc) { 17643 /* minInclusive < BASE maxExclusive */ 17644 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17645 if (res == -2) 17646 goto internal_error; 17647 if (res != -1) 17648 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17649 } 17650 } 17651 if (ftotdig && bftotdig) { 17652 /* 17653 * SCC " totalDigits valid restriction" 17654 * totalDigits <= BASE totalDigits 17655 */ 17656 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17657 if (res == -2) 17658 goto internal_error; 17659 if (res == 1) 17660 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17661 -1, 1, 1); 17662 if ((res != 0) && (bftotdig->fixed)) { 17663 FACET_RESTR_FIXED_ERR(ftotdig) 17664 } 17665 } 17666 if (ffracdig && bffracdig) { 17667 /* 17668 * SCC "fractionDigits valid restriction" 17669 * fractionDigits <= BASE fractionDigits 17670 */ 17671 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17672 if (res == -2) 17673 goto internal_error; 17674 if (res == 1) 17675 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17676 -1, 1, 1); 17677 if ((res != 0) && (bffracdig->fixed)) { 17678 FACET_RESTR_FIXED_ERR(ffracdig) 17679 } 17680 } 17681 /* 17682 * SCC "fractionDigits less than or equal to totalDigits" 17683 */ 17684 if (! ftotdig) 17685 ftotdig = bftotdig; 17686 if (! ffracdig) 17687 ffracdig = bffracdig; 17688 if (ftotdig && ffracdig) { 17689 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17690 if (res == -2) 17691 goto internal_error; 17692 if (res == 1) 17693 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17694 -1, 1, 0); 17695 } 17696 /* 17697 * *Enumerations* won' be added here, since only the first set 17698 * of enumerations in the ancestor-or-self axis is used 17699 * for validation, plus we need to use the base type of those 17700 * enumerations for whitespace. 17701 * 17702 * *Patterns*: won't be add here, since they are ORed at 17703 * type level and ANDed at ancestor level. This will 17704 * happen during validation by walking the base axis 17705 * of the type. 17706 */ 17707 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17708 bfacet = cur->facet; 17709 /* 17710 * Special handling of enumerations and patterns. 17711 * TODO: hmm, they should not appear in the set, so remove this. 17712 */ 17713 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17714 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17715 continue; 17716 /* 17717 * Search for a duplicate facet in the current type. 17718 */ 17719 link = type->facetSet; 17720 /* err = 0; */ 17721 /* fixedErr = 0; */ 17722 while (link != NULL) { 17723 facet = link->facet; 17724 if (facet->type == bfacet->type) { 17725 switch (facet->type) { 17726 case XML_SCHEMA_FACET_WHITESPACE: 17727 /* 17728 * The whitespace must be stronger. 17729 */ 17730 if (facet->whitespace < bfacet->whitespace) { 17731 FACET_RESTR_ERR(facet, 17732 "The 'whitespace' value has to be equal to " 17733 "or stronger than the 'whitespace' value of " 17734 "the base type") 17735 } 17736 if ((bfacet->fixed) && 17737 (facet->whitespace != bfacet->whitespace)) { 17738 FACET_RESTR_FIXED_ERR(facet) 17739 } 17740 break; 17741 default: 17742 break; 17743 } 17744 /* Duplicate found. */ 17745 break; 17746 } 17747 link = link->next; 17748 } 17749 /* 17750 * If no duplicate was found: add the base types's facet 17751 * to the set. 17752 */ 17753 if (link == NULL) { 17754 link = (xmlSchemaFacetLinkPtr) 17755 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17756 if (link == NULL) { 17757 xmlSchemaPErrMemory(pctxt, 17758 "deriving facets, creating a facet link", NULL); 17759 return (-1); 17760 } 17761 link->facet = cur->facet; 17762 link->next = NULL; 17763 if (last == NULL) 17764 type->facetSet = link; 17765 else 17766 last->next = link; 17767 last = link; 17768 } 17769 17770 } 17771 17772 return (0); 17773 internal_error: 17774 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17775 "an error occurred"); 17776 return (-1); 17777 } 17778 17779 static int 17780 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17781 xmlSchemaTypePtr type) 17782 { 17783 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17784 /* 17785 * The actual value is then formed by replacing any union type 17786 * definition in the `explicit members` with the members of their 17787 * {member type definitions}, in order. 17788 * 17789 * TODO: There's a bug entry at 17790 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17791 * which indicates that we'll keep the union types the future. 17792 */ 17793 link = type->memberTypes; 17794 while (link != NULL) { 17795 17796 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17797 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17798 17799 if (WXS_IS_UNION(link->type)) { 17800 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17801 if (subLink != NULL) { 17802 link->type = subLink->type; 17803 if (subLink->next != NULL) { 17804 lastLink = link->next; 17805 subLink = subLink->next; 17806 prevLink = link; 17807 while (subLink != NULL) { 17808 newLink = (xmlSchemaTypeLinkPtr) 17809 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17810 if (newLink == NULL) { 17811 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17812 NULL); 17813 return (-1); 17814 } 17815 newLink->type = subLink->type; 17816 prevLink->next = newLink; 17817 prevLink = newLink; 17818 newLink->next = lastLink; 17819 17820 subLink = subLink->next; 17821 } 17822 } 17823 } 17824 } 17825 link = link->next; 17826 } 17827 return (0); 17828 } 17829 17830 static void 17831 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17832 { 17833 int has = 0, needVal = 0, normVal = 0; 17834 17835 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17836 if (has) { 17837 needVal = (type->baseType->flags & 17838 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17839 normVal = (type->baseType->flags & 17840 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17841 } 17842 if (type->facets != NULL) { 17843 xmlSchemaFacetPtr fac; 17844 17845 for (fac = type->facets; fac != NULL; fac = fac->next) { 17846 switch (fac->type) { 17847 case XML_SCHEMA_FACET_WHITESPACE: 17848 break; 17849 case XML_SCHEMA_FACET_PATTERN: 17850 normVal = 1; 17851 has = 1; 17852 break; 17853 case XML_SCHEMA_FACET_ENUMERATION: 17854 needVal = 1; 17855 normVal = 1; 17856 has = 1; 17857 break; 17858 default: 17859 has = 1; 17860 break; 17861 } 17862 } 17863 } 17864 if (normVal) 17865 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17866 if (needVal) 17867 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17868 if (has) 17869 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17870 17871 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17872 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17873 /* 17874 * OPTIMIZE VAL TODO: Some facets need a computed value. 17875 */ 17876 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17877 (prim->builtInType != XML_SCHEMAS_STRING)) { 17878 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17879 } 17880 } 17881 } 17882 17883 static int 17884 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17885 { 17886 17887 17888 /* 17889 * Evaluate the whitespace-facet value. 17890 */ 17891 if (WXS_IS_LIST(type)) { 17892 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17893 return (0); 17894 } else if (WXS_IS_UNION(type)) 17895 return (0); 17896 17897 if (type->facetSet != NULL) { 17898 xmlSchemaFacetLinkPtr lin; 17899 17900 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17901 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17902 switch (lin->facet->whitespace) { 17903 case XML_SCHEMAS_FACET_PRESERVE: 17904 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17905 break; 17906 case XML_SCHEMAS_FACET_REPLACE: 17907 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17908 break; 17909 case XML_SCHEMAS_FACET_COLLAPSE: 17910 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17911 break; 17912 default: 17913 return (-1); 17914 } 17915 return (0); 17916 } 17917 } 17918 } 17919 /* 17920 * For all `atomic` datatypes other than string (and types `derived` 17921 * by `restriction` from it) the value of whiteSpace is fixed to 17922 * collapse 17923 */ 17924 { 17925 xmlSchemaTypePtr anc; 17926 17927 for (anc = type->baseType; anc != NULL && 17928 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17929 anc = anc->baseType) { 17930 17931 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17932 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17933 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17934 17935 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17936 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17937 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17938 17939 } else 17940 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17941 break; 17942 } 17943 } 17944 } 17945 return (0); 17946 } 17947 17948 static int 17949 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17950 xmlSchemaTypePtr type) 17951 { 17952 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17953 return(0); 17954 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17955 return(0); 17956 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17957 17958 if (WXS_IS_LIST(type)) { 17959 /* 17960 * Corresponds to <simpleType><list>... 17961 */ 17962 if (type->subtypes == NULL) { 17963 /* 17964 * This one is really needed, so get out. 17965 */ 17966 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17967 "list type has no item-type assigned"); 17968 return(-1); 17969 } 17970 } else if (WXS_IS_UNION(type)) { 17971 /* 17972 * Corresponds to <simpleType><union>... 17973 */ 17974 if (type->memberTypes == NULL) { 17975 /* 17976 * This one is really needed, so get out. 17977 */ 17978 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17979 "union type has no member-types assigned"); 17980 return(-1); 17981 } 17982 } else { 17983 /* 17984 * Corresponds to <simpleType><restriction>... 17985 */ 17986 if (type->baseType == NULL) { 17987 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17988 "type has no base-type assigned"); 17989 return(-1); 17990 } 17991 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17992 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17993 return(-1); 17994 /* 17995 * Variety 17996 * If the <restriction> alternative is chosen, then the 17997 * {variety} of the {base type definition}. 17998 */ 17999 if (WXS_IS_ATOMIC(type->baseType)) 18000 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 18001 else if (WXS_IS_LIST(type->baseType)) { 18002 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 18003 /* 18004 * Inherit the itemType. 18005 */ 18006 type->subtypes = type->baseType->subtypes; 18007 } else if (WXS_IS_UNION(type->baseType)) { 18008 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 18009 /* 18010 * NOTE that we won't assign the memberTypes of the base, 18011 * since this will make trouble when freeing them; we will 18012 * use a lookup function to access them instead. 18013 */ 18014 } 18015 } 18016 return(0); 18017 } 18018 18019 #ifdef DEBUG_TYPE 18020 static void 18021 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18022 xmlSchemaTypePtr type) 18023 { 18024 if (type->node != NULL) { 18025 xmlGenericError(xmlGenericErrorContext, 18026 "Type of %s : %s:%d :", name, 18027 type->node->doc->URL, 18028 xmlGetLineNo(type->node)); 18029 } else { 18030 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18031 } 18032 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18033 switch (type->contentType) { 18034 case XML_SCHEMA_CONTENT_SIMPLE: 18035 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18036 break; 18037 case XML_SCHEMA_CONTENT_ELEMENTS: 18038 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18039 break; 18040 case XML_SCHEMA_CONTENT_UNKNOWN: 18041 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18042 break; 18043 case XML_SCHEMA_CONTENT_EMPTY: 18044 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18045 break; 18046 case XML_SCHEMA_CONTENT_MIXED: 18047 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18048 type->subtypes)) 18049 xmlGenericError(xmlGenericErrorContext, 18050 "mixed as emptiable particle\n"); 18051 else 18052 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18053 break; 18054 /* Removed, since not used. */ 18055 /* 18056 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18057 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18058 break; 18059 */ 18060 case XML_SCHEMA_CONTENT_BASIC: 18061 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18062 break; 18063 default: 18064 xmlGenericError(xmlGenericErrorContext, 18065 "not registered !!!\n"); 18066 break; 18067 } 18068 } 18069 } 18070 #endif 18071 18072 /* 18073 * 3.14.6 Constraints on Simple Type Definition Schema Components 18074 */ 18075 static int 18076 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18077 xmlSchemaTypePtr type) 18078 { 18079 int res, olderrs = pctxt->nberrors; 18080 18081 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18082 return(-1); 18083 18084 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18085 return(0); 18086 18087 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18088 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18089 18090 if (type->baseType == NULL) { 18091 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18092 "missing baseType"); 18093 goto exit_failure; 18094 } 18095 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18096 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18097 /* 18098 * If a member type of a union is a union itself, we need to substitute 18099 * that member type for its member types. 18100 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18101 * types in WXS 1.1. 18102 */ 18103 if ((type->memberTypes != NULL) && 18104 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18105 return(-1); 18106 /* 18107 * SPEC src-simple-type 1 18108 * "The corresponding simple type definition, if any, must satisfy 18109 * the conditions set out in Constraints on Simple Type Definition 18110 * Schema Components ($3.14.6)." 18111 */ 18112 /* 18113 * Schema Component Constraint: Simple Type Definition Properties Correct 18114 * (st-props-correct) 18115 */ 18116 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18117 HFAILURE HERROR 18118 /* 18119 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18120 * (cos-st-restricts) 18121 */ 18122 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18123 HFAILURE HERROR 18124 /* 18125 * TODO: Removed the error report, since it got annoying to get an 18126 * extra error report, if anything failed until now. 18127 * Enable this if needed. 18128 * 18129 * xmlSchemaPErr(ctxt, type->node, 18130 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18131 * "Simple type '%s' does not satisfy the constraints " 18132 * "on simple type definitions.\n", 18133 * type->name, NULL); 18134 */ 18135 /* 18136 * Schema Component Constraint: Simple Type Restriction (Facets) 18137 * (st-restrict-facets) 18138 */ 18139 res = xmlSchemaCheckFacetValues(type, pctxt); 18140 HFAILURE HERROR 18141 if ((type->facetSet != NULL) || 18142 (type->baseType->facetSet != NULL)) { 18143 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18144 HFAILURE HERROR 18145 } 18146 /* 18147 * Whitespace value. 18148 */ 18149 res = xmlSchemaTypeFixupWhitespace(type); 18150 HFAILURE HERROR 18151 xmlSchemaTypeFixupOptimFacets(type); 18152 18153 exit_error: 18154 #ifdef DEBUG_TYPE 18155 xmlSchemaDebugFixedType(pctxt, type); 18156 #endif 18157 if (olderrs != pctxt->nberrors) 18158 return(pctxt->err); 18159 return(0); 18160 18161 exit_failure: 18162 #ifdef DEBUG_TYPE 18163 xmlSchemaDebugFixedType(pctxt, type); 18164 #endif 18165 return(-1); 18166 } 18167 18168 static int 18169 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18170 xmlSchemaTypePtr type) 18171 { 18172 int res = 0, olderrs = pctxt->nberrors; 18173 xmlSchemaTypePtr baseType = type->baseType; 18174 18175 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18176 return(0); 18177 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18178 if (baseType == NULL) { 18179 PERROR_INT("xmlSchemaFixupComplexType", 18180 "missing baseType"); 18181 goto exit_failure; 18182 } 18183 /* 18184 * Fixup the base type. 18185 */ 18186 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18187 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18188 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18189 /* 18190 * Skip fixup if the base type is invalid. 18191 * TODO: Generate a warning! 18192 */ 18193 return(0); 18194 } 18195 /* 18196 * This basically checks if the base type can be derived. 18197 */ 18198 res = xmlSchemaCheckSRCCT(pctxt, type); 18199 HFAILURE HERROR 18200 /* 18201 * Fixup the content type. 18202 */ 18203 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18204 /* 18205 * Corresponds to <complexType><simpleContent>... 18206 */ 18207 if ((WXS_IS_COMPLEX(baseType)) && 18208 (baseType->contentTypeDef != NULL) && 18209 (WXS_IS_RESTRICTION(type))) { 18210 xmlSchemaTypePtr contentBase, content; 18211 #ifdef ENABLE_NAMED_LOCALS 18212 char buf[30]; 18213 const xmlChar *tmpname; 18214 #endif 18215 /* 18216 * SPEC (1) If <restriction> + base type is <complexType>, 18217 * "whose own {content type} is a simple type..." 18218 */ 18219 if (type->contentTypeDef != NULL) { 18220 /* 18221 * SPEC (1.1) "the simple type definition corresponding to the 18222 * <simpleType> among the [children] of <restriction> if there 18223 * is one;" 18224 * Note that this "<simpleType> among the [children]" was put 18225 * into ->contentTypeDef during parsing. 18226 */ 18227 contentBase = type->contentTypeDef; 18228 type->contentTypeDef = NULL; 18229 } else { 18230 /* 18231 * (1.2) "...otherwise (<restriction> has no <simpleType> 18232 * among its [children]), the simple type definition which 18233 * is the {content type} of the ... base type." 18234 */ 18235 contentBase = baseType->contentTypeDef; 18236 } 18237 /* 18238 * SPEC 18239 * "... a simple type definition which restricts the simple 18240 * type definition identified in clause 1.1 or clause 1.2 18241 * with a set of facet components" 18242 * 18243 * Create the anonymous simple type, which will be the content 18244 * type of the complex type. 18245 */ 18246 #ifdef ENABLE_NAMED_LOCALS 18247 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18248 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18249 content = xmlSchemaAddType(pctxt, pctxt->schema, 18250 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18251 type->node, 0); 18252 #else 18253 content = xmlSchemaAddType(pctxt, pctxt->schema, 18254 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18255 type->node, 0); 18256 #endif 18257 if (content == NULL) 18258 goto exit_failure; 18259 /* 18260 * We will use the same node as for the <complexType> 18261 * to have it somehow anchored in the schema doc. 18262 */ 18263 content->type = XML_SCHEMA_TYPE_SIMPLE; 18264 content->baseType = contentBase; 18265 /* 18266 * Move the facets, previously anchored on the 18267 * complexType during parsing. 18268 */ 18269 content->facets = type->facets; 18270 type->facets = NULL; 18271 content->facetSet = type->facetSet; 18272 type->facetSet = NULL; 18273 18274 type->contentTypeDef = content; 18275 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18276 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18277 /* 18278 * Fixup the newly created type. We don't need to check 18279 * for circularity here. 18280 */ 18281 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18282 HFAILURE HERROR 18283 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18284 HFAILURE HERROR 18285 18286 } else if ((WXS_IS_COMPLEX(baseType)) && 18287 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18288 (WXS_IS_RESTRICTION(type))) { 18289 /* 18290 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18291 * an emptiable particle, then a simple type definition which 18292 * restricts the <restriction>'s <simpleType> child. 18293 */ 18294 if ((type->contentTypeDef == NULL) || 18295 (type->contentTypeDef->baseType == NULL)) { 18296 /* 18297 * TODO: Check if this ever happens. 18298 */ 18299 xmlSchemaPCustomErr(pctxt, 18300 XML_SCHEMAP_INTERNAL, 18301 WXS_BASIC_CAST type, NULL, 18302 "Internal error: xmlSchemaTypeFixup, " 18303 "complex type '%s': the <simpleContent><restriction> " 18304 "is missing a <simpleType> child, but was not caught " 18305 "by xmlSchemaCheckSRCCT()", type->name); 18306 goto exit_failure; 18307 } 18308 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18309 /* 18310 * SPEC (3) If <extension> + base is <complexType> with 18311 * <simpleType> content, "...then the {content type} of that 18312 * complex type definition" 18313 */ 18314 if (baseType->contentTypeDef == NULL) { 18315 /* 18316 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18317 * should have caught this already. 18318 */ 18319 xmlSchemaPCustomErr(pctxt, 18320 XML_SCHEMAP_INTERNAL, 18321 WXS_BASIC_CAST type, NULL, 18322 "Internal error: xmlSchemaTypeFixup, " 18323 "complex type '%s': the <extension>ed base type is " 18324 "a complex type with no simple content type", 18325 type->name); 18326 goto exit_failure; 18327 } 18328 type->contentTypeDef = baseType->contentTypeDef; 18329 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18330 /* 18331 * SPEC (4) <extension> + base is <simpleType> 18332 * "... then that simple type definition" 18333 */ 18334 type->contentTypeDef = baseType; 18335 } else { 18336 /* 18337 * TODO: Check if this ever happens. 18338 */ 18339 xmlSchemaPCustomErr(pctxt, 18340 XML_SCHEMAP_INTERNAL, 18341 WXS_BASIC_CAST type, NULL, 18342 "Internal error: xmlSchemaTypeFixup, " 18343 "complex type '%s' with <simpleContent>: unhandled " 18344 "derivation case", type->name); 18345 goto exit_failure; 18346 } 18347 } else { 18348 int dummySequence = 0; 18349 xmlSchemaParticlePtr particle = 18350 (xmlSchemaParticlePtr) type->subtypes; 18351 /* 18352 * Corresponds to <complexType><complexContent>... 18353 * 18354 * NOTE that the effective mixed was already set during parsing of 18355 * <complexType> and <complexContent>; its flag value is 18356 * XML_SCHEMAS_TYPE_MIXED. 18357 * 18358 * Compute the "effective content": 18359 * (2.1.1) + (2.1.2) + (2.1.3) 18360 */ 18361 if ((particle == NULL) || 18362 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18363 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18364 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18365 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18366 (particle->minOccurs == 0))) && 18367 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18368 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18369 /* 18370 * SPEC (2.1.4) "If the `effective mixed` is true, then 18371 * a particle whose properties are as follows:..." 18372 * 18373 * Empty sequence model group with 18374 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18375 * NOTE that we sill assign it the <complexType> node to 18376 * somehow anchor it in the doc. 18377 */ 18378 if ((particle == NULL) || 18379 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18380 /* 18381 * Create the particle. 18382 */ 18383 particle = xmlSchemaAddParticle(pctxt, 18384 type->node, 1, 1); 18385 if (particle == NULL) 18386 goto exit_failure; 18387 /* 18388 * Create the model group. 18389 */ /* URGENT TODO: avoid adding to pending items. */ 18390 particle->children = (xmlSchemaTreeItemPtr) 18391 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18392 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18393 if (particle->children == NULL) 18394 goto exit_failure; 18395 18396 type->subtypes = (xmlSchemaTypePtr) particle; 18397 } 18398 dummySequence = 1; 18399 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18400 } else { 18401 /* 18402 * SPEC (2.1.5) "otherwise empty" 18403 */ 18404 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18405 } 18406 } else { 18407 /* 18408 * SPEC (2.2) "otherwise the particle corresponding to the 18409 * <all>, <choice>, <group> or <sequence> among the 18410 * [children]." 18411 */ 18412 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18413 } 18414 /* 18415 * Compute the "content type". 18416 */ 18417 if (WXS_IS_RESTRICTION(type)) { 18418 /* 18419 * SPEC (3.1) "If <restriction>..." 18420 * (3.1.1) + (3.1.2) */ 18421 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18422 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18423 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18424 } 18425 } else { 18426 /* 18427 * SPEC (3.2) "If <extension>..." 18428 */ 18429 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18430 /* 18431 * SPEC (3.2.1) 18432 * "If the `effective content` is empty, then the 18433 * {content type} of the [...] base ..." 18434 */ 18435 type->contentType = baseType->contentType; 18436 type->subtypes = baseType->subtypes; 18437 /* 18438 * Fixes bug #347316: 18439 * This is the case when the base type has a simple 18440 * type definition as content. 18441 */ 18442 type->contentTypeDef = baseType->contentTypeDef; 18443 /* 18444 * NOTE that the effective mixed is ignored here. 18445 */ 18446 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18447 /* 18448 * SPEC (3.2.2) 18449 */ 18450 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18451 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18452 } else { 18453 /* 18454 * SPEC (3.2.3) 18455 */ 18456 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18457 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18458 /* 18459 * "A model group whose {compositor} is sequence and whose 18460 * {particles} are..." 18461 */ 18462 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18463 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18464 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18465 XML_SCHEMA_TYPE_ALL)) 18466 { 18467 /* 18468 * SPEC cos-all-limited (1) 18469 */ 18470 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18471 /* TODO: error code */ 18472 XML_SCHEMAP_COS_ALL_LIMITED, 18473 WXS_ITEM_NODE(type), NULL, 18474 "The type has an 'all' model group in its " 18475 "{content type} and thus cannot be derived from " 18476 "a non-empty type, since this would produce a " 18477 "'sequence' model group containing the 'all' " 18478 "model group; 'all' model groups are not " 18479 "allowed to appear inside other model groups", 18480 NULL, NULL); 18481 18482 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18483 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18484 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18485 XML_SCHEMA_TYPE_ALL)) 18486 { 18487 /* 18488 * SPEC cos-all-limited (1) 18489 */ 18490 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18491 /* TODO: error code */ 18492 XML_SCHEMAP_COS_ALL_LIMITED, 18493 WXS_ITEM_NODE(type), NULL, 18494 "A type cannot be derived by extension from a type " 18495 "which has an 'all' model group in its " 18496 "{content type}, since this would produce a " 18497 "'sequence' model group containing the 'all' " 18498 "model group; 'all' model groups are not " 18499 "allowed to appear inside other model groups", 18500 NULL, NULL); 18501 18502 } else if (! dummySequence) { 18503 xmlSchemaTreeItemPtr effectiveContent = 18504 (xmlSchemaTreeItemPtr) type->subtypes; 18505 /* 18506 * Create the particle. 18507 */ 18508 particle = xmlSchemaAddParticle(pctxt, 18509 type->node, 1, 1); 18510 if (particle == NULL) 18511 goto exit_failure; 18512 /* 18513 * Create the "sequence" model group. 18514 */ 18515 particle->children = (xmlSchemaTreeItemPtr) 18516 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18517 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18518 if (particle->children == NULL) 18519 goto exit_failure; 18520 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18521 /* 18522 * SPEC "the particle of the {content type} of 18523 * the ... base ..." 18524 * Create a duplicate of the base type's particle 18525 * and assign its "term" to it. 18526 */ 18527 particle->children->children = 18528 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18529 type->node, 18530 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18531 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18532 if (particle->children->children == NULL) 18533 goto exit_failure; 18534 particle = (xmlSchemaParticlePtr) 18535 particle->children->children; 18536 particle->children = 18537 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18538 /* 18539 * SPEC "followed by the `effective content`." 18540 */ 18541 particle->next = effectiveContent; 18542 /* 18543 * This all will result in: 18544 * new-particle 18545 * --> new-sequence( 18546 * new-particle 18547 * --> base-model, 18548 * this-particle 18549 * --> this-model 18550 * ) 18551 */ 18552 } else { 18553 /* 18554 * This is the case when there is already an empty 18555 * <sequence> with minOccurs==maxOccurs==1. 18556 * Just add the base types's content type. 18557 * NOTE that, although we miss to add an intermediate 18558 * <sequence>, this should produce no difference to 18559 * neither the regex compilation of the content model, 18560 * nor to the complex type constraints. 18561 */ 18562 particle->children->children = 18563 (xmlSchemaTreeItemPtr) baseType->subtypes; 18564 } 18565 } 18566 } 18567 } 18568 /* 18569 * Now fixup attribute uses: 18570 * - expand attr. group references 18571 * - intersect attribute wildcards 18572 * - inherit attribute uses of the base type 18573 * - inherit or union attr. wildcards if extending 18574 * - apply attr. use prohibitions if restricting 18575 */ 18576 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18577 HFAILURE HERROR 18578 /* 18579 * Apply the complex type component constraints; this will not 18580 * check attributes, since this is done in 18581 * xmlSchemaFixupTypeAttributeUses(). 18582 */ 18583 res = xmlSchemaCheckCTComponent(pctxt, type); 18584 HFAILURE HERROR 18585 18586 #ifdef DEBUG_TYPE 18587 xmlSchemaDebugFixedType(pctxt, type); 18588 #endif 18589 if (olderrs != pctxt->nberrors) 18590 return(pctxt->err); 18591 else 18592 return(0); 18593 18594 exit_error: 18595 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18596 #ifdef DEBUG_TYPE 18597 xmlSchemaDebugFixedType(pctxt, type); 18598 #endif 18599 return(pctxt->err); 18600 18601 exit_failure: 18602 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18603 #ifdef DEBUG_TYPE 18604 xmlSchemaDebugFixedType(pctxt, type); 18605 #endif 18606 return(-1); 18607 } 18608 18609 18610 /** 18611 * xmlSchemaTypeFixup: 18612 * @typeDecl: the schema type definition 18613 * @ctxt: the schema parser context 18614 * 18615 * Fixes the content model of the type. 18616 * URGENT TODO: We need an int result! 18617 */ 18618 static int 18619 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18620 xmlSchemaAbstractCtxtPtr actxt) 18621 { 18622 if (type == NULL) 18623 return(0); 18624 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18625 AERROR_INT("xmlSchemaTypeFixup", 18626 "this function needs a parser context"); 18627 return(-1); 18628 } 18629 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18630 return(0); 18631 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18632 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18633 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18634 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18635 return(0); 18636 } 18637 18638 /** 18639 * xmlSchemaCheckFacet: 18640 * @facet: the facet 18641 * @typeDecl: the schema type definition 18642 * @pctxt: the schema parser context or NULL 18643 * @name: the optional name of the type 18644 * 18645 * Checks and computes the values of facets. 18646 * 18647 * Returns 0 if valid, a positive error code if not valid and 18648 * -1 in case of an internal or API error. 18649 */ 18650 int 18651 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18652 xmlSchemaTypePtr typeDecl, 18653 xmlSchemaParserCtxtPtr pctxt, 18654 const xmlChar * name ATTRIBUTE_UNUSED) 18655 { 18656 int ret = 0, ctxtGiven; 18657 18658 if ((facet == NULL) || (typeDecl == NULL)) 18659 return(-1); 18660 /* 18661 * TODO: will the parser context be given if used from 18662 * the relaxNG module? 18663 */ 18664 if (pctxt == NULL) 18665 ctxtGiven = 0; 18666 else 18667 ctxtGiven = 1; 18668 18669 switch (facet->type) { 18670 case XML_SCHEMA_FACET_MININCLUSIVE: 18671 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18672 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18673 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18674 case XML_SCHEMA_FACET_ENUMERATION: { 18675 /* 18676 * Okay we need to validate the value 18677 * at that point. 18678 */ 18679 xmlSchemaTypePtr base; 18680 18681 /* 4.3.5.5 Constraints on enumeration Schema Components 18682 * Schema Component Constraint: enumeration valid restriction 18683 * It is an `error` if any member of {value} is not in the 18684 * `value space` of {base type definition}. 18685 * 18686 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18687 * The value `must` be in the 18688 * `value space` of the `base type`. 18689 */ 18690 /* 18691 * This function is intended to deliver a compiled value 18692 * on the facet. In this implementation of XML Schemata the 18693 * type holding a facet, won't be a built-in type. 18694 * Thus to ensure that other API 18695 * calls (relaxng) do work, if the given type is a built-in 18696 * type, we will assume that the given built-in type *is 18697 * already* the base type. 18698 */ 18699 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18700 base = typeDecl->baseType; 18701 if (base == NULL) { 18702 PERROR_INT("xmlSchemaCheckFacet", 18703 "a type user derived type has no base type"); 18704 return (-1); 18705 } 18706 } else 18707 base = typeDecl; 18708 18709 if (! ctxtGiven) { 18710 /* 18711 * A context is needed if called from RelaxNG. 18712 */ 18713 pctxt = xmlSchemaNewParserCtxt("*"); 18714 if (pctxt == NULL) 18715 return (-1); 18716 } 18717 /* 18718 * NOTE: This call does not check the content nodes, 18719 * since they are not available: 18720 * facet->node is just the node holding the facet 18721 * definition, *not* the attribute holding the *value* 18722 * of the facet. 18723 */ 18724 ret = xmlSchemaVCheckCVCSimpleType( 18725 ACTXT_CAST pctxt, facet->node, base, 18726 facet->value, &(facet->val), 1, 1, 0); 18727 if (ret != 0) { 18728 if (ret < 0) { 18729 /* No error message for RelaxNG. */ 18730 if (ctxtGiven) { 18731 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18732 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18733 "Internal error: xmlSchemaCheckFacet, " 18734 "failed to validate the value '%s' of the " 18735 "facet '%s' against the base type", 18736 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18737 } 18738 goto internal_error; 18739 } 18740 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18741 /* No error message for RelaxNG. */ 18742 if (ctxtGiven) { 18743 xmlChar *str = NULL; 18744 18745 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18746 ret, facet->node, WXS_BASIC_CAST facet, 18747 "The value '%s' of the facet does not validate " 18748 "against the base type '%s'", 18749 facet->value, 18750 xmlSchemaFormatQName(&str, 18751 base->targetNamespace, base->name)); 18752 FREE_AND_NULL(str); 18753 } 18754 goto exit; 18755 } else if (facet->val == NULL) { 18756 if (ctxtGiven) { 18757 PERROR_INT("xmlSchemaCheckFacet", 18758 "value was not computed"); 18759 } 18760 TODO 18761 } 18762 break; 18763 } 18764 case XML_SCHEMA_FACET_PATTERN: 18765 facet->regexp = xmlRegexpCompile(facet->value); 18766 if (facet->regexp == NULL) { 18767 ret = XML_SCHEMAP_REGEXP_INVALID; 18768 /* No error message for RelaxNG. */ 18769 if (ctxtGiven) { 18770 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18771 ret, facet->node, WXS_BASIC_CAST typeDecl, 18772 "The value '%s' of the facet 'pattern' is not a " 18773 "valid regular expression", 18774 facet->value, NULL); 18775 } 18776 } 18777 break; 18778 case XML_SCHEMA_FACET_TOTALDIGITS: 18779 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18780 case XML_SCHEMA_FACET_LENGTH: 18781 case XML_SCHEMA_FACET_MAXLENGTH: 18782 case XML_SCHEMA_FACET_MINLENGTH: 18783 18784 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18785 ret = xmlSchemaValidatePredefinedType( 18786 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18787 facet->value, &(facet->val)); 18788 } else { 18789 ret = xmlSchemaValidatePredefinedType( 18790 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18791 facet->value, &(facet->val)); 18792 } 18793 if (ret != 0) { 18794 if (ret < 0) { 18795 /* No error message for RelaxNG. */ 18796 if (ctxtGiven) { 18797 PERROR_INT("xmlSchemaCheckFacet", 18798 "validating facet value"); 18799 } 18800 goto internal_error; 18801 } 18802 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18803 /* No error message for RelaxNG. */ 18804 if (ctxtGiven) { 18805 /* error code */ 18806 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18807 ret, facet->node, WXS_BASIC_CAST typeDecl, 18808 "The value '%s' of the facet '%s' is not a valid '%s'", 18809 facet->value, 18810 xmlSchemaFacetTypeToString(facet->type), 18811 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18812 BAD_CAST "nonNegativeInteger" : 18813 BAD_CAST "positiveInteger", 18814 NULL); 18815 } 18816 } 18817 break; 18818 18819 case XML_SCHEMA_FACET_WHITESPACE:{ 18820 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18821 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18822 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18823 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18824 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18825 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18826 } else { 18827 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18828 /* No error message for RelaxNG. */ 18829 if (ctxtGiven) { 18830 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18831 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18832 ret, facet->node, WXS_BASIC_CAST typeDecl, 18833 "The value '%s' of the facet 'whitespace' is not " 18834 "valid", facet->value, NULL); 18835 } 18836 } 18837 } 18838 default: 18839 break; 18840 } 18841 exit: 18842 if ((! ctxtGiven) && (pctxt != NULL)) 18843 xmlSchemaFreeParserCtxt(pctxt); 18844 return (ret); 18845 internal_error: 18846 if ((! ctxtGiven) && (pctxt != NULL)) 18847 xmlSchemaFreeParserCtxt(pctxt); 18848 return (-1); 18849 } 18850 18851 /** 18852 * xmlSchemaCheckFacetValues: 18853 * @typeDecl: the schema type definition 18854 * @ctxt: the schema parser context 18855 * 18856 * Checks the default values types, especially for facets 18857 */ 18858 static int 18859 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18860 xmlSchemaParserCtxtPtr pctxt) 18861 { 18862 int res, olderrs = pctxt->nberrors; 18863 const xmlChar *name = typeDecl->name; 18864 /* 18865 * NOTE: It is intended to use the facets list, instead 18866 * of facetSet. 18867 */ 18868 if (typeDecl->facets != NULL) { 18869 xmlSchemaFacetPtr facet = typeDecl->facets; 18870 18871 /* 18872 * Temporarily assign the "schema" to the validation context 18873 * of the parser context. This is needed for NOTATION validation. 18874 */ 18875 if (pctxt->vctxt == NULL) { 18876 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18877 return(-1); 18878 } 18879 pctxt->vctxt->schema = pctxt->schema; 18880 while (facet != NULL) { 18881 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18882 HFAILURE 18883 facet = facet->next; 18884 } 18885 pctxt->vctxt->schema = NULL; 18886 } 18887 if (olderrs != pctxt->nberrors) 18888 return(pctxt->err); 18889 return(0); 18890 exit_failure: 18891 return(-1); 18892 } 18893 18894 /** 18895 * xmlSchemaGetCircModelGrDefRef: 18896 * @ctxtMGroup: the searched model group 18897 * @selfMGroup: the second searched model group 18898 * @particle: the first particle 18899 * 18900 * This one is intended to be used by 18901 * xmlSchemaCheckGroupDefCircular only. 18902 * 18903 * Returns the particle with the circular model group definition reference, 18904 * otherwise NULL. 18905 */ 18906 static xmlSchemaTreeItemPtr 18907 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18908 xmlSchemaTreeItemPtr particle) 18909 { 18910 xmlSchemaTreeItemPtr circ = NULL; 18911 xmlSchemaTreeItemPtr term; 18912 xmlSchemaModelGroupDefPtr gdef; 18913 18914 for (; particle != NULL; particle = particle->next) { 18915 term = particle->children; 18916 if (term == NULL) 18917 continue; 18918 switch (term->type) { 18919 case XML_SCHEMA_TYPE_GROUP: 18920 gdef = (xmlSchemaModelGroupDefPtr) term; 18921 if (gdef == groupDef) 18922 return (particle); 18923 /* 18924 * Mark this model group definition to avoid infinite 18925 * recursion on circular references not yet examined. 18926 */ 18927 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18928 continue; 18929 if (gdef->children != NULL) { 18930 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18931 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18932 gdef->children->children); 18933 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18934 if (circ != NULL) 18935 return (circ); 18936 } 18937 break; 18938 case XML_SCHEMA_TYPE_SEQUENCE: 18939 case XML_SCHEMA_TYPE_CHOICE: 18940 case XML_SCHEMA_TYPE_ALL: 18941 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18942 if (circ != NULL) 18943 return (circ); 18944 break; 18945 default: 18946 break; 18947 } 18948 } 18949 return (NULL); 18950 } 18951 18952 /** 18953 * xmlSchemaCheckGroupDefCircular: 18954 * @item: the model group definition 18955 * @ctxt: the parser context 18956 * @name: the name 18957 * 18958 * Checks for circular references to model group definitions. 18959 */ 18960 static void 18961 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18962 xmlSchemaParserCtxtPtr ctxt) 18963 { 18964 /* 18965 * Schema Component Constraint: Model Group Correct 18966 * 2 Circular groups are disallowed. That is, within the {particles} 18967 * of a group there must not be at any depth a particle whose {term} 18968 * is the group itself. 18969 */ 18970 if ((item == NULL) || 18971 (item->type != XML_SCHEMA_TYPE_GROUP) || 18972 (item->children == NULL)) 18973 return; 18974 { 18975 xmlSchemaTreeItemPtr circ; 18976 18977 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18978 if (circ != NULL) { 18979 xmlChar *str = NULL; 18980 /* 18981 * TODO: The error report is not adequate: this constraint 18982 * is defined for model groups but not definitions, but since 18983 * there cannot be any circular model groups without a model group 18984 * definition (if not using a construction API), we check those 18985 * definitions only. 18986 */ 18987 xmlSchemaPCustomErr(ctxt, 18988 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18989 NULL, WXS_ITEM_NODE(circ), 18990 "Circular reference to the model group definition '%s' " 18991 "defined", xmlSchemaFormatQName(&str, 18992 item->targetNamespace, item->name)); 18993 FREE_AND_NULL(str) 18994 /* 18995 * NOTE: We will cut the reference to avoid further 18996 * confusion of the processor. This is a fatal error. 18997 */ 18998 circ->children = NULL; 18999 } 19000 } 19001 } 19002 19003 /** 19004 * xmlSchemaModelGroupToModelGroupDefFixup: 19005 * @ctxt: the parser context 19006 * @mg: the model group 19007 * 19008 * Assigns the model group of model group definitions to the "term" 19009 * of the referencing particle. 19010 * In xmlSchemaResolveModelGroupParticleReferences the model group 19011 * definitions were assigned to the "term", since needed for the 19012 * circularity check. 19013 * 19014 * Schema Component Constraint: 19015 * All Group Limited (cos-all-limited) (1.2) 19016 */ 19017 static void 19018 xmlSchemaModelGroupToModelGroupDefFixup( 19019 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 19020 xmlSchemaModelGroupPtr mg) 19021 { 19022 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19023 19024 while (particle != NULL) { 19025 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19026 ((WXS_PARTICLE_TERM(particle))->type != 19027 XML_SCHEMA_TYPE_GROUP)) 19028 { 19029 particle = WXS_PTC_CAST particle->next; 19030 continue; 19031 } 19032 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19033 /* 19034 * TODO: Remove the particle. 19035 */ 19036 WXS_PARTICLE_TERM(particle) = NULL; 19037 particle = WXS_PTC_CAST particle->next; 19038 continue; 19039 } 19040 /* 19041 * Assign the model group to the {term} of the particle. 19042 */ 19043 WXS_PARTICLE_TERM(particle) = 19044 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19045 19046 particle = WXS_PTC_CAST particle->next; 19047 } 19048 } 19049 19050 /** 19051 * xmlSchemaCheckAttrGroupCircularRecur: 19052 * @ctxtGr: the searched attribute group 19053 * @attr: the current attribute list to be processed 19054 * 19055 * This one is intended to be used by 19056 * xmlSchemaCheckAttrGroupCircular only. 19057 * 19058 * Returns the circular attribute group reference, otherwise NULL. 19059 */ 19060 static xmlSchemaQNameRefPtr 19061 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19062 xmlSchemaItemListPtr list) 19063 { 19064 xmlSchemaAttributeGroupPtr gr; 19065 xmlSchemaQNameRefPtr ref, circ; 19066 int i; 19067 /* 19068 * We will search for an attribute group reference which 19069 * references the context attribute group. 19070 */ 19071 for (i = 0; i < list->nbItems; i++) { 19072 ref = list->items[i]; 19073 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19074 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19075 (ref->item != NULL)) 19076 { 19077 gr = WXS_ATTR_GROUP_CAST ref->item; 19078 if (gr == ctxtGr) 19079 return(ref); 19080 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19081 continue; 19082 /* 19083 * Mark as visited to avoid infinite recursion on 19084 * circular references not yet examined. 19085 */ 19086 if ((gr->attrUses) && 19087 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19088 { 19089 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19090 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19091 (xmlSchemaItemListPtr) gr->attrUses); 19092 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19093 if (circ != NULL) 19094 return (circ); 19095 } 19096 19097 } 19098 } 19099 return (NULL); 19100 } 19101 19102 /** 19103 * xmlSchemaCheckAttrGroupCircular: 19104 * attrGr: the attribute group definition 19105 * @ctxt: the parser context 19106 * @name: the name 19107 * 19108 * Checks for circular references of attribute groups. 19109 */ 19110 static int 19111 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19112 xmlSchemaParserCtxtPtr ctxt) 19113 { 19114 /* 19115 * Schema Representation Constraint: 19116 * Attribute Group Definition Representation OK 19117 * 3 Circular group reference is disallowed outside <redefine>. 19118 * That is, unless this element information item's parent is 19119 * <redefine>, then among the [children], if any, there must 19120 * not be an <attributeGroup> with ref [attribute] which resolves 19121 * to the component corresponding to this <attributeGroup>. Indirect 19122 * circularity is also ruled out. That is, when QName resolution 19123 * (Schema Document) ($3.15.3) is applied to a `QName` arising from 19124 * any <attributeGroup>s with a ref [attribute] among the [children], 19125 * it must not be the case that a `QName` is encountered at any depth 19126 * which resolves to the component corresponding to this <attributeGroup>. 19127 */ 19128 if (attrGr->attrUses == NULL) 19129 return(0); 19130 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19131 return(0); 19132 else { 19133 xmlSchemaQNameRefPtr circ; 19134 19135 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19136 (xmlSchemaItemListPtr) attrGr->attrUses); 19137 if (circ != NULL) { 19138 xmlChar *str = NULL; 19139 /* 19140 * TODO: Report the referenced attr group as QName. 19141 */ 19142 xmlSchemaPCustomErr(ctxt, 19143 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19144 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19145 "Circular reference to the attribute group '%s' " 19146 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19147 FREE_AND_NULL(str); 19148 /* 19149 * NOTE: We will cut the reference to avoid further 19150 * confusion of the processor. 19151 * BADSPEC TODO: The spec should define how to process in this case. 19152 */ 19153 circ->item = NULL; 19154 return(ctxt->err); 19155 } 19156 } 19157 return(0); 19158 } 19159 19160 static int 19161 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19162 xmlSchemaAttributeGroupPtr attrGr); 19163 19164 /** 19165 * xmlSchemaExpandAttributeGroupRefs: 19166 * @pctxt: the parser context 19167 * @node: the node of the component holding the attribute uses 19168 * @completeWild: the intersected wildcard to be returned 19169 * @list: the attribute uses 19170 * 19171 * Substitutes contained attribute group references 19172 * for their attribute uses. Wildcards are intersected. 19173 * Attribute use prohibitions are removed from the list 19174 * and returned via the @prohibs list. 19175 * Pointlessness of attr. prohibs, if a matching attr. decl 19176 * is existent a well, are checked. 19177 */ 19178 static int 19179 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19180 xmlSchemaBasicItemPtr item, 19181 xmlSchemaWildcardPtr *completeWild, 19182 xmlSchemaItemListPtr list, 19183 xmlSchemaItemListPtr prohibs) 19184 { 19185 xmlSchemaAttributeGroupPtr gr; 19186 xmlSchemaAttributeUsePtr use; 19187 xmlSchemaItemListPtr sublist; 19188 int i, j; 19189 int created = (*completeWild == NULL) ? 0 : 1; 19190 19191 if (prohibs) 19192 prohibs->nbItems = 0; 19193 19194 for (i = 0; i < list->nbItems; i++) { 19195 use = list->items[i]; 19196 19197 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19198 if (prohibs == NULL) { 19199 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19200 "unexpected attr prohibition found"); 19201 return(-1); 19202 } 19203 /* 19204 * Remove from attribute uses. 19205 */ 19206 if (xmlSchemaItemListRemove(list, i) == -1) 19207 return(-1); 19208 i--; 19209 /* 19210 * Note that duplicate prohibitions were already 19211 * handled at parsing time. 19212 */ 19213 /* 19214 * Add to list of prohibitions. 19215 */ 19216 xmlSchemaItemListAddSize(prohibs, 2, use); 19217 continue; 19218 } 19219 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19220 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19221 { 19222 if ((WXS_QNAME_CAST use)->item == NULL) 19223 return(-1); 19224 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19225 /* 19226 * Expand the referenced attr. group. 19227 * TODO: remove this, this is done in a previous step, so 19228 * already done here. 19229 */ 19230 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19231 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19232 return(-1); 19233 } 19234 /* 19235 * Build the 'complete' wildcard; i.e. intersect multiple 19236 * wildcards. 19237 */ 19238 if (gr->attributeWildcard != NULL) { 19239 if (*completeWild == NULL) { 19240 *completeWild = gr->attributeWildcard; 19241 } else { 19242 if (! created) { 19243 xmlSchemaWildcardPtr tmpWild; 19244 19245 /* 19246 * Copy the first encountered wildcard as context, 19247 * except for the annotation. 19248 * 19249 * Although the complete wildcard might not correspond 19250 * to any node in the schema, we will anchor it on 19251 * the node of the owner component. 19252 */ 19253 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19254 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19255 WXS_ITEM_NODE(item)); 19256 if (tmpWild == NULL) 19257 return(-1); 19258 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19259 tmpWild, *completeWild) == -1) 19260 return (-1); 19261 tmpWild->processContents = (*completeWild)->processContents; 19262 *completeWild = tmpWild; 19263 created = 1; 19264 } 19265 19266 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19267 gr->attributeWildcard) == -1) 19268 return(-1); 19269 } 19270 } 19271 /* 19272 * Just remove the reference if the referenced group does not 19273 * contain any attribute uses. 19274 */ 19275 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19276 if ((sublist == NULL) || sublist->nbItems == 0) { 19277 if (xmlSchemaItemListRemove(list, i) == -1) 19278 return(-1); 19279 i--; 19280 continue; 19281 } 19282 /* 19283 * Add the attribute uses. 19284 */ 19285 list->items[i] = sublist->items[0]; 19286 if (sublist->nbItems != 1) { 19287 for (j = 1; j < sublist->nbItems; j++) { 19288 i++; 19289 if (xmlSchemaItemListInsert(list, 19290 sublist->items[j], i) == -1) 19291 return(-1); 19292 } 19293 } 19294 } 19295 19296 } 19297 /* 19298 * Handle pointless prohibitions of declared attributes. 19299 */ 19300 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19301 xmlSchemaAttributeUseProhibPtr prohib; 19302 19303 for (i = prohibs->nbItems -1; i >= 0; i--) { 19304 prohib = prohibs->items[i]; 19305 for (j = 0; j < list->nbItems; j++) { 19306 use = list->items[j]; 19307 19308 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19309 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19310 { 19311 xmlChar *str = NULL; 19312 19313 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19314 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19315 prohib->node, NULL, 19316 "Skipping pointless attribute use prohibition " 19317 "'%s', since a corresponding attribute use " 19318 "exists already in the type definition", 19319 xmlSchemaFormatQName(&str, 19320 prohib->targetNamespace, prohib->name), 19321 NULL, NULL); 19322 FREE_AND_NULL(str); 19323 /* 19324 * Remove the prohibition. 19325 */ 19326 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19327 return(-1); 19328 break; 19329 } 19330 } 19331 } 19332 } 19333 return(0); 19334 } 19335 19336 /** 19337 * xmlSchemaAttributeGroupExpandRefs: 19338 * @pctxt: the parser context 19339 * @attrGr: the attribute group definition 19340 * 19341 * Computation of: 19342 * {attribute uses} property 19343 * {attribute wildcard} property 19344 * 19345 * Substitutes contained attribute group references 19346 * for their attribute uses. Wildcards are intersected. 19347 */ 19348 static int 19349 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19350 xmlSchemaAttributeGroupPtr attrGr) 19351 { 19352 if ((attrGr->attrUses == NULL) || 19353 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19354 return(0); 19355 19356 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19357 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19358 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19359 return(-1); 19360 return(0); 19361 } 19362 19363 /** 19364 * xmlSchemaAttributeGroupExpandRefs: 19365 * @pctxt: the parser context 19366 * @attrGr: the attribute group definition 19367 * 19368 * Substitutes contained attribute group references 19369 * for their attribute uses. Wildcards are intersected. 19370 * 19371 * Schema Component Constraint: 19372 * Attribute Group Definition Properties Correct (ag-props-correct) 19373 */ 19374 static int 19375 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19376 xmlSchemaAttributeGroupPtr attrGr) 19377 { 19378 /* 19379 * SPEC ag-props-correct 19380 * (1) "The values of the properties of an attribute group definition 19381 * must be as described in the property tableau in The Attribute 19382 * Group Definition Schema Component ($3.6.1), modulo the impact of 19383 * Missing Sub-components ($5.3);" 19384 */ 19385 19386 if ((attrGr->attrUses != NULL) && 19387 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19388 { 19389 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19390 xmlSchemaAttributeUsePtr use, tmp; 19391 int i, j, hasId = 0; 19392 19393 for (i = uses->nbItems -1; i >= 0; i--) { 19394 use = uses->items[i]; 19395 /* 19396 * SPEC ag-props-correct 19397 * (2) "Two distinct members of the {attribute uses} must not have 19398 * {attribute declaration}s both of whose {name}s match and whose 19399 * {target namespace}s are identical." 19400 */ 19401 if (i > 0) { 19402 for (j = i -1; j >= 0; j--) { 19403 tmp = uses->items[j]; 19404 if ((WXS_ATTRUSE_DECL_NAME(use) == 19405 WXS_ATTRUSE_DECL_NAME(tmp)) && 19406 (WXS_ATTRUSE_DECL_TNS(use) == 19407 WXS_ATTRUSE_DECL_TNS(tmp))) 19408 { 19409 xmlChar *str = NULL; 19410 19411 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19412 XML_SCHEMAP_AG_PROPS_CORRECT, 19413 attrGr->node, WXS_BASIC_CAST attrGr, 19414 "Duplicate %s", 19415 xmlSchemaGetComponentDesignation(&str, use), 19416 NULL); 19417 FREE_AND_NULL(str); 19418 /* 19419 * Remove the duplicate. 19420 */ 19421 if (xmlSchemaItemListRemove(uses, i) == -1) 19422 return(-1); 19423 goto next_use; 19424 } 19425 } 19426 } 19427 /* 19428 * SPEC ag-props-correct 19429 * (3) "Two distinct members of the {attribute uses} must not have 19430 * {attribute declaration}s both of whose {type definition}s are or 19431 * are derived from ID." 19432 * TODO: Does 'derived' include member-types of unions? 19433 */ 19434 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19435 if (xmlSchemaIsDerivedFromBuiltInType( 19436 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19437 { 19438 if (hasId) { 19439 xmlChar *str = NULL; 19440 19441 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19442 XML_SCHEMAP_AG_PROPS_CORRECT, 19443 attrGr->node, WXS_BASIC_CAST attrGr, 19444 "There must not exist more than one attribute " 19445 "declaration of type 'xs:ID' " 19446 "(or derived from 'xs:ID'). The %s violates this " 19447 "constraint", 19448 xmlSchemaGetComponentDesignation(&str, use), 19449 NULL); 19450 FREE_AND_NULL(str); 19451 if (xmlSchemaItemListRemove(uses, i) == -1) 19452 return(-1); 19453 } 19454 hasId = 1; 19455 } 19456 } 19457 next_use: {} 19458 } 19459 } 19460 return(0); 19461 } 19462 19463 /** 19464 * xmlSchemaResolveAttrGroupReferences: 19465 * @attrgrpDecl: the schema attribute definition 19466 * @ctxt: the schema parser context 19467 * @name: the attribute name 19468 * 19469 * Resolves references to attribute group definitions. 19470 */ 19471 static int 19472 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19473 xmlSchemaParserCtxtPtr ctxt) 19474 { 19475 xmlSchemaAttributeGroupPtr group; 19476 19477 if (ref->item != NULL) 19478 return(0); 19479 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19480 ref->name, 19481 ref->targetNamespace); 19482 if (group == NULL) { 19483 xmlSchemaPResCompAttrErr(ctxt, 19484 XML_SCHEMAP_SRC_RESOLVE, 19485 NULL, ref->node, 19486 "ref", ref->name, ref->targetNamespace, 19487 ref->itemType, NULL); 19488 return(ctxt->err); 19489 } 19490 ref->item = WXS_BASIC_CAST group; 19491 return(0); 19492 } 19493 19494 /** 19495 * xmlSchemaCheckAttrPropsCorrect: 19496 * @item: an schema attribute declaration/use 19497 * @ctxt: a schema parser context 19498 * @name: the name of the attribute 19499 * 19500 * 19501 * Schema Component Constraint: 19502 * Attribute Declaration Properties Correct (a-props-correct) 19503 * 19504 * Validates the value constraints of an attribute declaration/use. 19505 * NOTE that this needs the simple type definitions to be already 19506 * built and checked. 19507 */ 19508 static int 19509 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19510 xmlSchemaAttributePtr attr) 19511 { 19512 19513 /* 19514 * SPEC a-props-correct (1) 19515 * "The values of the properties of an attribute declaration must 19516 * be as described in the property tableau in The Attribute 19517 * Declaration Schema Component ($3.2.1), modulo the impact of 19518 * Missing Sub-components ($5.3)." 19519 */ 19520 19521 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19522 return(0); 19523 19524 if (attr->defValue != NULL) { 19525 int ret; 19526 19527 /* 19528 * SPEC a-props-correct (3) 19529 * "If the {type definition} is or is derived from ID then there 19530 * must not be a {value constraint}." 19531 */ 19532 if (xmlSchemaIsDerivedFromBuiltInType( 19533 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19534 { 19535 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19536 XML_SCHEMAP_A_PROPS_CORRECT_3, 19537 NULL, WXS_BASIC_CAST attr, 19538 "Value constraints are not allowed if the type definition " 19539 "is or is derived from xs:ID", 19540 NULL, NULL); 19541 return(pctxt->err); 19542 } 19543 /* 19544 * SPEC a-props-correct (2) 19545 * "if there is a {value constraint}, the canonical lexical 19546 * representation of its value must be `valid` with respect 19547 * to the {type definition} as defined in String Valid ($3.14.4)." 19548 * TODO: Don't care about the *canonical* stuff here, this requirement 19549 * will be removed in WXS 1.1 anyway. 19550 */ 19551 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19552 attr->node, WXS_ATTR_TYPEDEF(attr), 19553 attr->defValue, &(attr->defVal), 19554 1, 1, 0); 19555 if (ret != 0) { 19556 if (ret < 0) { 19557 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19558 "calling xmlSchemaVCheckCVCSimpleType()"); 19559 return(-1); 19560 } 19561 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19562 XML_SCHEMAP_A_PROPS_CORRECT_2, 19563 NULL, WXS_BASIC_CAST attr, 19564 "The value of the value constraint is not valid", 19565 NULL, NULL); 19566 return(pctxt->err); 19567 } 19568 } 19569 19570 return(0); 19571 } 19572 19573 static xmlSchemaElementPtr 19574 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19575 xmlSchemaElementPtr ancestor) 19576 { 19577 xmlSchemaElementPtr ret; 19578 19579 if (WXS_SUBST_HEAD(ancestor) == NULL) 19580 return (NULL); 19581 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19582 return (ancestor); 19583 19584 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19585 return (NULL); 19586 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19587 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19588 WXS_SUBST_HEAD(ancestor)); 19589 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19590 19591 return (ret); 19592 } 19593 19594 /** 19595 * xmlSchemaCheckElemPropsCorrect: 19596 * @ctxt: a schema parser context 19597 * @decl: the element declaration 19598 * @name: the name of the attribute 19599 * 19600 * Schema Component Constraint: 19601 * Element Declaration Properties Correct (e-props-correct) 19602 * 19603 * STATUS: 19604 * missing: (6) 19605 */ 19606 static int 19607 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19608 xmlSchemaElementPtr elemDecl) 19609 { 19610 int ret = 0; 19611 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19612 /* 19613 * SPEC (1) "The values of the properties of an element declaration 19614 * must be as described in the property tableau in The Element 19615 * Declaration Schema Component ($3.3.1), modulo the impact of Missing 19616 * Sub-components ($5.3)." 19617 */ 19618 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19619 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19620 19621 xmlSchemaCheckElementDeclComponent(head, pctxt); 19622 /* 19623 * SPEC (3) "If there is a non-`absent` {substitution group 19624 * affiliation}, then {scope} must be global." 19625 */ 19626 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19627 xmlSchemaPCustomErr(pctxt, 19628 XML_SCHEMAP_E_PROPS_CORRECT_3, 19629 WXS_BASIC_CAST elemDecl, NULL, 19630 "Only global element declarations can have a " 19631 "substitution group affiliation", NULL); 19632 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19633 } 19634 /* 19635 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19636 * That is, it must not be possible to return to an element declaration 19637 * by repeatedly following the {substitution group affiliation} 19638 * property." 19639 */ 19640 if (head == elemDecl) 19641 circ = head; 19642 else if (WXS_SUBST_HEAD(head) != NULL) 19643 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19644 else 19645 circ = NULL; 19646 if (circ != NULL) { 19647 xmlChar *strA = NULL, *strB = NULL; 19648 19649 xmlSchemaPCustomErrExt(pctxt, 19650 XML_SCHEMAP_E_PROPS_CORRECT_6, 19651 WXS_BASIC_CAST circ, NULL, 19652 "The element declaration '%s' defines a circular " 19653 "substitution group to element declaration '%s'", 19654 xmlSchemaGetComponentQName(&strA, circ), 19655 xmlSchemaGetComponentQName(&strB, head), 19656 NULL); 19657 FREE_AND_NULL(strA) 19658 FREE_AND_NULL(strB) 19659 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19660 } 19661 /* 19662 * SPEC (4) "If there is a {substitution group affiliation}, 19663 * the {type definition} 19664 * of the element declaration must be validly derived from the {type 19665 * definition} of the {substitution group affiliation}, given the value 19666 * of the {substitution group exclusions} of the {substitution group 19667 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6) 19668 * (if the {type definition} is complex) or as defined in 19669 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is 19670 * simple)." 19671 * 19672 * NOTE: {substitution group exclusions} means the values of the 19673 * attribute "final". 19674 */ 19675 19676 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19677 int set = 0; 19678 19679 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19680 set |= SUBSET_EXTENSION; 19681 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19682 set |= SUBSET_RESTRICTION; 19683 19684 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19685 WXS_ELEM_TYPEDEF(head), set) != 0) { 19686 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19687 19688 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19689 xmlSchemaPCustomErrExt(pctxt, 19690 XML_SCHEMAP_E_PROPS_CORRECT_4, 19691 WXS_BASIC_CAST elemDecl, NULL, 19692 "The type definition '%s' was " 19693 "either rejected by the substitution group " 19694 "affiliation '%s', or not validly derived from its type " 19695 "definition '%s'", 19696 xmlSchemaGetComponentQName(&strA, typeDef), 19697 xmlSchemaGetComponentQName(&strB, head), 19698 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19699 FREE_AND_NULL(strA) 19700 FREE_AND_NULL(strB) 19701 FREE_AND_NULL(strC) 19702 } 19703 } 19704 } 19705 /* 19706 * SPEC (5) "If the {type definition} or {type definition}'s 19707 * {content type} 19708 * is or is derived from ID then there must not be a {value constraint}. 19709 * Note: The use of ID as a type definition for elements goes beyond 19710 * XML 1.0, and should be avoided if backwards compatibility is desired" 19711 */ 19712 if ((elemDecl->value != NULL) && 19713 ((WXS_IS_SIMPLE(typeDef) && 19714 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19715 (WXS_IS_COMPLEX(typeDef) && 19716 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19717 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19718 XML_SCHEMAS_ID)))) { 19719 19720 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19721 xmlSchemaPCustomErr(pctxt, 19722 XML_SCHEMAP_E_PROPS_CORRECT_5, 19723 WXS_BASIC_CAST elemDecl, NULL, 19724 "The type definition (or type definition's content type) is or " 19725 "is derived from ID; value constraints are not allowed in " 19726 "conjunction with such a type definition", NULL); 19727 } else if (elemDecl->value != NULL) { 19728 int vcret; 19729 xmlNodePtr node = NULL; 19730 19731 /* 19732 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19733 * representation of its value must be `valid` with respect to the 19734 * {type definition} as defined in Element Default Valid (Immediate) 19735 * ($3.3.6)." 19736 */ 19737 if (typeDef == NULL) { 19738 xmlSchemaPErr(pctxt, elemDecl->node, 19739 XML_SCHEMAP_INTERNAL, 19740 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19741 "type is missing... skipping validation of " 19742 "the value constraint", NULL, NULL); 19743 return (-1); 19744 } 19745 if (elemDecl->node != NULL) { 19746 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19747 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19748 BAD_CAST "fixed"); 19749 else 19750 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19751 BAD_CAST "default"); 19752 } 19753 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19754 typeDef, elemDecl->value, &(elemDecl->defVal)); 19755 if (vcret != 0) { 19756 if (vcret < 0) { 19757 PERROR_INT("xmlSchemaElemCheckValConstr", 19758 "failed to validate the value constraint of an " 19759 "element declaration"); 19760 return (-1); 19761 } 19762 return (vcret); 19763 } 19764 } 19765 19766 return (ret); 19767 } 19768 19769 /** 19770 * xmlSchemaCheckElemSubstGroup: 19771 * @ctxt: a schema parser context 19772 * @decl: the element declaration 19773 * @name: the name of the attribute 19774 * 19775 * Schema Component Constraint: 19776 * Substitution Group (cos-equiv-class) 19777 * 19778 * In Libxml2 the subst. groups will be precomputed, in terms of that 19779 * a list will be built for each subst. group head, holding all direct 19780 * referents to this head. 19781 * NOTE that this function needs: 19782 * 1. circular subst. groups to be checked beforehand 19783 * 2. the declaration's type to be derived from the head's type 19784 * 19785 * STATUS: 19786 * 19787 */ 19788 static void 19789 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19790 xmlSchemaElementPtr elemDecl) 19791 { 19792 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19793 /* SPEC (1) "Its {abstract} is false." */ 19794 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19795 return; 19796 { 19797 xmlSchemaElementPtr head; 19798 xmlSchemaTypePtr headType, type; 19799 int set, methSet; 19800 /* 19801 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19802 * {disallowed substitutions} as the blocking constraint, as defined in 19803 * Substitution Group OK (Transitive) ($3.3.6)." 19804 */ 19805 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19806 head = WXS_SUBST_HEAD(head)) { 19807 set = 0; 19808 methSet = 0; 19809 /* 19810 * The blocking constraints. 19811 */ 19812 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19813 continue; 19814 headType = head->subtypes; 19815 type = elemDecl->subtypes; 19816 if (headType == type) 19817 goto add_member; 19818 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19819 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19820 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19821 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19822 /* 19823 * SPEC: Substitution Group OK (Transitive) (2.3) 19824 * "The set of all {derivation method}s involved in the 19825 * derivation of D's {type definition} from C's {type definition} 19826 * does not intersect with the union of the blocking constraint, 19827 * C's {prohibited substitutions} (if C is complex, otherwise the 19828 * empty set) and the {prohibited substitutions} (respectively the 19829 * empty set) of any intermediate {type definition}s in the 19830 * derivation of D's {type definition} from C's {type definition}." 19831 */ 19832 /* 19833 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19834 * subst.head axis, the methSet does not need to be computed for 19835 * the full depth over and over. 19836 */ 19837 /* 19838 * The set of all {derivation method}s involved in the derivation 19839 */ 19840 while ((type != NULL) && (type != headType)) { 19841 if ((WXS_IS_EXTENSION(type)) && 19842 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19843 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19844 19845 if (WXS_IS_RESTRICTION(type) && 19846 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19847 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19848 19849 type = type->baseType; 19850 } 19851 /* 19852 * The {prohibited substitutions} of all intermediate types + 19853 * the head's type. 19854 */ 19855 type = elemDecl->subtypes->baseType; 19856 while (type != NULL) { 19857 if (WXS_IS_COMPLEX(type)) { 19858 if ((type->flags & 19859 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19860 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19861 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19862 if ((type->flags & 19863 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19864 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19865 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19866 } else 19867 break; 19868 if (type == headType) 19869 break; 19870 type = type->baseType; 19871 } 19872 if ((set != 0) && 19873 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19874 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19875 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19876 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19877 continue; 19878 } 19879 add_member: 19880 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19881 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19882 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19883 } 19884 } 19885 } 19886 19887 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19888 /** 19889 * xmlSchemaCheckElementDeclComponent 19890 * @pctxt: the schema parser context 19891 * @ctxtComponent: the context component (an element declaration) 19892 * @ctxtParticle: the first particle of the context component 19893 * @searchParticle: the element declaration particle to be analysed 19894 * 19895 * Schema Component Constraint: Element Declarations Consistent 19896 */ 19897 static int 19898 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19899 xmlSchemaBasicItemPtr ctxtComponent, 19900 xmlSchemaParticlePtr ctxtParticle, 19901 xmlSchemaParticlePtr searchParticle, 19902 xmlSchemaParticlePtr curParticle, 19903 int search) 19904 { 19905 return(0); 19906 19907 int ret = 0; 19908 xmlSchemaParticlePtr cur = curParticle; 19909 if (curParticle == NULL) { 19910 return(0); 19911 } 19912 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19913 /* 19914 * Just return in this case. A missing "term" of the particle 19915 * might arise due to an invalid "term" component. 19916 */ 19917 return(0); 19918 } 19919 while (cur != NULL) { 19920 switch (WXS_PARTICLE_TERM(cur)->type) { 19921 case XML_SCHEMA_TYPE_ANY: 19922 break; 19923 case XML_SCHEMA_TYPE_ELEMENT: 19924 if (search == 0) { 19925 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19926 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19927 if (ret != 0) 19928 return(ret); 19929 } else { 19930 xmlSchemaElementPtr elem = 19931 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19932 /* 19933 * SPEC Element Declarations Consistent: 19934 * "If the {particles} contains, either directly, 19935 * indirectly (that is, within the {particles} of a 19936 * contained model group, recursively) or `implicitly` 19937 * two or more element declaration particles with 19938 * the same {name} and {target namespace}, then 19939 * all their type definitions must be the same 19940 * top-level definition [...]" 19941 */ 19942 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19943 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19944 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19945 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19946 { 19947 xmlChar *strA = NULL, *strB = NULL; 19948 19949 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19950 /* TODO: error code */ 19951 XML_SCHEMAP_COS_NONAMBIG, 19952 WXS_ITEM_NODE(cur), NULL, 19953 "In the content model of %s, there are multiple " 19954 "element declarations for '%s' with different " 19955 "type definitions", 19956 xmlSchemaGetComponentDesignation(&strA, 19957 ctxtComponent), 19958 xmlSchemaFormatQName(&strB, 19959 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19960 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19961 FREE_AND_NULL(strA); 19962 FREE_AND_NULL(strB); 19963 return(XML_SCHEMAP_COS_NONAMBIG); 19964 } 19965 } 19966 break; 19967 case XML_SCHEMA_TYPE_SEQUENCE: { 19968 break; 19969 } 19970 case XML_SCHEMA_TYPE_CHOICE:{ 19971 /* 19972 xmlSchemaTreeItemPtr sub; 19973 19974 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19975 while (sub != NULL) { 19976 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19977 ctxtParticle, ctxtElem); 19978 if (ret != 0) 19979 return(ret); 19980 sub = sub->next; 19981 } 19982 */ 19983 break; 19984 } 19985 case XML_SCHEMA_TYPE_ALL: 19986 break; 19987 case XML_SCHEMA_TYPE_GROUP: 19988 break; 19989 default: 19990 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19991 "xmlSchemaCheckElementDeclConsistent", 19992 "found unexpected term of type '%s' in content model", 19993 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19994 return(-1); 19995 } 19996 cur = (xmlSchemaParticlePtr) cur->next; 19997 } 19998 19999 exit: 20000 return(ret); 20001 } 20002 #endif 20003 20004 /** 20005 * xmlSchemaCheckElementDeclComponent 20006 * @item: an schema element declaration/particle 20007 * @ctxt: a schema parser context 20008 * @name: the name of the attribute 20009 * 20010 * Validates the value constraints of an element declaration. 20011 * Adds substitution group members. 20012 */ 20013 static void 20014 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 20015 xmlSchemaParserCtxtPtr ctxt) 20016 { 20017 if (elemDecl == NULL) 20018 return; 20019 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 20020 return; 20021 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 20022 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 20023 /* 20024 * Adds substitution group members. 20025 */ 20026 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 20027 } 20028 } 20029 20030 /** 20031 * xmlSchemaResolveModelGroupParticleReferences: 20032 * @particle: a particle component 20033 * @ctxt: a parser context 20034 * 20035 * Resolves references of a model group's {particles} to 20036 * model group definitions and to element declarations. 20037 */ 20038 static void 20039 xmlSchemaResolveModelGroupParticleReferences( 20040 xmlSchemaParserCtxtPtr ctxt, 20041 xmlSchemaModelGroupPtr mg) 20042 { 20043 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 20044 xmlSchemaQNameRefPtr ref; 20045 xmlSchemaBasicItemPtr refItem; 20046 20047 /* 20048 * URGENT TODO: Test this. 20049 */ 20050 while (particle != NULL) { 20051 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20052 ((WXS_PARTICLE_TERM(particle))->type != 20053 XML_SCHEMA_EXTRA_QNAMEREF)) 20054 { 20055 goto next_particle; 20056 } 20057 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20058 /* 20059 * Resolve the reference. 20060 * NULL the {term} by default. 20061 */ 20062 particle->children = NULL; 20063 20064 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20065 ref->itemType, ref->name, ref->targetNamespace); 20066 if (refItem == NULL) { 20067 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20068 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20069 ref->targetNamespace, ref->itemType, NULL); 20070 /* TODO: remove the particle. */ 20071 goto next_particle; 20072 } 20073 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20074 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20075 /* TODO: remove the particle. */ 20076 goto next_particle; 20077 /* 20078 * NOTE that we will assign the model group definition 20079 * itself to the "term" of the particle. This will ease 20080 * the check for circular model group definitions. After 20081 * that the "term" will be assigned the model group of the 20082 * model group definition. 20083 */ 20084 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20085 XML_SCHEMA_TYPE_ALL) { 20086 /* 20087 * SPEC cos-all-limited (1) 20088 * SPEC cos-all-limited (1.2) 20089 * "It appears only as the value of one or both of the 20090 * following properties:" 20091 * (1.1) "the {model group} property of a model group 20092 * definition." 20093 * (1.2) "the {term} property of a particle [... of] the " 20094 * {content type} of a complex type definition." 20095 */ 20096 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20097 /* TODO: error code */ 20098 XML_SCHEMAP_COS_ALL_LIMITED, 20099 WXS_ITEM_NODE(particle), NULL, 20100 "A model group definition is referenced, but " 20101 "it contains an 'all' model group, which " 20102 "cannot be contained by model groups", 20103 NULL, NULL); 20104 /* TODO: remove the particle. */ 20105 goto next_particle; 20106 } 20107 particle->children = (xmlSchemaTreeItemPtr) refItem; 20108 } else { 20109 /* 20110 * TODO: Are referenced element declarations the only 20111 * other components we expect here? 20112 */ 20113 particle->children = (xmlSchemaTreeItemPtr) refItem; 20114 } 20115 next_particle: 20116 particle = WXS_PTC_CAST particle->next; 20117 } 20118 } 20119 20120 static int 20121 xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20122 xmlSchemaValPtr y) 20123 { 20124 xmlSchemaTypePtr tx, ty, ptx, pty; 20125 int ret; 20126 20127 while (x != NULL) { 20128 /* Same types. */ 20129 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20130 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20131 ptx = xmlSchemaGetPrimitiveType(tx); 20132 pty = xmlSchemaGetPrimitiveType(ty); 20133 /* 20134 * (1) if a datatype T' is `derived` by `restriction` from an 20135 * atomic datatype T then the `value space` of T' is a subset of 20136 * the `value space` of T. */ 20137 /* 20138 * (2) if datatypes T' and T'' are `derived` by `restriction` 20139 * from a common atomic ancestor T then the `value space`s of T' 20140 * and T'' may overlap. 20141 */ 20142 if (ptx != pty) 20143 return(0); 20144 /* 20145 * We assume computed values to be normalized, so do a fast 20146 * string comparison for string based types. 20147 */ 20148 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20149 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20150 if (! xmlStrEqual( 20151 xmlSchemaValueGetAsString(x), 20152 xmlSchemaValueGetAsString(y))) 20153 return (0); 20154 } else { 20155 ret = xmlSchemaCompareValuesWhtsp( 20156 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20157 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20158 if (ret == -2) 20159 return(-1); 20160 if (ret != 0) 20161 return(0); 20162 } 20163 /* 20164 * Lists. 20165 */ 20166 x = xmlSchemaValueGetNext(x); 20167 if (x != NULL) { 20168 y = xmlSchemaValueGetNext(y); 20169 if (y == NULL) 20170 return (0); 20171 } else if (xmlSchemaValueGetNext(y) != NULL) 20172 return (0); 20173 else 20174 return (1); 20175 } 20176 return (0); 20177 } 20178 20179 /** 20180 * xmlSchemaResolveAttrUseReferences: 20181 * @item: an attribute use 20182 * @ctxt: a parser context 20183 * 20184 * Resolves the referenced attribute declaration. 20185 */ 20186 static int 20187 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20188 xmlSchemaParserCtxtPtr ctxt) 20189 { 20190 if ((ctxt == NULL) || (ause == NULL)) 20191 return(-1); 20192 if ((ause->attrDecl == NULL) || 20193 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20194 return(0); 20195 20196 { 20197 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20198 20199 /* 20200 * TODO: Evaluate, what errors could occur if the declaration is not 20201 * found. 20202 */ 20203 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20204 ref->name, ref->targetNamespace); 20205 if (ause->attrDecl == NULL) { 20206 xmlSchemaPResCompAttrErr(ctxt, 20207 XML_SCHEMAP_SRC_RESOLVE, 20208 WXS_BASIC_CAST ause, ause->node, 20209 "ref", ref->name, ref->targetNamespace, 20210 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20211 return(ctxt->err);; 20212 } 20213 } 20214 return(0); 20215 } 20216 20217 /** 20218 * xmlSchemaCheckAttrUsePropsCorrect: 20219 * @ctxt: a parser context 20220 * @use: an attribute use 20221 * 20222 * Schema Component Constraint: 20223 * Attribute Use Correct (au-props-correct) 20224 * 20225 */ 20226 static int 20227 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20228 xmlSchemaAttributeUsePtr use) 20229 { 20230 if ((ctxt == NULL) || (use == NULL)) 20231 return(-1); 20232 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20233 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20234 return(0); 20235 20236 /* 20237 * SPEC au-props-correct (1) 20238 * "The values of the properties of an attribute use must be as 20239 * described in the property tableau in The Attribute Use Schema 20240 * Component ($3.5.1), modulo the impact of Missing 20241 * Sub-components ($5.3)." 20242 */ 20243 20244 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20245 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20246 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20247 { 20248 xmlSchemaPCustomErr(ctxt, 20249 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20250 WXS_BASIC_CAST use, NULL, 20251 "The attribute declaration has a 'fixed' value constraint " 20252 ", thus the attribute use must also have a 'fixed' value " 20253 "constraint", 20254 NULL); 20255 return(ctxt->err); 20256 } 20257 /* 20258 * Compute and check the value constraint's value. 20259 */ 20260 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20261 int ret; 20262 /* 20263 * TODO: The spec seems to be missing a check of the 20264 * value constraint of the attribute use. We will do it here. 20265 */ 20266 /* 20267 * SPEC a-props-correct (3) 20268 */ 20269 if (xmlSchemaIsDerivedFromBuiltInType( 20270 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20271 { 20272 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20273 XML_SCHEMAP_AU_PROPS_CORRECT, 20274 NULL, WXS_BASIC_CAST use, 20275 "Value constraints are not allowed if the type definition " 20276 "is or is derived from xs:ID", 20277 NULL, NULL); 20278 return(ctxt->err); 20279 } 20280 20281 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20282 use->node, WXS_ATTRUSE_TYPEDEF(use), 20283 use->defValue, &(use->defVal), 20284 1, 1, 0); 20285 if (ret != 0) { 20286 if (ret < 0) { 20287 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20288 "calling xmlSchemaVCheckCVCSimpleType()"); 20289 return(-1); 20290 } 20291 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20292 XML_SCHEMAP_AU_PROPS_CORRECT, 20293 NULL, WXS_BASIC_CAST use, 20294 "The value of the value constraint is not valid", 20295 NULL, NULL); 20296 return(ctxt->err); 20297 } 20298 } 20299 /* 20300 * SPEC au-props-correct (2) 20301 * "If the {attribute declaration} has a fixed 20302 * {value constraint}, then if the attribute use itself has a 20303 * {value constraint}, it must also be fixed and its value must match 20304 * that of the {attribute declaration}'s {value constraint}." 20305 */ 20306 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20307 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20308 { 20309 if (! xmlSchemaAreValuesEqual(use->defVal, 20310 (WXS_ATTRUSE_DECL(use))->defVal)) 20311 { 20312 xmlSchemaPCustomErr(ctxt, 20313 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20314 WXS_BASIC_CAST use, NULL, 20315 "The 'fixed' value constraint of the attribute use " 20316 "must match the attribute declaration's value " 20317 "constraint '%s'", 20318 (WXS_ATTRUSE_DECL(use))->defValue); 20319 } 20320 return(ctxt->err); 20321 } 20322 return(0); 20323 } 20324 20325 20326 20327 20328 /** 20329 * xmlSchemaResolveAttrTypeReferences: 20330 * @item: an attribute declaration 20331 * @ctxt: a parser context 20332 * 20333 * Resolves the referenced type definition component. 20334 */ 20335 static int 20336 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20337 xmlSchemaParserCtxtPtr ctxt) 20338 { 20339 /* 20340 * The simple type definition corresponding to the <simpleType> element 20341 * information item in the [children], if present, otherwise the simple 20342 * type definition `resolved` to by the `actual value` of the type 20343 * [attribute], if present, otherwise the `simple ur-type definition`. 20344 */ 20345 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20346 return(0); 20347 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20348 if (item->subtypes != NULL) 20349 return(0); 20350 if (item->typeName != NULL) { 20351 xmlSchemaTypePtr type; 20352 20353 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20354 item->typeNs); 20355 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20356 xmlSchemaPResCompAttrErr(ctxt, 20357 XML_SCHEMAP_SRC_RESOLVE, 20358 WXS_BASIC_CAST item, item->node, 20359 "type", item->typeName, item->typeNs, 20360 XML_SCHEMA_TYPE_SIMPLE, NULL); 20361 return(ctxt->err); 20362 } else 20363 item->subtypes = type; 20364 20365 } else { 20366 /* 20367 * The type defaults to the xs:anySimpleType. 20368 */ 20369 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20370 } 20371 return(0); 20372 } 20373 20374 /** 20375 * xmlSchemaResolveIDCKeyReferences: 20376 * @idc: the identity-constraint definition 20377 * @ctxt: the schema parser context 20378 * @name: the attribute name 20379 * 20380 * Resolve keyRef references to key/unique IDCs. 20381 * Schema Component Constraint: 20382 * Identity-constraint Definition Properties Correct (c-props-correct) 20383 */ 20384 static int 20385 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20386 xmlSchemaParserCtxtPtr pctxt) 20387 { 20388 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20389 return(0); 20390 if (idc->ref->name != NULL) { 20391 idc->ref->item = (xmlSchemaBasicItemPtr) 20392 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20393 idc->ref->targetNamespace); 20394 if (idc->ref->item == NULL) { 20395 /* 20396 * TODO: It is actually not an error to fail to resolve 20397 * at this stage. BUT we need to be that strict! 20398 */ 20399 xmlSchemaPResCompAttrErr(pctxt, 20400 XML_SCHEMAP_SRC_RESOLVE, 20401 WXS_BASIC_CAST idc, idc->node, 20402 "refer", idc->ref->name, 20403 idc->ref->targetNamespace, 20404 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20405 return(pctxt->err); 20406 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20407 /* 20408 * SPEC c-props-correct (1) 20409 */ 20410 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20411 XML_SCHEMAP_C_PROPS_CORRECT, 20412 NULL, WXS_BASIC_CAST idc, 20413 "The keyref references a keyref", 20414 NULL, NULL); 20415 idc->ref->item = NULL; 20416 return(pctxt->err); 20417 } else { 20418 if (idc->nbFields != 20419 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20420 xmlChar *str = NULL; 20421 xmlSchemaIDCPtr refer; 20422 20423 refer = (xmlSchemaIDCPtr) idc->ref->item; 20424 /* 20425 * SPEC c-props-correct(2) 20426 * "If the {identity-constraint category} is keyref, 20427 * the cardinality of the {fields} must equal that of 20428 * the {fields} of the {referenced key}. 20429 */ 20430 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20431 XML_SCHEMAP_C_PROPS_CORRECT, 20432 NULL, WXS_BASIC_CAST idc, 20433 "The cardinality of the keyref differs from the " 20434 "cardinality of the referenced key/unique '%s'", 20435 xmlSchemaFormatQName(&str, refer->targetNamespace, 20436 refer->name), 20437 NULL); 20438 FREE_AND_NULL(str) 20439 return(pctxt->err); 20440 } 20441 } 20442 } 20443 return(0); 20444 } 20445 20446 static int 20447 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20448 xmlSchemaParserCtxtPtr pctxt) 20449 { 20450 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20451 prohib->targetNamespace) == NULL) { 20452 20453 xmlSchemaPResCompAttrErr(pctxt, 20454 XML_SCHEMAP_SRC_RESOLVE, 20455 NULL, prohib->node, 20456 "ref", prohib->name, prohib->targetNamespace, 20457 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20458 return(XML_SCHEMAP_SRC_RESOLVE); 20459 } 20460 return(0); 20461 } 20462 20463 #define WXS_REDEFINED_TYPE(c) \ 20464 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20465 20466 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20467 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20468 20469 #define WXS_REDEFINED_ATTR_GROUP(c) \ 20470 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20471 20472 static int 20473 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20474 { 20475 int err = 0; 20476 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20477 xmlSchemaBasicItemPtr prev, item; 20478 int wasRedefined; 20479 20480 if (redef == NULL) 20481 return(0); 20482 20483 do { 20484 item = redef->item; 20485 /* 20486 * First try to locate the redefined component in the 20487 * schema graph starting with the redefined schema. 20488 * NOTE: According to this schema bug entry: 20489 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20490 * it's not clear if the referenced component needs to originate 20491 * from the <redefine>d schema _document_ or the schema; the latter 20492 * would include all imported and included sub-schemas of the 20493 * <redefine>d schema. Currently the latter approach is used. 20494 * SUPPLEMENT: It seems that the WG moves towards the latter 20495 * approach, so we are doing it right. 20496 * 20497 */ 20498 prev = xmlSchemaFindRedefCompInGraph( 20499 redef->targetBucket, item->type, 20500 redef->refName, redef->refTargetNs); 20501 if (prev == NULL) { 20502 xmlChar *str = NULL; 20503 xmlNodePtr node; 20504 20505 /* 20506 * SPEC src-redefine: 20507 * (6.2.1) "The `actual value` of its own name attribute plus 20508 * target namespace must successfully `resolve` to a model 20509 * group definition in I." 20510 * (7.2.1) "The `actual value` of its own name attribute plus 20511 * target namespace must successfully `resolve` to an attribute 20512 * group definition in I." 20513 20514 * 20515 * Note that, if we are redefining with the use of references 20516 * to components, the spec assumes the src-resolve to be used; 20517 * but this won't assure that we search only *inside* the 20518 * redefined schema. 20519 */ 20520 if (redef->reference) 20521 node = WXS_ITEM_NODE(redef->reference); 20522 else 20523 node = WXS_ITEM_NODE(item); 20524 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20525 /* 20526 * TODO: error code. 20527 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20528 * reference kind. 20529 */ 20530 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20531 "The %s '%s' to be redefined could not be found in " 20532 "the redefined schema", 20533 WXS_ITEM_TYPE_NAME(item), 20534 xmlSchemaFormatQName(&str, redef->refTargetNs, 20535 redef->refName)); 20536 FREE_AND_NULL(str); 20537 err = pctxt->err; 20538 redef = redef->next; 20539 continue; 20540 } 20541 /* 20542 * TODO: Obtaining and setting the redefinition state is really 20543 * clumsy. 20544 */ 20545 wasRedefined = 0; 20546 switch (item->type) { 20547 case XML_SCHEMA_TYPE_COMPLEX: 20548 case XML_SCHEMA_TYPE_SIMPLE: 20549 if ((WXS_TYPE_CAST prev)->flags & 20550 XML_SCHEMAS_TYPE_REDEFINED) 20551 { 20552 wasRedefined = 1; 20553 break; 20554 } 20555 /* Mark it as redefined. */ 20556 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20557 /* 20558 * Assign the redefined type to the 20559 * base type of the redefining type. 20560 * TODO: How 20561 */ 20562 ((xmlSchemaTypePtr) item)->baseType = 20563 (xmlSchemaTypePtr) prev; 20564 break; 20565 case XML_SCHEMA_TYPE_GROUP: 20566 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20567 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20568 { 20569 wasRedefined = 1; 20570 break; 20571 } 20572 /* Mark it as redefined. */ 20573 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20574 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20575 if (redef->reference != NULL) { 20576 /* 20577 * Overwrite the QName-reference with the 20578 * referenced model group def. 20579 */ 20580 (WXS_PTC_CAST redef->reference)->children = 20581 WXS_TREE_CAST prev; 20582 } 20583 redef->target = prev; 20584 break; 20585 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20586 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20587 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20588 { 20589 wasRedefined = 1; 20590 break; 20591 } 20592 (WXS_ATTR_GROUP_CAST prev)->flags |= 20593 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20594 if (redef->reference != NULL) { 20595 /* 20596 * Assign the redefined attribute group to the 20597 * QName-reference component. 20598 * This is the easy case, since we will just 20599 * expand the redefined group. 20600 */ 20601 (WXS_QNAME_CAST redef->reference)->item = prev; 20602 redef->target = NULL; 20603 } else { 20604 /* 20605 * This is the complicated case: we need 20606 * to apply src-redefine (7.2.2) at a later 20607 * stage, i.e. when attribute group references 20608 * have been expanded and simple types have 20609 * been fixed. 20610 */ 20611 redef->target = prev; 20612 } 20613 break; 20614 default: 20615 PERROR_INT("xmlSchemaResolveRedefReferences", 20616 "Unexpected redefined component type"); 20617 return(-1); 20618 } 20619 if (wasRedefined) { 20620 xmlChar *str = NULL; 20621 xmlNodePtr node; 20622 20623 if (redef->reference) 20624 node = WXS_ITEM_NODE(redef->reference); 20625 else 20626 node = WXS_ITEM_NODE(redef->item); 20627 20628 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20629 /* TODO: error code. */ 20630 XML_SCHEMAP_SRC_REDEFINE, 20631 node, NULL, 20632 "The referenced %s was already redefined. Multiple " 20633 "redefinition of the same component is not supported", 20634 xmlSchemaGetComponentDesignation(&str, prev), 20635 NULL); 20636 FREE_AND_NULL(str) 20637 err = pctxt->err; 20638 redef = redef->next; 20639 continue; 20640 } 20641 redef = redef->next; 20642 } while (redef != NULL); 20643 20644 return(err); 20645 } 20646 20647 static int 20648 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20649 { 20650 int err = 0; 20651 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20652 xmlSchemaBasicItemPtr item; 20653 20654 if (redef == NULL) 20655 return(0); 20656 20657 do { 20658 if (redef->target == NULL) { 20659 redef = redef->next; 20660 continue; 20661 } 20662 item = redef->item; 20663 20664 switch (item->type) { 20665 case XML_SCHEMA_TYPE_SIMPLE: 20666 case XML_SCHEMA_TYPE_COMPLEX: 20667 /* 20668 * Since the spec wants the {name} of the redefined 20669 * type to be 'absent', we'll NULL it. 20670 */ 20671 (WXS_TYPE_CAST redef->target)->name = NULL; 20672 20673 /* 20674 * TODO: Seems like there's nothing more to do. The normal 20675 * inheritance mechanism is used. But not 100% sure. 20676 */ 20677 break; 20678 case XML_SCHEMA_TYPE_GROUP: 20679 /* 20680 * URGENT TODO: 20681 * SPEC src-redefine: 20682 * (6.2.2) "The {model group} of the model group definition 20683 * which corresponds to it per XML Representation of Model 20684 * Group Definition Schema Components ($3.7.2) must be a 20685 * `valid restriction` of the {model group} of that model 20686 * group definition in I, as defined in Particle Valid 20687 * (Restriction) ($3.9.6)." 20688 */ 20689 break; 20690 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20691 /* 20692 * SPEC src-redefine: 20693 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20694 * the attribute group definition which corresponds to it 20695 * per XML Representation of Attribute Group Definition Schema 20696 * Components ($3.6.2) must be `valid restrictions` of the 20697 * {attribute uses} and {attribute wildcard} of that attribute 20698 * group definition in I, as defined in clause 2, clause 3 and 20699 * clause 4 of Derivation Valid (Restriction, Complex) 20700 * ($3.4.6) (where references to the base type definition are 20701 * understood as references to the attribute group definition 20702 * in I)." 20703 */ 20704 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20705 XML_SCHEMA_ACTION_REDEFINE, 20706 item, redef->target, 20707 (WXS_ATTR_GROUP_CAST item)->attrUses, 20708 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20709 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20710 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20711 if (err == -1) 20712 return(-1); 20713 break; 20714 default: 20715 break; 20716 } 20717 redef = redef->next; 20718 } while (redef != NULL); 20719 return(0); 20720 } 20721 20722 20723 static int 20724 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20725 xmlSchemaBucketPtr bucket) 20726 { 20727 xmlSchemaBasicItemPtr item; 20728 int err; 20729 xmlHashTablePtr *table; 20730 const xmlChar *name; 20731 int i; 20732 20733 #define WXS_GET_GLOBAL_HASH(c, slot) { \ 20734 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20735 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20736 else \ 20737 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20738 20739 /* 20740 * Add global components to the schema's hash tables. 20741 * This is the place where duplicate components will be 20742 * detected. 20743 * TODO: I think normally we should support imports of the 20744 * same namespace from multiple locations. We don't do currently, 20745 * but if we do then according to: 20746 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20747 * we would need, if imported directly, to import redefined 20748 * components as well to be able to catch clashing components. 20749 * (I hope I'll still know what this means after some months :-() 20750 */ 20751 if (bucket == NULL) 20752 return(-1); 20753 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20754 return(0); 20755 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20756 20757 for (i = 0; i < bucket->globals->nbItems; i++) { 20758 item = bucket->globals->items[i]; 20759 table = NULL; 20760 switch (item->type) { 20761 case XML_SCHEMA_TYPE_COMPLEX: 20762 case XML_SCHEMA_TYPE_SIMPLE: 20763 if (WXS_REDEFINED_TYPE(item)) 20764 continue; 20765 name = (WXS_TYPE_CAST item)->name; 20766 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20767 break; 20768 case XML_SCHEMA_TYPE_ELEMENT: 20769 name = (WXS_ELEM_CAST item)->name; 20770 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20771 break; 20772 case XML_SCHEMA_TYPE_ATTRIBUTE: 20773 name = (WXS_ATTR_CAST item)->name; 20774 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20775 break; 20776 case XML_SCHEMA_TYPE_GROUP: 20777 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20778 continue; 20779 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20780 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20781 break; 20782 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20783 if (WXS_REDEFINED_ATTR_GROUP(item)) 20784 continue; 20785 name = (WXS_ATTR_GROUP_CAST item)->name; 20786 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20787 break; 20788 case XML_SCHEMA_TYPE_IDC_KEY: 20789 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20790 case XML_SCHEMA_TYPE_IDC_KEYREF: 20791 name = (WXS_IDC_CAST item)->name; 20792 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20793 break; 20794 case XML_SCHEMA_TYPE_NOTATION: 20795 name = ((xmlSchemaNotationPtr) item)->name; 20796 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20797 break; 20798 default: 20799 PERROR_INT("xmlSchemaAddComponents", 20800 "Unexpected global component type"); 20801 continue; 20802 } 20803 if (*table == NULL) { 20804 *table = xmlHashCreateDict(10, pctxt->dict); 20805 if (*table == NULL) { 20806 PERROR_INT("xmlSchemaAddComponents", 20807 "failed to create a component hash table"); 20808 return(-1); 20809 } 20810 } 20811 err = xmlHashAddEntry(*table, name, item); 20812 if (err != 0) { 20813 xmlChar *str = NULL; 20814 20815 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20816 XML_SCHEMAP_REDEFINED_TYPE, 20817 WXS_ITEM_NODE(item), 20818 WXS_BASIC_CAST item, 20819 "A global %s '%s' does already exist", 20820 WXS_ITEM_TYPE_NAME(item), 20821 xmlSchemaGetComponentQName(&str, item)); 20822 FREE_AND_NULL(str); 20823 } 20824 } 20825 /* 20826 * Process imported/included schemas. 20827 */ 20828 if (bucket->relations != NULL) { 20829 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20830 do { 20831 if ((rel->bucket != NULL) && 20832 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20833 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20834 return(-1); 20835 } 20836 rel = rel->next; 20837 } while (rel != NULL); 20838 } 20839 return(0); 20840 } 20841 20842 static int 20843 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20844 xmlSchemaBucketPtr rootBucket) 20845 { 20846 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20847 xmlSchemaTreeItemPtr item, *items; 20848 int nbItems, i, ret = 0; 20849 xmlSchemaBucketPtr oldbucket = con->bucket; 20850 xmlSchemaElementPtr elemDecl; 20851 20852 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20853 20854 if ((con->pending == NULL) || 20855 (con->pending->nbItems == 0)) 20856 return(0); 20857 20858 /* 20859 * Since xmlSchemaFixupComplexType() will create new particles 20860 * (local components), and those particle components need a bucket 20861 * on the constructor, we'll assure here that the constructor has 20862 * a bucket. 20863 * TODO: Think about storing locals _only_ on the main bucket. 20864 */ 20865 if (con->bucket == NULL) 20866 con->bucket = rootBucket; 20867 20868 /* TODO: 20869 * SPEC (src-redefine): 20870 * (6.2) "If it has no such self-reference, then all of the 20871 * following must be true:" 20872 20873 * (6.2.2) The {model group} of the model group definition which 20874 * corresponds to it per XML Representation of Model Group 20875 * Definition Schema Components ($3.7.2) must be a `valid 20876 * restriction` of the {model group} of that model group definition 20877 * in I, as defined in Particle Valid (Restriction) ($3.9.6)." 20878 */ 20879 xmlSchemaCheckSRCRedefineFirst(pctxt); 20880 20881 /* 20882 * Add global components to the schemata's hash tables. 20883 */ 20884 xmlSchemaAddComponents(pctxt, rootBucket); 20885 20886 pctxt->ctxtType = NULL; 20887 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20888 nbItems = con->pending->nbItems; 20889 /* 20890 * Now that we have parsed *all* the schema document(s) and converted 20891 * them to schema components, we can resolve references, apply component 20892 * constraints, create the FSA from the content model, etc. 20893 */ 20894 /* 20895 * Resolve references of.. 20896 * 20897 * 1. element declarations: 20898 * - the type definition 20899 * - the substitution group affiliation 20900 * 2. simple/complex types: 20901 * - the base type definition 20902 * - the memberTypes of union types 20903 * - the itemType of list types 20904 * 3. attributes declarations and attribute uses: 20905 * - the type definition 20906 * - if an attribute use, then the attribute declaration 20907 * 4. attribute group references: 20908 * - the attribute group definition 20909 * 5. particles: 20910 * - the term of the particle (e.g. a model group) 20911 * 6. IDC key-references: 20912 * - the referenced IDC 'key' or 'unique' definition 20913 * 7. Attribute prohibitions which had a "ref" attribute. 20914 */ 20915 for (i = 0; i < nbItems; i++) { 20916 item = items[i]; 20917 switch (item->type) { 20918 case XML_SCHEMA_TYPE_ELEMENT: 20919 xmlSchemaResolveElementReferences( 20920 (xmlSchemaElementPtr) item, pctxt); 20921 FIXHFAILURE; 20922 break; 20923 case XML_SCHEMA_TYPE_COMPLEX: 20924 case XML_SCHEMA_TYPE_SIMPLE: 20925 xmlSchemaResolveTypeReferences( 20926 (xmlSchemaTypePtr) item, pctxt); 20927 FIXHFAILURE; 20928 break; 20929 case XML_SCHEMA_TYPE_ATTRIBUTE: 20930 xmlSchemaResolveAttrTypeReferences( 20931 (xmlSchemaAttributePtr) item, pctxt); 20932 FIXHFAILURE; 20933 break; 20934 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20935 xmlSchemaResolveAttrUseReferences( 20936 (xmlSchemaAttributeUsePtr) item, pctxt); 20937 FIXHFAILURE; 20938 break; 20939 case XML_SCHEMA_EXTRA_QNAMEREF: 20940 if ((WXS_QNAME_CAST item)->itemType == 20941 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20942 { 20943 xmlSchemaResolveAttrGroupReferences( 20944 WXS_QNAME_CAST item, pctxt); 20945 } 20946 FIXHFAILURE; 20947 break; 20948 case XML_SCHEMA_TYPE_SEQUENCE: 20949 case XML_SCHEMA_TYPE_CHOICE: 20950 case XML_SCHEMA_TYPE_ALL: 20951 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20952 WXS_MODEL_GROUP_CAST item); 20953 FIXHFAILURE; 20954 break; 20955 case XML_SCHEMA_TYPE_IDC_KEY: 20956 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20957 case XML_SCHEMA_TYPE_IDC_KEYREF: 20958 xmlSchemaResolveIDCKeyReferences( 20959 (xmlSchemaIDCPtr) item, pctxt); 20960 FIXHFAILURE; 20961 break; 20962 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20963 /* 20964 * Handle attribue prohibition which had a 20965 * "ref" attribute. 20966 */ 20967 xmlSchemaResolveAttrUseProhibReferences( 20968 WXS_ATTR_PROHIB_CAST item, pctxt); 20969 FIXHFAILURE; 20970 break; 20971 default: 20972 break; 20973 } 20974 } 20975 if (pctxt->nberrors != 0) 20976 goto exit_error; 20977 20978 /* 20979 * Now that all references are resolved we 20980 * can check for circularity of... 20981 * 1. the base axis of type definitions 20982 * 2. nested model group definitions 20983 * 3. nested attribute group definitions 20984 * TODO: check for circular substitution groups. 20985 */ 20986 for (i = 0; i < nbItems; i++) { 20987 item = items[i]; 20988 /* 20989 * Let's better stop on the first error here. 20990 */ 20991 switch (item->type) { 20992 case XML_SCHEMA_TYPE_COMPLEX: 20993 case XML_SCHEMA_TYPE_SIMPLE: 20994 xmlSchemaCheckTypeDefCircular( 20995 (xmlSchemaTypePtr) item, pctxt); 20996 FIXHFAILURE; 20997 if (pctxt->nberrors != 0) 20998 goto exit_error; 20999 break; 21000 case XML_SCHEMA_TYPE_GROUP: 21001 xmlSchemaCheckGroupDefCircular( 21002 (xmlSchemaModelGroupDefPtr) item, pctxt); 21003 FIXHFAILURE; 21004 if (pctxt->nberrors != 0) 21005 goto exit_error; 21006 break; 21007 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21008 xmlSchemaCheckAttrGroupCircular( 21009 (xmlSchemaAttributeGroupPtr) item, pctxt); 21010 FIXHFAILURE; 21011 if (pctxt->nberrors != 0) 21012 goto exit_error; 21013 break; 21014 default: 21015 break; 21016 } 21017 } 21018 if (pctxt->nberrors != 0) 21019 goto exit_error; 21020 /* 21021 * Model group definition references: 21022 * Such a reference is reflected by a particle at the component 21023 * level. Until now the 'term' of such particles pointed 21024 * to the model group definition; this was done, in order to 21025 * ease circularity checks. Now we need to set the 'term' of 21026 * such particles to the model group of the model group definition. 21027 */ 21028 for (i = 0; i < nbItems; i++) { 21029 item = items[i]; 21030 switch (item->type) { 21031 case XML_SCHEMA_TYPE_SEQUENCE: 21032 case XML_SCHEMA_TYPE_CHOICE: 21033 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 21034 WXS_MODEL_GROUP_CAST item); 21035 break; 21036 default: 21037 break; 21038 } 21039 } 21040 if (pctxt->nberrors != 0) 21041 goto exit_error; 21042 /* 21043 * Expand attribute group references of attribute group definitions. 21044 */ 21045 for (i = 0; i < nbItems; i++) { 21046 item = items[i]; 21047 switch (item->type) { 21048 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21049 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 21050 WXS_ATTR_GROUP_HAS_REFS(item)) 21051 { 21052 xmlSchemaAttributeGroupExpandRefs(pctxt, 21053 WXS_ATTR_GROUP_CAST item); 21054 FIXHFAILURE; 21055 } 21056 break; 21057 default: 21058 break; 21059 } 21060 } 21061 if (pctxt->nberrors != 0) 21062 goto exit_error; 21063 /* 21064 * First compute the variety of simple types. This is needed as 21065 * a separate step, since otherwise we won't be able to detect 21066 * circular union types in all cases. 21067 */ 21068 for (i = 0; i < nbItems; i++) { 21069 item = items[i]; 21070 switch (item->type) { 21071 case XML_SCHEMA_TYPE_SIMPLE: 21072 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21073 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21074 (xmlSchemaTypePtr) item); 21075 FIXHFAILURE; 21076 } 21077 break; 21078 default: 21079 break; 21080 } 21081 } 21082 if (pctxt->nberrors != 0) 21083 goto exit_error; 21084 /* 21085 * Detect circular union types. Note that this needs the variety to 21086 * be already computed. 21087 */ 21088 for (i = 0; i < nbItems; i++) { 21089 item = items[i]; 21090 switch (item->type) { 21091 case XML_SCHEMA_TYPE_SIMPLE: 21092 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21093 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21094 (xmlSchemaTypePtr) item); 21095 FIXHFAILURE; 21096 } 21097 break; 21098 default: 21099 break; 21100 } 21101 } 21102 if (pctxt->nberrors != 0) 21103 goto exit_error; 21104 21105 /* 21106 * Do the complete type fixup for simple types. 21107 */ 21108 for (i = 0; i < nbItems; i++) { 21109 item = items[i]; 21110 switch (item->type) { 21111 case XML_SCHEMA_TYPE_SIMPLE: 21112 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21113 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21114 FIXHFAILURE; 21115 } 21116 break; 21117 default: 21118 break; 21119 } 21120 } 21121 if (pctxt->nberrors != 0) 21122 goto exit_error; 21123 /* 21124 * At this point we need build and check all simple types. 21125 */ 21126 /* 21127 * Apply constraints for attribute declarations. 21128 */ 21129 for (i = 0; i < nbItems; i++) { 21130 item = items[i]; 21131 switch (item->type) { 21132 case XML_SCHEMA_TYPE_ATTRIBUTE: 21133 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21134 FIXHFAILURE; 21135 break; 21136 default: 21137 break; 21138 } 21139 } 21140 if (pctxt->nberrors != 0) 21141 goto exit_error; 21142 /* 21143 * Apply constraints for attribute uses. 21144 */ 21145 for (i = 0; i < nbItems; i++) { 21146 item = items[i]; 21147 switch (item->type) { 21148 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21149 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21150 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21151 WXS_ATTR_USE_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 attribute group definitions. 21164 */ 21165 for (i = 0; i < nbItems; i++) { 21166 item = items[i]; 21167 switch (item->type) { 21168 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21169 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21170 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21171 { 21172 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21173 FIXHFAILURE; 21174 } 21175 break; 21176 default: 21177 break; 21178 } 21179 } 21180 if (pctxt->nberrors != 0) 21181 goto exit_error; 21182 21183 /* 21184 * Apply constraints for redefinitions. 21185 */ 21186 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21187 xmlSchemaCheckSRCRedefineSecond(pctxt); 21188 if (pctxt->nberrors != 0) 21189 goto exit_error; 21190 21191 /* 21192 * Complex types are built and checked. 21193 */ 21194 for (i = 0; i < nbItems; i++) { 21195 item = con->pending->items[i]; 21196 switch (item->type) { 21197 case XML_SCHEMA_TYPE_COMPLEX: 21198 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21199 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21200 FIXHFAILURE; 21201 } 21202 break; 21203 default: 21204 break; 21205 } 21206 } 21207 if (pctxt->nberrors != 0) 21208 goto exit_error; 21209 21210 /* 21211 * The list could have changed, since xmlSchemaFixupComplexType() 21212 * will create particles and model groups in some cases. 21213 */ 21214 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21215 nbItems = con->pending->nbItems; 21216 21217 /* 21218 * Apply some constraints for element declarations. 21219 */ 21220 for (i = 0; i < nbItems; i++) { 21221 item = items[i]; 21222 switch (item->type) { 21223 case XML_SCHEMA_TYPE_ELEMENT: 21224 elemDecl = (xmlSchemaElementPtr) item; 21225 21226 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21227 { 21228 xmlSchemaCheckElementDeclComponent( 21229 (xmlSchemaElementPtr) elemDecl, pctxt); 21230 FIXHFAILURE; 21231 } 21232 21233 #ifdef WXS_ELEM_DECL_CONS_ENABLED 21234 /* 21235 * Schema Component Constraint: Element Declarations Consistent 21236 * Apply this constraint to local types of element declarations. 21237 */ 21238 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21239 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21240 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21241 { 21242 xmlSchemaCheckElementDeclConsistent(pctxt, 21243 WXS_BASIC_CAST elemDecl, 21244 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21245 NULL, NULL, 0); 21246 } 21247 #endif 21248 break; 21249 default: 21250 break; 21251 } 21252 } 21253 if (pctxt->nberrors != 0) 21254 goto exit_error; 21255 21256 /* 21257 * Finally we can build the automaton from the content model of 21258 * complex types. 21259 */ 21260 21261 for (i = 0; i < nbItems; i++) { 21262 item = items[i]; 21263 switch (item->type) { 21264 case XML_SCHEMA_TYPE_COMPLEX: 21265 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21266 /* FIXHFAILURE; */ 21267 break; 21268 default: 21269 break; 21270 } 21271 } 21272 if (pctxt->nberrors != 0) 21273 goto exit_error; 21274 /* 21275 * URGENT TODO: cos-element-consistent 21276 */ 21277 goto exit; 21278 21279 exit_error: 21280 ret = pctxt->err; 21281 goto exit; 21282 21283 exit_failure: 21284 ret = -1; 21285 21286 exit: 21287 /* 21288 * Reset the constructor. This is needed for XSI acquisition, since 21289 * those items will be processed over and over again for every XSI 21290 * if not cleared here. 21291 */ 21292 con->bucket = oldbucket; 21293 con->pending->nbItems = 0; 21294 if (con->substGroups != NULL) { 21295 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); 21296 con->substGroups = NULL; 21297 } 21298 if (con->redefs != NULL) { 21299 xmlSchemaRedefListFree(con->redefs); 21300 con->redefs = NULL; 21301 } 21302 return(ret); 21303 } 21304 /** 21305 * xmlSchemaParse: 21306 * @ctxt: a schema validation context 21307 * 21308 * parse a schema definition resource and build an internal 21309 * XML Schema structure which can be used to validate instances. 21310 * 21311 * Returns the internal XML Schema structure built from the resource or 21312 * NULL in case of error 21313 */ 21314 xmlSchemaPtr 21315 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21316 { 21317 xmlSchemaPtr mainSchema = NULL; 21318 xmlSchemaBucketPtr bucket = NULL; 21319 int res; 21320 21321 /* 21322 * This one is used if the schema to be parsed was specified via 21323 * the API; i.e. not automatically by the validated instance document. 21324 */ 21325 21326 xmlSchemaInitTypes(); 21327 21328 if (ctxt == NULL) 21329 return (NULL); 21330 21331 /* TODO: Init the context. Is this all we need?*/ 21332 ctxt->nberrors = 0; 21333 ctxt->err = 0; 21334 ctxt->counter = 0; 21335 21336 /* Create the *main* schema. */ 21337 mainSchema = xmlSchemaNewSchema(ctxt); 21338 if (mainSchema == NULL) 21339 goto exit_failure; 21340 /* 21341 * Create the schema constructor. 21342 */ 21343 if (ctxt->constructor == NULL) { 21344 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21345 if (ctxt->constructor == NULL) 21346 return(NULL); 21347 /* Take ownership of the constructor to be able to free it. */ 21348 ctxt->ownsConstructor = 1; 21349 } 21350 ctxt->constructor->mainSchema = mainSchema; 21351 /* 21352 * Locate and add the schema document. 21353 */ 21354 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21355 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21356 NULL, NULL, &bucket); 21357 if (res == -1) 21358 goto exit_failure; 21359 if (res != 0) 21360 goto exit; 21361 21362 if (bucket == NULL) { 21363 /* TODO: Error code, actually we failed to *locate* the schema. */ 21364 if (ctxt->URL) 21365 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21366 NULL, NULL, 21367 "Failed to locate the main schema resource at '%s'", 21368 ctxt->URL, NULL); 21369 else 21370 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21371 NULL, NULL, 21372 "Failed to locate the main schema resource", 21373 NULL, NULL); 21374 goto exit; 21375 } 21376 /* Then do the parsing for good. */ 21377 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21378 goto exit_failure; 21379 if (ctxt->nberrors != 0) 21380 goto exit; 21381 21382 mainSchema->doc = bucket->doc; 21383 mainSchema->preserve = ctxt->preserve; 21384 21385 ctxt->schema = mainSchema; 21386 21387 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21388 goto exit_failure; 21389 21390 /* 21391 * TODO: This is not nice, since we cannot distinguish from the 21392 * result if there was an internal error or not. 21393 */ 21394 exit: 21395 if (ctxt->nberrors != 0) { 21396 if (mainSchema) { 21397 xmlSchemaFree(mainSchema); 21398 mainSchema = NULL; 21399 } 21400 if (ctxt->constructor) { 21401 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21402 ctxt->constructor = NULL; 21403 ctxt->ownsConstructor = 0; 21404 } 21405 } 21406 ctxt->schema = NULL; 21407 return(mainSchema); 21408 exit_failure: 21409 /* 21410 * Quite verbose, but should catch internal errors, which were 21411 * not communicated. 21412 */ 21413 if (mainSchema) { 21414 xmlSchemaFree(mainSchema); 21415 mainSchema = NULL; 21416 } 21417 if (ctxt->constructor) { 21418 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21419 ctxt->constructor = NULL; 21420 ctxt->ownsConstructor = 0; 21421 } 21422 PERROR_INT2("xmlSchemaParse", 21423 "An internal error occurred"); 21424 ctxt->schema = NULL; 21425 return(NULL); 21426 } 21427 21428 /** 21429 * xmlSchemaSetParserErrors: 21430 * @ctxt: a schema validation context 21431 * @err: the error callback 21432 * @warn: the warning callback 21433 * @ctx: contextual data for the callbacks 21434 * 21435 * Set the callback functions used to handle errors for a validation context 21436 */ 21437 void 21438 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21439 xmlSchemaValidityErrorFunc err, 21440 xmlSchemaValidityWarningFunc warn, void *ctx) 21441 { 21442 if (ctxt == NULL) 21443 return; 21444 ctxt->error = err; 21445 ctxt->warning = warn; 21446 ctxt->errCtxt = ctx; 21447 if (ctxt->vctxt != NULL) 21448 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21449 } 21450 21451 /** 21452 * xmlSchemaSetParserStructuredErrors: 21453 * @ctxt: a schema parser context 21454 * @serror: the structured error function 21455 * @ctx: the functions context 21456 * 21457 * Set the structured error callback 21458 */ 21459 void 21460 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21461 xmlStructuredErrorFunc serror, 21462 void *ctx) 21463 { 21464 if (ctxt == NULL) 21465 return; 21466 ctxt->serror = serror; 21467 ctxt->errCtxt = ctx; 21468 if (ctxt->vctxt != NULL) 21469 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21470 } 21471 21472 /** 21473 * xmlSchemaGetParserErrors: 21474 * @ctxt: a XMl-Schema parser context 21475 * @err: the error callback result 21476 * @warn: the warning callback result 21477 * @ctx: contextual data for the callbacks result 21478 * 21479 * Get the callback information used to handle errors for a parser context 21480 * 21481 * Returns -1 in case of failure, 0 otherwise 21482 */ 21483 int 21484 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21485 xmlSchemaValidityErrorFunc * err, 21486 xmlSchemaValidityWarningFunc * warn, void **ctx) 21487 { 21488 if (ctxt == NULL) 21489 return(-1); 21490 if (err != NULL) 21491 *err = ctxt->error; 21492 if (warn != NULL) 21493 *warn = ctxt->warning; 21494 if (ctx != NULL) 21495 *ctx = ctxt->errCtxt; 21496 return(0); 21497 } 21498 21499 /** 21500 * xmlSchemaFacetTypeToString: 21501 * @type: the facet type 21502 * 21503 * Convert the xmlSchemaTypeType to a char string. 21504 * 21505 * Returns the char string representation of the facet type if the 21506 * type is a facet and an "Internal Error" string otherwise. 21507 */ 21508 static const xmlChar * 21509 xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21510 { 21511 switch (type) { 21512 case XML_SCHEMA_FACET_PATTERN: 21513 return (BAD_CAST "pattern"); 21514 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21515 return (BAD_CAST "maxExclusive"); 21516 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21517 return (BAD_CAST "maxInclusive"); 21518 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21519 return (BAD_CAST "minExclusive"); 21520 case XML_SCHEMA_FACET_MININCLUSIVE: 21521 return (BAD_CAST "minInclusive"); 21522 case XML_SCHEMA_FACET_WHITESPACE: 21523 return (BAD_CAST "whiteSpace"); 21524 case XML_SCHEMA_FACET_ENUMERATION: 21525 return (BAD_CAST "enumeration"); 21526 case XML_SCHEMA_FACET_LENGTH: 21527 return (BAD_CAST "length"); 21528 case XML_SCHEMA_FACET_MAXLENGTH: 21529 return (BAD_CAST "maxLength"); 21530 case XML_SCHEMA_FACET_MINLENGTH: 21531 return (BAD_CAST "minLength"); 21532 case XML_SCHEMA_FACET_TOTALDIGITS: 21533 return (BAD_CAST "totalDigits"); 21534 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21535 return (BAD_CAST "fractionDigits"); 21536 default: 21537 break; 21538 } 21539 return (BAD_CAST "Internal Error"); 21540 } 21541 21542 static xmlSchemaWhitespaceValueType 21543 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21544 { 21545 /* 21546 * The normalization type can be changed only for types which are derived 21547 * from xsd:string. 21548 */ 21549 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21550 /* 21551 * Note that we assume a whitespace of preserve for anySimpleType. 21552 */ 21553 if ((type->builtInType == XML_SCHEMAS_STRING) || 21554 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21555 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21556 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21557 return(XML_SCHEMA_WHITESPACE_REPLACE); 21558 else { 21559 /* 21560 * For all `atomic` datatypes other than string (and types `derived` 21561 * by `restriction` from it) the value of whiteSpace is fixed to 21562 * collapse 21563 * Note that this includes built-in list datatypes. 21564 */ 21565 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21566 } 21567 } else if (WXS_IS_LIST(type)) { 21568 /* 21569 * For list types the facet "whiteSpace" is fixed to "collapse". 21570 */ 21571 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21572 } else if (WXS_IS_UNION(type)) { 21573 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21574 } else if (WXS_IS_ATOMIC(type)) { 21575 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21576 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21577 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21578 return (XML_SCHEMA_WHITESPACE_REPLACE); 21579 else 21580 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21581 } 21582 return (-1); 21583 } 21584 21585 /************************************************************************ 21586 * * 21587 * Simple type validation * 21588 * * 21589 ************************************************************************/ 21590 21591 21592 /************************************************************************ 21593 * * 21594 * DOM Validation code * 21595 * * 21596 ************************************************************************/ 21597 21598 /** 21599 * xmlSchemaAssembleByLocation: 21600 * @pctxt: a schema parser context 21601 * @vctxt: a schema validation context 21602 * @schema: the existing schema 21603 * @node: the node that fired the assembling 21604 * @nsName: the namespace name of the new schema 21605 * @location: the location of the schema 21606 * 21607 * Expands an existing schema by an additional schema. 21608 * 21609 * Returns 0 if the new schema is correct, a positive error code 21610 * number otherwise and -1 in case of an internal or API error. 21611 */ 21612 static int 21613 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21614 xmlSchemaPtr schema, 21615 xmlNodePtr node, 21616 const xmlChar *nsName, 21617 const xmlChar *location) 21618 { 21619 int ret = 0; 21620 xmlSchemaParserCtxtPtr pctxt; 21621 xmlSchemaBucketPtr bucket = NULL; 21622 21623 if ((vctxt == NULL) || (schema == NULL)) 21624 return (-1); 21625 21626 if (vctxt->pctxt == NULL) { 21627 VERROR_INT("xmlSchemaAssembleByLocation", 21628 "no parser context available"); 21629 return(-1); 21630 } 21631 pctxt = vctxt->pctxt; 21632 if (pctxt->constructor == NULL) { 21633 PERROR_INT("xmlSchemaAssembleByLocation", 21634 "no constructor"); 21635 return(-1); 21636 } 21637 /* 21638 * Acquire the schema document. 21639 */ 21640 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21641 location, node); 21642 /* 21643 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21644 * the process will automatically change this to 21645 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21646 */ 21647 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21648 location, NULL, NULL, 0, node, NULL, nsName, 21649 &bucket); 21650 if (ret != 0) 21651 return(ret); 21652 if (bucket == NULL) { 21653 /* 21654 * Generate a warning that the document could not be located. 21655 */ 21656 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21657 node, NULL, 21658 "The document at location '%s' could not be acquired", 21659 location, NULL, NULL); 21660 return(ret); 21661 } 21662 /* 21663 * The first located schema will be handled as if all other 21664 * schemas imported by XSI were imported by this first schema. 21665 */ 21666 if ((bucket != NULL) && 21667 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21668 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21669 /* 21670 * TODO: Is this handled like an import? I.e. is it not an error 21671 * if the schema cannot be located? 21672 */ 21673 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21674 return(0); 21675 /* 21676 * We will reuse the parser context for every schema imported 21677 * directly via XSI. So reset the context. 21678 */ 21679 pctxt->nberrors = 0; 21680 pctxt->err = 0; 21681 pctxt->doc = bucket->doc; 21682 21683 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21684 if (ret == -1) { 21685 pctxt->doc = NULL; 21686 goto exit_failure; 21687 } 21688 /* Paranoid error channelling. */ 21689 if ((ret == 0) && (pctxt->nberrors != 0)) 21690 ret = pctxt->err; 21691 if (pctxt->nberrors == 0) { 21692 /* 21693 * Only bother to fixup pending components, if there was 21694 * no error yet. 21695 * For every XSI acquired schema (and its sub-schemata) we will 21696 * fixup the components. 21697 */ 21698 xmlSchemaFixupComponents(pctxt, bucket); 21699 ret = pctxt->err; 21700 /* 21701 * Not nice, but we need somehow to channel the schema parser 21702 * error to the validation context. 21703 */ 21704 if ((ret != 0) && (vctxt->err == 0)) 21705 vctxt->err = ret; 21706 vctxt->nberrors += pctxt->nberrors; 21707 } else { 21708 /* Add to validation error sum. */ 21709 vctxt->nberrors += pctxt->nberrors; 21710 } 21711 pctxt->doc = NULL; 21712 return(ret); 21713 exit_failure: 21714 pctxt->doc = NULL; 21715 return (-1); 21716 } 21717 21718 static xmlSchemaAttrInfoPtr 21719 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21720 int metaType) 21721 { 21722 if (vctxt->nbAttrInfos == 0) 21723 return (NULL); 21724 { 21725 int i; 21726 xmlSchemaAttrInfoPtr iattr; 21727 21728 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21729 iattr = vctxt->attrInfos[i]; 21730 if (iattr->metaType == metaType) 21731 return (iattr); 21732 } 21733 21734 } 21735 return (NULL); 21736 } 21737 21738 /** 21739 * xmlSchemaAssembleByXSI: 21740 * @vctxt: a schema validation context 21741 * 21742 * Expands an existing schema by an additional schema using 21743 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute 21744 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace 21745 * must be set to 1. 21746 * 21747 * Returns 0 if the new schema is correct, a positive error code 21748 * number otherwise and -1 in case of an internal or API error. 21749 */ 21750 static int 21751 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21752 { 21753 const xmlChar *cur, *end; 21754 const xmlChar *nsname = NULL, *location; 21755 int count = 0; 21756 int ret = 0; 21757 xmlSchemaAttrInfoPtr iattr; 21758 21759 /* 21760 * Parse the value; we will assume an even number of values 21761 * to be given (this is how Xerces and XSV work). 21762 * 21763 * URGENT TODO: !! This needs to work for both 21764 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21765 * element !! 21766 */ 21767 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21768 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21769 if (iattr == NULL) 21770 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21771 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21772 if (iattr == NULL) 21773 return (0); 21774 cur = iattr->value; 21775 do { 21776 /* 21777 * TODO: Move the string parsing mechanism away from here. 21778 */ 21779 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21780 /* 21781 * Get the namespace name. 21782 */ 21783 while (IS_BLANK_CH(*cur)) 21784 cur++; 21785 end = cur; 21786 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21787 end++; 21788 if (end == cur) 21789 break; 21790 count++; /* TODO: Don't use the schema's dict. */ 21791 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21792 cur = end; 21793 } 21794 /* 21795 * Get the URI. 21796 */ 21797 while (IS_BLANK_CH(*cur)) 21798 cur++; 21799 end = cur; 21800 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21801 end++; 21802 if (end == cur) { 21803 if (iattr->metaType == 21804 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21805 { 21806 /* 21807 * If using @schemaLocation then tuples are expected. 21808 * I.e. the namespace name *and* the document's URI. 21809 */ 21810 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21811 iattr->node, NULL, 21812 "The value must consist of tuples: the target namespace " 21813 "name and the document's URI", NULL, NULL, NULL); 21814 } 21815 break; 21816 } 21817 count++; /* TODO: Don't use the schema's dict. */ 21818 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21819 cur = end; 21820 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21821 iattr->node, nsname, location); 21822 if (ret == -1) { 21823 VERROR_INT("xmlSchemaAssembleByXSI", 21824 "assembling schemata"); 21825 return (-1); 21826 } 21827 } while (*cur != 0); 21828 return (ret); 21829 } 21830 21831 static const xmlChar * 21832 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21833 const xmlChar *prefix) 21834 { 21835 if (vctxt->sax != NULL) { 21836 int i, j; 21837 xmlSchemaNodeInfoPtr inode; 21838 21839 for (i = vctxt->depth; i >= 0; i--) { 21840 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21841 inode = vctxt->elemInfos[i]; 21842 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21843 if (((prefix == NULL) && 21844 (inode->nsBindings[j] == NULL)) || 21845 ((prefix != NULL) && xmlStrEqual(prefix, 21846 inode->nsBindings[j]))) { 21847 21848 /* 21849 * Note that the namespace bindings are already 21850 * in a string dict. 21851 */ 21852 return (inode->nsBindings[j+1]); 21853 } 21854 } 21855 } 21856 } 21857 return (NULL); 21858 #ifdef LIBXML_READER_ENABLED 21859 } else if (vctxt->reader != NULL) { 21860 xmlChar *nsName; 21861 21862 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21863 if (nsName != NULL) { 21864 const xmlChar *ret; 21865 21866 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21867 xmlFree(nsName); 21868 return (ret); 21869 } else 21870 return (NULL); 21871 #endif 21872 } else { 21873 xmlNsPtr ns; 21874 21875 if ((vctxt->inode->node == NULL) || 21876 (vctxt->inode->node->doc == NULL)) { 21877 VERROR_INT("xmlSchemaLookupNamespace", 21878 "no node or node's doc available"); 21879 return (NULL); 21880 } 21881 ns = xmlSearchNs(vctxt->inode->node->doc, 21882 vctxt->inode->node, prefix); 21883 if (ns != NULL) 21884 return (ns->href); 21885 return (NULL); 21886 } 21887 } 21888 21889 /* 21890 * This one works on the schema of the validation context. 21891 */ 21892 static int 21893 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21894 xmlSchemaPtr schema, 21895 xmlNodePtr node, 21896 const xmlChar *value, 21897 xmlSchemaValPtr *val, 21898 int valNeeded) 21899 { 21900 int ret; 21901 21902 if (vctxt && (vctxt->schema == NULL)) { 21903 VERROR_INT("xmlSchemaValidateNotation", 21904 "a schema is needed on the validation context"); 21905 return (-1); 21906 } 21907 ret = xmlValidateQName(value, 1); 21908 if (ret != 0) 21909 return (ret); 21910 { 21911 xmlChar *localName = NULL; 21912 xmlChar *prefix = NULL; 21913 21914 localName = xmlSplitQName2(value, &prefix); 21915 if (prefix != NULL) { 21916 const xmlChar *nsName = NULL; 21917 21918 if (vctxt != NULL) 21919 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21920 else if (node != NULL) { 21921 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21922 if (ns != NULL) 21923 nsName = ns->href; 21924 } else { 21925 xmlFree(prefix); 21926 xmlFree(localName); 21927 return (1); 21928 } 21929 if (nsName == NULL) { 21930 xmlFree(prefix); 21931 xmlFree(localName); 21932 return (1); 21933 } 21934 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21935 if ((valNeeded) && (val != NULL)) { 21936 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21937 xmlStrdup(nsName)); 21938 if (*val == NULL) 21939 ret = -1; 21940 } 21941 } else 21942 ret = 1; 21943 xmlFree(prefix); 21944 xmlFree(localName); 21945 } else { 21946 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21947 if (valNeeded && (val != NULL)) { 21948 (*val) = xmlSchemaNewNOTATIONValue( 21949 BAD_CAST xmlStrdup(value), NULL); 21950 if (*val == NULL) 21951 ret = -1; 21952 } 21953 } else 21954 return (1); 21955 } 21956 } 21957 return (ret); 21958 } 21959 21960 static int 21961 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21962 const xmlChar* lname, 21963 const xmlChar* nsname) 21964 { 21965 int i; 21966 21967 lname = xmlDictLookup(vctxt->dict, lname, -1); 21968 if (lname == NULL) 21969 return(-1); 21970 if (nsname != NULL) { 21971 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21972 if (nsname == NULL) 21973 return(-1); 21974 } 21975 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21976 if ((vctxt->nodeQNames->items [i] == lname) && 21977 (vctxt->nodeQNames->items[i +1] == nsname)) 21978 /* Already there */ 21979 return(i); 21980 } 21981 /* Add new entry. */ 21982 i = vctxt->nodeQNames->nbItems; 21983 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21984 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21985 return(i); 21986 } 21987 21988 /************************************************************************ 21989 * * 21990 * Validation of identity-constraints (IDC) * 21991 * * 21992 ************************************************************************/ 21993 21994 /** 21995 * xmlSchemaAugmentIDC: 21996 * @idcDef: the IDC definition 21997 * 21998 * Creates an augmented IDC definition item. 21999 * 22000 * Returns the item, or NULL on internal errors. 22001 */ 22002 static void 22003 xmlSchemaAugmentIDC(void *payload, void *data, 22004 const xmlChar *name ATTRIBUTE_UNUSED) 22005 { 22006 xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload; 22007 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; 22008 xmlSchemaIDCAugPtr aidc; 22009 22010 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 22011 if (aidc == NULL) { 22012 xmlSchemaVErrMemory(vctxt, 22013 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 22014 NULL); 22015 return; 22016 } 22017 aidc->keyrefDepth = -1; 22018 aidc->def = idcDef; 22019 aidc->next = NULL; 22020 if (vctxt->aidcs == NULL) 22021 vctxt->aidcs = aidc; 22022 else { 22023 aidc->next = vctxt->aidcs; 22024 vctxt->aidcs = aidc; 22025 } 22026 /* 22027 * Save if we have keyrefs at all. 22028 */ 22029 if ((vctxt->hasKeyrefs == 0) && 22030 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 22031 vctxt->hasKeyrefs = 1; 22032 } 22033 22034 /** 22035 * xmlSchemaAugmentImportedIDC: 22036 * @imported: the imported schema 22037 * 22038 * Creates an augmented IDC definition for the imported schema. 22039 */ 22040 static void 22041 xmlSchemaAugmentImportedIDC(void *payload, void *data, 22042 const xmlChar *name ATTRIBUTE_UNUSED) { 22043 xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload; 22044 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; 22045 if (imported->schema->idcDef != NULL) { 22046 xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt); 22047 } 22048 } 22049 22050 /** 22051 * xmlSchemaIDCNewBinding: 22052 * @idcDef: the IDC definition of this binding 22053 * 22054 * Creates a new IDC binding. 22055 * 22056 * Returns the new IDC binding, NULL on internal errors. 22057 */ 22058 static xmlSchemaPSVIIDCBindingPtr 22059 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22060 { 22061 xmlSchemaPSVIIDCBindingPtr ret; 22062 22063 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22064 sizeof(xmlSchemaPSVIIDCBinding)); 22065 if (ret == NULL) { 22066 xmlSchemaVErrMemory(NULL, 22067 "allocating a PSVI IDC binding item", NULL); 22068 return (NULL); 22069 } 22070 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22071 ret->definition = idcDef; 22072 return (ret); 22073 } 22074 22075 /** 22076 * xmlSchemaIDCStoreNodeTableItem: 22077 * @vctxt: the WXS validation context 22078 * @item: the IDC node table item 22079 * 22080 * The validation context is used to store IDC node table items. 22081 * They are stored to avoid copying them if IDC node-tables are merged 22082 * with corresponding parent IDC node-tables (bubbling). 22083 * 22084 * Returns 0 if succeeded, -1 on internal errors. 22085 */ 22086 static int 22087 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22088 xmlSchemaPSVIIDCNodePtr item) 22089 { 22090 /* 22091 * Add to global list. 22092 */ 22093 if (vctxt->idcNodes == NULL) { 22094 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22095 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22096 if (vctxt->idcNodes == NULL) { 22097 xmlSchemaVErrMemory(vctxt, 22098 "allocating the IDC node table item list", NULL); 22099 return (-1); 22100 } 22101 vctxt->sizeIdcNodes = 20; 22102 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22103 vctxt->sizeIdcNodes *= 2; 22104 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22105 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22106 sizeof(xmlSchemaPSVIIDCNodePtr)); 22107 if (vctxt->idcNodes == NULL) { 22108 xmlSchemaVErrMemory(vctxt, 22109 "re-allocating the IDC node table item list", NULL); 22110 return (-1); 22111 } 22112 } 22113 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22114 22115 return (0); 22116 } 22117 22118 /** 22119 * xmlSchemaIDCStoreKey: 22120 * @vctxt: the WXS validation context 22121 * @item: the IDC key 22122 * 22123 * The validation context is used to store an IDC key. 22124 * 22125 * Returns 0 if succeeded, -1 on internal errors. 22126 */ 22127 static int 22128 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22129 xmlSchemaPSVIIDCKeyPtr key) 22130 { 22131 /* 22132 * Add to global list. 22133 */ 22134 if (vctxt->idcKeys == NULL) { 22135 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22136 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22137 if (vctxt->idcKeys == NULL) { 22138 xmlSchemaVErrMemory(vctxt, 22139 "allocating the IDC key storage list", NULL); 22140 return (-1); 22141 } 22142 vctxt->sizeIdcKeys = 40; 22143 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22144 vctxt->sizeIdcKeys *= 2; 22145 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22146 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22147 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22148 if (vctxt->idcKeys == NULL) { 22149 xmlSchemaVErrMemory(vctxt, 22150 "re-allocating the IDC key storage list", NULL); 22151 return (-1); 22152 } 22153 } 22154 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22155 22156 return (0); 22157 } 22158 22159 /** 22160 * xmlSchemaIDCAppendNodeTableItem: 22161 * @bind: the IDC binding 22162 * @ntItem: the node-table item 22163 * 22164 * Appends the IDC node-table item to the binding. 22165 * 22166 * Returns 0 on success and -1 on internal errors. 22167 */ 22168 static int 22169 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22170 xmlSchemaPSVIIDCNodePtr ntItem) 22171 { 22172 if (bind->nodeTable == NULL) { 22173 bind->sizeNodes = 10; 22174 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22175 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22176 if (bind->nodeTable == NULL) { 22177 xmlSchemaVErrMemory(NULL, 22178 "allocating an array of IDC node-table items", NULL); 22179 return(-1); 22180 } 22181 } else if (bind->sizeNodes <= bind->nbNodes) { 22182 bind->sizeNodes *= 2; 22183 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22184 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22185 sizeof(xmlSchemaPSVIIDCNodePtr)); 22186 if (bind->nodeTable == NULL) { 22187 xmlSchemaVErrMemory(NULL, 22188 "re-allocating an array of IDC node-table items", NULL); 22189 return(-1); 22190 } 22191 } 22192 bind->nodeTable[bind->nbNodes++] = ntItem; 22193 return(0); 22194 } 22195 22196 /** 22197 * xmlSchemaIDCAcquireBinding: 22198 * @vctxt: the WXS validation context 22199 * @matcher: the IDC matcher 22200 * 22201 * Looks up an PSVI IDC binding, for the IDC definition and 22202 * of the given matcher. If none found, a new one is created 22203 * and added to the IDC table. 22204 * 22205 * Returns an IDC binding or NULL on internal errors. 22206 */ 22207 static xmlSchemaPSVIIDCBindingPtr 22208 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22209 xmlSchemaIDCMatcherPtr matcher) 22210 { 22211 xmlSchemaNodeInfoPtr ielem; 22212 22213 ielem = vctxt->elemInfos[matcher->depth]; 22214 22215 if (ielem->idcTable == NULL) { 22216 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22217 if (ielem->idcTable == NULL) 22218 return (NULL); 22219 return(ielem->idcTable); 22220 } else { 22221 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22222 22223 bind = ielem->idcTable; 22224 do { 22225 if (bind->definition == matcher->aidc->def) 22226 return(bind); 22227 if (bind->next == NULL) { 22228 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22229 if (bind->next == NULL) 22230 return (NULL); 22231 return(bind->next); 22232 } 22233 bind = bind->next; 22234 } while (bind != NULL); 22235 } 22236 return (NULL); 22237 } 22238 22239 static xmlSchemaItemListPtr 22240 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22241 xmlSchemaIDCMatcherPtr matcher) 22242 { 22243 if (matcher->targets == NULL) 22244 matcher->targets = xmlSchemaItemListCreate(); 22245 return(matcher->targets); 22246 } 22247 22248 /** 22249 * xmlSchemaIDCFreeKey: 22250 * @key: the IDC key 22251 * 22252 * Frees an IDC key together with its compiled value. 22253 */ 22254 static void 22255 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22256 { 22257 if (key->val != NULL) 22258 xmlSchemaFreeValue(key->val); 22259 xmlFree(key); 22260 } 22261 22262 /** 22263 * xmlSchemaIDCFreeBinding: 22264 * 22265 * Frees an IDC binding. Note that the node table-items 22266 * are not freed. 22267 */ 22268 static void 22269 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22270 { 22271 if (bind->nodeTable != NULL) 22272 xmlFree(bind->nodeTable); 22273 if (bind->dupls != NULL) 22274 xmlSchemaItemListFree(bind->dupls); 22275 xmlFree(bind); 22276 } 22277 22278 /** 22279 * xmlSchemaIDCFreeIDCTable: 22280 * @bind: the first IDC binding in the list 22281 * 22282 * Frees an IDC table, i.e. all the IDC bindings in the list. 22283 */ 22284 static void 22285 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22286 { 22287 xmlSchemaPSVIIDCBindingPtr prev; 22288 22289 while (bind != NULL) { 22290 prev = bind; 22291 bind = bind->next; 22292 xmlSchemaIDCFreeBinding(prev); 22293 } 22294 } 22295 22296 /** 22297 * xmlSchemaIDCFreeMatcherList: 22298 * @matcher: the first IDC matcher in the list 22299 * 22300 * Frees a list of IDC matchers. 22301 */ 22302 static void 22303 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22304 { 22305 xmlSchemaIDCMatcherPtr next; 22306 22307 while (matcher != NULL) { 22308 next = matcher->next; 22309 if (matcher->keySeqs != NULL) { 22310 int i; 22311 for (i = 0; i < matcher->sizeKeySeqs; i++) 22312 if (matcher->keySeqs[i] != NULL) 22313 xmlFree(matcher->keySeqs[i]); 22314 xmlFree(matcher->keySeqs); 22315 } 22316 if (matcher->targets != NULL) { 22317 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22318 int i; 22319 xmlSchemaPSVIIDCNodePtr idcNode; 22320 /* 22321 * Node-table items for keyrefs are not stored globally 22322 * to the validation context, since they are not bubbled. 22323 * We need to free them here. 22324 */ 22325 for (i = 0; i < matcher->targets->nbItems; i++) { 22326 idcNode = 22327 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22328 xmlFree(idcNode->keys); 22329 xmlFree(idcNode); 22330 } 22331 } 22332 xmlSchemaItemListFree(matcher->targets); 22333 } 22334 xmlFree(matcher); 22335 matcher = next; 22336 } 22337 } 22338 22339 /** 22340 * xmlSchemaIDCReleaseMatcherList: 22341 * @vctxt: the WXS validation context 22342 * @matcher: the first IDC matcher in the list 22343 * 22344 * Caches a list of IDC matchers for reuse. 22345 */ 22346 static void 22347 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22348 xmlSchemaIDCMatcherPtr matcher) 22349 { 22350 xmlSchemaIDCMatcherPtr next; 22351 22352 while (matcher != NULL) { 22353 next = matcher->next; 22354 if (matcher->keySeqs != NULL) { 22355 int i; 22356 /* 22357 * Don't free the array, but only the content. 22358 */ 22359 for (i = 0; i < matcher->sizeKeySeqs; i++) 22360 if (matcher->keySeqs[i] != NULL) { 22361 xmlFree(matcher->keySeqs[i]); 22362 matcher->keySeqs[i] = NULL; 22363 } 22364 } 22365 if (matcher->targets) { 22366 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22367 int i; 22368 xmlSchemaPSVIIDCNodePtr idcNode; 22369 /* 22370 * Node-table items for keyrefs are not stored globally 22371 * to the validation context, since they are not bubbled. 22372 * We need to free them here. 22373 */ 22374 for (i = 0; i < matcher->targets->nbItems; i++) { 22375 idcNode = 22376 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22377 xmlFree(idcNode->keys); 22378 xmlFree(idcNode); 22379 } 22380 } 22381 xmlSchemaItemListFree(matcher->targets); 22382 matcher->targets = NULL; 22383 } 22384 matcher->next = NULL; 22385 /* 22386 * Cache the matcher. 22387 */ 22388 if (vctxt->idcMatcherCache != NULL) 22389 matcher->nextCached = vctxt->idcMatcherCache; 22390 vctxt->idcMatcherCache = matcher; 22391 22392 matcher = next; 22393 } 22394 } 22395 22396 /** 22397 * xmlSchemaIDCAddStateObject: 22398 * @vctxt: the WXS validation context 22399 * @matcher: the IDC matcher 22400 * @sel: the XPath information 22401 * @parent: the parent "selector" state object if any 22402 * @type: "selector" or "field" 22403 * 22404 * Creates/reuses and activates state objects for the given 22405 * XPath information; if the XPath expression consists of unions, 22406 * multiple state objects are created for every unioned expression. 22407 * 22408 * Returns 0 on success and -1 on internal errors. 22409 */ 22410 static int 22411 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22412 xmlSchemaIDCMatcherPtr matcher, 22413 xmlSchemaIDCSelectPtr sel, 22414 int type) 22415 { 22416 xmlSchemaIDCStateObjPtr sto; 22417 22418 /* 22419 * Reuse the state objects from the pool. 22420 */ 22421 if (vctxt->xpathStatePool != NULL) { 22422 sto = vctxt->xpathStatePool; 22423 vctxt->xpathStatePool = sto->next; 22424 sto->next = NULL; 22425 } else { 22426 /* 22427 * Create a new state object. 22428 */ 22429 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22430 if (sto == NULL) { 22431 xmlSchemaVErrMemory(NULL, 22432 "allocating an IDC state object", NULL); 22433 return (-1); 22434 } 22435 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22436 } 22437 /* 22438 * Add to global list. 22439 */ 22440 if (vctxt->xpathStates != NULL) 22441 sto->next = vctxt->xpathStates; 22442 vctxt->xpathStates = sto; 22443 22444 /* 22445 * Free the old xpath validation context. 22446 */ 22447 if (sto->xpathCtxt != NULL) 22448 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22449 22450 /* 22451 * Create a new XPath (pattern) validation context. 22452 */ 22453 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22454 (xmlPatternPtr) sel->xpathComp); 22455 if (sto->xpathCtxt == NULL) { 22456 VERROR_INT("xmlSchemaIDCAddStateObject", 22457 "failed to create an XPath validation context"); 22458 return (-1); 22459 } 22460 sto->type = type; 22461 sto->depth = vctxt->depth; 22462 sto->matcher = matcher; 22463 sto->sel = sel; 22464 sto->nbHistory = 0; 22465 22466 #ifdef DEBUG_IDC 22467 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22468 sto->sel->xpath); 22469 #endif 22470 return (0); 22471 } 22472 22473 /** 22474 * xmlSchemaXPathEvaluate: 22475 * @vctxt: the WXS validation context 22476 * @nodeType: the nodeType of the current node 22477 * 22478 * Evaluates all active XPath state objects. 22479 * 22480 * Returns the number of IC "field" state objects which resolved to 22481 * this node, 0 if none resolved and -1 on internal errors. 22482 */ 22483 static int 22484 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22485 xmlElementType nodeType) 22486 { 22487 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22488 int res, resolved = 0, depth = vctxt->depth; 22489 22490 if (vctxt->xpathStates == NULL) 22491 return (0); 22492 22493 if (nodeType == XML_ATTRIBUTE_NODE) 22494 depth++; 22495 #ifdef DEBUG_IDC 22496 { 22497 xmlChar *str = NULL; 22498 xmlGenericError(xmlGenericErrorContext, 22499 "IDC: EVAL on %s, depth %d, type %d\n", 22500 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22501 vctxt->inode->localName), depth, nodeType); 22502 FREE_AND_NULL(str) 22503 } 22504 #endif 22505 /* 22506 * Process all active XPath state objects. 22507 */ 22508 first = vctxt->xpathStates; 22509 sto = first; 22510 while (sto != head) { 22511 #ifdef DEBUG_IDC 22512 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22513 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22514 sto->matcher->aidc->def->name, sto->sel->xpath); 22515 else 22516 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22517 sto->matcher->aidc->def->name, sto->sel->xpath); 22518 #endif 22519 if (nodeType == XML_ELEMENT_NODE) 22520 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22521 vctxt->inode->localName, vctxt->inode->nsName); 22522 else 22523 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22524 vctxt->inode->localName, vctxt->inode->nsName); 22525 22526 if (res == -1) { 22527 VERROR_INT("xmlSchemaXPathEvaluate", 22528 "calling xmlStreamPush()"); 22529 return (-1); 22530 } 22531 if (res == 0) 22532 goto next_sto; 22533 /* 22534 * Full match. 22535 */ 22536 #ifdef DEBUG_IDC 22537 xmlGenericError(xmlGenericErrorContext, "IDC: " 22538 "MATCH\n"); 22539 #endif 22540 /* 22541 * Register a match in the state object history. 22542 */ 22543 if (sto->history == NULL) { 22544 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22545 if (sto->history == NULL) { 22546 xmlSchemaVErrMemory(NULL, 22547 "allocating the state object history", NULL); 22548 return(-1); 22549 } 22550 sto->sizeHistory = 5; 22551 } else if (sto->sizeHistory <= sto->nbHistory) { 22552 sto->sizeHistory *= 2; 22553 sto->history = (int *) xmlRealloc(sto->history, 22554 sto->sizeHistory * sizeof(int)); 22555 if (sto->history == NULL) { 22556 xmlSchemaVErrMemory(NULL, 22557 "re-allocating the state object history", NULL); 22558 return(-1); 22559 } 22560 } 22561 sto->history[sto->nbHistory++] = depth; 22562 22563 #ifdef DEBUG_IDC 22564 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22565 vctxt->depth); 22566 #endif 22567 22568 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22569 xmlSchemaIDCSelectPtr sel; 22570 /* 22571 * Activate state objects for the IDC fields of 22572 * the IDC selector. 22573 */ 22574 #ifdef DEBUG_IDC 22575 xmlGenericError(xmlGenericErrorContext, "IDC: " 22576 "activating field states\n"); 22577 #endif 22578 sel = sto->matcher->aidc->def->fields; 22579 while (sel != NULL) { 22580 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22581 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22582 return (-1); 22583 sel = sel->next; 22584 } 22585 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22586 /* 22587 * An IDC key node was found by the IDC field. 22588 */ 22589 #ifdef DEBUG_IDC 22590 xmlGenericError(xmlGenericErrorContext, 22591 "IDC: key found\n"); 22592 #endif 22593 /* 22594 * Notify that the character value of this node is 22595 * needed. 22596 */ 22597 if (resolved == 0) { 22598 if ((vctxt->inode->flags & 22599 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22600 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22601 } 22602 resolved++; 22603 } 22604 next_sto: 22605 if (sto->next == NULL) { 22606 /* 22607 * Evaluate field state objects created on this node as well. 22608 */ 22609 head = first; 22610 sto = vctxt->xpathStates; 22611 } else 22612 sto = sto->next; 22613 } 22614 return (resolved); 22615 } 22616 22617 static const xmlChar * 22618 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22619 xmlChar **buf, 22620 xmlSchemaPSVIIDCKeyPtr *seq, 22621 int count) 22622 { 22623 int i, res; 22624 xmlChar *value = NULL; 22625 22626 *buf = xmlStrdup(BAD_CAST "["); 22627 for (i = 0; i < count; i++) { 22628 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22629 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22630 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22631 &value); 22632 if (res == 0) 22633 *buf = xmlStrcat(*buf, BAD_CAST value); 22634 else { 22635 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22636 "failed to compute a canonical value"); 22637 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22638 } 22639 if (i < count -1) 22640 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22641 else 22642 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22643 if (value != NULL) { 22644 xmlFree(value); 22645 value = NULL; 22646 } 22647 } 22648 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22649 22650 return (BAD_CAST *buf); 22651 } 22652 22653 /** 22654 * xmlSchemaXPathPop: 22655 * @vctxt: the WXS validation context 22656 * 22657 * Pops all XPath states. 22658 * 22659 * Returns 0 on success and -1 on internal errors. 22660 */ 22661 static int 22662 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22663 { 22664 xmlSchemaIDCStateObjPtr sto; 22665 int res; 22666 22667 if (vctxt->xpathStates == NULL) 22668 return(0); 22669 sto = vctxt->xpathStates; 22670 do { 22671 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22672 if (res == -1) 22673 return (-1); 22674 sto = sto->next; 22675 } while (sto != NULL); 22676 return(0); 22677 } 22678 22679 /** 22680 * xmlSchemaXPathProcessHistory: 22681 * @vctxt: the WXS validation context 22682 * @type: the simple/complex type of the current node if any at all 22683 * @val: the precompiled value 22684 * 22685 * Processes and pops the history items of the IDC state objects. 22686 * IDC key-sequences are validated/created on IDC bindings. 22687 * 22688 * Returns 0 on success and -1 on internal errors. 22689 */ 22690 static int 22691 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22692 int depth) 22693 { 22694 xmlSchemaIDCStateObjPtr sto, nextsto; 22695 int res, matchDepth; 22696 xmlSchemaPSVIIDCKeyPtr key = NULL; 22697 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22698 22699 if (vctxt->xpathStates == NULL) 22700 return (0); 22701 sto = vctxt->xpathStates; 22702 22703 #ifdef DEBUG_IDC 22704 { 22705 xmlChar *str = NULL; 22706 xmlGenericError(xmlGenericErrorContext, 22707 "IDC: BACK on %s, depth %d\n", 22708 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22709 vctxt->inode->localName), vctxt->depth); 22710 FREE_AND_NULL(str) 22711 } 22712 #endif 22713 /* 22714 * Evaluate the state objects. 22715 */ 22716 while (sto != NULL) { 22717 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22718 if (res == -1) { 22719 VERROR_INT("xmlSchemaXPathProcessHistory", 22720 "calling xmlStreamPop()"); 22721 return (-1); 22722 } 22723 #ifdef DEBUG_IDC 22724 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22725 sto->sel->xpath); 22726 #endif 22727 if (sto->nbHistory == 0) 22728 goto deregister_check; 22729 22730 matchDepth = sto->history[sto->nbHistory -1]; 22731 22732 /* 22733 * Only matches at the current depth are of interest. 22734 */ 22735 if (matchDepth != depth) { 22736 sto = sto->next; 22737 continue; 22738 } 22739 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22740 /* 22741 * NOTE: According to 22742 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22743 * ... the simple-content of complex types is also allowed. 22744 */ 22745 22746 if (WXS_IS_COMPLEX(type)) { 22747 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22748 /* 22749 * Sanity check for complex types with simple content. 22750 */ 22751 simpleType = type->contentTypeDef; 22752 if (simpleType == NULL) { 22753 VERROR_INT("xmlSchemaXPathProcessHistory", 22754 "field resolves to a CT with simple content " 22755 "but the CT is missing the ST definition"); 22756 return (-1); 22757 } 22758 } else 22759 simpleType = NULL; 22760 } else 22761 simpleType = type; 22762 if (simpleType == NULL) { 22763 xmlChar *str = NULL; 22764 22765 /* 22766 * Not qualified if the field resolves to a node of non 22767 * simple type. 22768 */ 22769 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22770 XML_SCHEMAV_CVC_IDC, NULL, 22771 WXS_BASIC_CAST sto->matcher->aidc->def, 22772 "The XPath '%s' of a field of %s does evaluate to a node of " 22773 "non-simple type", 22774 sto->sel->xpath, 22775 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22776 FREE_AND_NULL(str); 22777 sto->nbHistory--; 22778 goto deregister_check; 22779 } 22780 22781 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22782 /* 22783 * Failed to provide the normalized value; maybe 22784 * the value was invalid. 22785 */ 22786 VERROR(XML_SCHEMAV_CVC_IDC, 22787 WXS_BASIC_CAST sto->matcher->aidc->def, 22788 "Warning: No precomputed value available, the value " 22789 "was either invalid or something strange happened"); 22790 sto->nbHistory--; 22791 goto deregister_check; 22792 } else { 22793 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22794 xmlSchemaPSVIIDCKeyPtr *keySeq; 22795 int pos, idx; 22796 22797 /* 22798 * The key will be anchored on the matcher's list of 22799 * key-sequences. The position in this list is determined 22800 * by the target node's depth relative to the matcher's 22801 * depth of creation (i.e. the depth of the scope element). 22802 * 22803 * Element Depth Pos List-entries 22804 * <scope> 0 NULL 22805 * <bar> 1 NULL 22806 * <target/> 2 2 target 22807 * <bar> 22808 * </scope> 22809 * 22810 * The size of the list is only dependent on the depth of 22811 * the tree. 22812 * An entry will be NULLed in selector_leave, i.e. when 22813 * we hit the target's 22814 */ 22815 pos = sto->depth - matcher->depth; 22816 idx = sto->sel->index; 22817 22818 /* 22819 * Create/grow the array of key-sequences. 22820 */ 22821 if (matcher->keySeqs == NULL) { 22822 if (pos > 9) 22823 matcher->sizeKeySeqs = pos * 2; 22824 else 22825 matcher->sizeKeySeqs = 10; 22826 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22827 xmlMalloc(matcher->sizeKeySeqs * 22828 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22829 if (matcher->keySeqs == NULL) { 22830 xmlSchemaVErrMemory(NULL, 22831 "allocating an array of key-sequences", 22832 NULL); 22833 return(-1); 22834 } 22835 memset(matcher->keySeqs, 0, 22836 matcher->sizeKeySeqs * 22837 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22838 } else if (pos >= matcher->sizeKeySeqs) { 22839 int i = matcher->sizeKeySeqs; 22840 22841 matcher->sizeKeySeqs *= 2; 22842 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22843 xmlRealloc(matcher->keySeqs, 22844 matcher->sizeKeySeqs * 22845 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22846 if (matcher->keySeqs == NULL) { 22847 xmlSchemaVErrMemory(NULL, 22848 "reallocating an array of key-sequences", 22849 NULL); 22850 return (-1); 22851 } 22852 /* 22853 * The array needs to be NULLed. 22854 * TODO: Use memset? 22855 */ 22856 for (; i < matcher->sizeKeySeqs; i++) 22857 matcher->keySeqs[i] = NULL; 22858 } 22859 22860 /* 22861 * Get/create the key-sequence. 22862 */ 22863 keySeq = matcher->keySeqs[pos]; 22864 if (keySeq == NULL) { 22865 goto create_sequence; 22866 } else if (keySeq[idx] != NULL) { 22867 xmlChar *str = NULL; 22868 /* 22869 * cvc-identity-constraint: 22870 * 3 For each node in the `target node set` all 22871 * of the {fields}, with that node as the context 22872 * node, evaluate to either an empty node-set or 22873 * a node-set with exactly one member, which must 22874 * have a simple type. 22875 * 22876 * The key was already set; report an error. 22877 */ 22878 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22879 XML_SCHEMAV_CVC_IDC, NULL, 22880 WXS_BASIC_CAST matcher->aidc->def, 22881 "The XPath '%s' of a field of %s evaluates to a " 22882 "node-set with more than one member", 22883 sto->sel->xpath, 22884 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22885 FREE_AND_NULL(str); 22886 sto->nbHistory--; 22887 goto deregister_check; 22888 } else 22889 goto create_key; 22890 22891 create_sequence: 22892 /* 22893 * Create a key-sequence. 22894 */ 22895 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22896 matcher->aidc->def->nbFields * 22897 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22898 if (keySeq == NULL) { 22899 xmlSchemaVErrMemory(NULL, 22900 "allocating an IDC key-sequence", NULL); 22901 return(-1); 22902 } 22903 memset(keySeq, 0, matcher->aidc->def->nbFields * 22904 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22905 matcher->keySeqs[pos] = keySeq; 22906 create_key: 22907 /* 22908 * Create a key once per node only. 22909 */ 22910 if (key == NULL) { 22911 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22912 sizeof(xmlSchemaPSVIIDCKey)); 22913 if (key == NULL) { 22914 xmlSchemaVErrMemory(NULL, 22915 "allocating a IDC key", NULL); 22916 xmlFree(keySeq); 22917 matcher->keySeqs[pos] = NULL; 22918 return(-1); 22919 } 22920 /* 22921 * Consume the compiled value. 22922 */ 22923 key->type = simpleType; 22924 key->val = vctxt->inode->val; 22925 vctxt->inode->val = NULL; 22926 /* 22927 * Store the key in a global list. 22928 */ 22929 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22930 xmlSchemaIDCFreeKey(key); 22931 return (-1); 22932 } 22933 } 22934 keySeq[idx] = key; 22935 } 22936 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22937 22938 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22939 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22940 xmlSchemaPSVIIDCNodePtr ntItem; 22941 xmlSchemaIDCMatcherPtr matcher; 22942 xmlSchemaIDCPtr idc; 22943 xmlSchemaItemListPtr targets; 22944 int pos, i, j, nbKeys; 22945 /* 22946 * Here we have the following scenario: 22947 * An IDC 'selector' state object resolved to a target node, 22948 * during the time this target node was in the 22949 * ancestor-or-self axis, the 'field' state object(s) looked 22950 * out for matching nodes to create a key-sequence for this 22951 * target node. Now we are back to this target node and need 22952 * to put the key-sequence, together with the target node 22953 * itself, into the node-table of the corresponding IDC 22954 * binding. 22955 */ 22956 matcher = sto->matcher; 22957 idc = matcher->aidc->def; 22958 nbKeys = idc->nbFields; 22959 pos = depth - matcher->depth; 22960 /* 22961 * Check if the matcher has any key-sequences at all, plus 22962 * if it has a key-sequence for the current target node. 22963 */ 22964 if ((matcher->keySeqs == NULL) || 22965 (matcher->sizeKeySeqs <= pos)) { 22966 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22967 goto selector_key_error; 22968 else 22969 goto selector_leave; 22970 } 22971 22972 keySeq = &(matcher->keySeqs[pos]); 22973 if (*keySeq == NULL) { 22974 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22975 goto selector_key_error; 22976 else 22977 goto selector_leave; 22978 } 22979 22980 for (i = 0; i < nbKeys; i++) { 22981 if ((*keySeq)[i] == NULL) { 22982 /* 22983 * Not qualified, if not all fields did resolve. 22984 */ 22985 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22986 /* 22987 * All fields of a "key" IDC must resolve. 22988 */ 22989 goto selector_key_error; 22990 } 22991 goto selector_leave; 22992 } 22993 } 22994 /* 22995 * All fields did resolve. 22996 */ 22997 22998 /* 22999 * 4.1 If the {identity-constraint category} is unique(/key), 23000 * then no two members of the `qualified node set` have 23001 * `key-sequences` whose members are pairwise equal, as 23002 * defined by Equal in [XML Schemas: Datatypes]. 23003 * 23004 * Get the IDC binding from the matcher and check for 23005 * duplicate key-sequences. 23006 */ 23007 #if 0 23008 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23009 #endif 23010 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 23011 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 23012 (targets->nbItems != 0)) { 23013 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 23014 23015 i = 0; 23016 res = 0; 23017 /* 23018 * Compare the key-sequences, key by key. 23019 */ 23020 do { 23021 bkeySeq = 23022 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 23023 for (j = 0; j < nbKeys; j++) { 23024 ckey = (*keySeq)[j]; 23025 bkey = bkeySeq[j]; 23026 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 23027 if (res == -1) { 23028 return (-1); 23029 } else if (res == 0) { 23030 /* 23031 * One of the keys differs, so the key-sequence 23032 * won't be equal; get out. 23033 */ 23034 break; 23035 } 23036 } 23037 if (res == 1) { 23038 /* 23039 * Duplicate key-sequence found. 23040 */ 23041 break; 23042 } 23043 i++; 23044 } while (i < targets->nbItems); 23045 if (i != targets->nbItems) { 23046 xmlChar *str = NULL, *strB = NULL; 23047 /* 23048 * TODO: Try to report the key-sequence. 23049 */ 23050 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23051 XML_SCHEMAV_CVC_IDC, NULL, 23052 WXS_BASIC_CAST idc, 23053 "Duplicate key-sequence %s in %s", 23054 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23055 (*keySeq), nbKeys), 23056 xmlSchemaGetIDCDesignation(&strB, idc)); 23057 FREE_AND_NULL(str); 23058 FREE_AND_NULL(strB); 23059 goto selector_leave; 23060 } 23061 } 23062 /* 23063 * Add a node-table item to the IDC binding. 23064 */ 23065 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23066 sizeof(xmlSchemaPSVIIDCNode)); 23067 if (ntItem == NULL) { 23068 xmlSchemaVErrMemory(NULL, 23069 "allocating an IDC node-table item", NULL); 23070 xmlFree(*keySeq); 23071 *keySeq = NULL; 23072 return(-1); 23073 } 23074 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23075 23076 /* 23077 * Store the node-table item in a global list. 23078 */ 23079 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23080 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23081 xmlFree(ntItem); 23082 xmlFree(*keySeq); 23083 *keySeq = NULL; 23084 return (-1); 23085 } 23086 ntItem->nodeQNameID = -1; 23087 } else { 23088 /* 23089 * Save a cached QName for this node on the IDC node, to be 23090 * able to report it, even if the node is not saved. 23091 */ 23092 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23093 vctxt->inode->localName, vctxt->inode->nsName); 23094 if (ntItem->nodeQNameID == -1) { 23095 xmlFree(ntItem); 23096 xmlFree(*keySeq); 23097 *keySeq = NULL; 23098 return (-1); 23099 } 23100 } 23101 /* 23102 * Init the node-table item: Save the node, position and 23103 * consume the key-sequence. 23104 */ 23105 ntItem->node = vctxt->node; 23106 ntItem->nodeLine = vctxt->inode->nodeLine; 23107 ntItem->keys = *keySeq; 23108 *keySeq = NULL; 23109 #if 0 23110 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23111 #endif 23112 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23113 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23114 /* 23115 * Free the item, since keyref items won't be 23116 * put on a global list. 23117 */ 23118 xmlFree(ntItem->keys); 23119 xmlFree(ntItem); 23120 } 23121 return (-1); 23122 } 23123 23124 goto selector_leave; 23125 selector_key_error: 23126 { 23127 xmlChar *str = NULL; 23128 /* 23129 * 4.2.1 (KEY) The `target node set` and the 23130 * `qualified node set` are equal, that is, every 23131 * member of the `target node set` is also a member 23132 * of the `qualified node set` and vice versa. 23133 */ 23134 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23135 XML_SCHEMAV_CVC_IDC, NULL, 23136 WXS_BASIC_CAST idc, 23137 "Not all fields of %s evaluate to a node", 23138 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23139 FREE_AND_NULL(str); 23140 } 23141 selector_leave: 23142 /* 23143 * Free the key-sequence if not added to the IDC table. 23144 */ 23145 if ((keySeq != NULL) && (*keySeq != NULL)) { 23146 xmlFree(*keySeq); 23147 *keySeq = NULL; 23148 } 23149 } /* if selector */ 23150 23151 sto->nbHistory--; 23152 23153 deregister_check: 23154 /* 23155 * Deregister state objects if they reach the depth of creation. 23156 */ 23157 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23158 #ifdef DEBUG_IDC 23159 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23160 sto->sel->xpath); 23161 #endif 23162 if (vctxt->xpathStates != sto) { 23163 VERROR_INT("xmlSchemaXPathProcessHistory", 23164 "The state object to be removed is not the first " 23165 "in the list"); 23166 } 23167 nextsto = sto->next; 23168 /* 23169 * Unlink from the list of active XPath state objects. 23170 */ 23171 vctxt->xpathStates = sto->next; 23172 sto->next = vctxt->xpathStatePool; 23173 /* 23174 * Link it to the pool of reusable state objects. 23175 */ 23176 vctxt->xpathStatePool = sto; 23177 sto = nextsto; 23178 } else 23179 sto = sto->next; 23180 } /* while (sto != NULL) */ 23181 return (0); 23182 } 23183 23184 /** 23185 * xmlSchemaIDCRegisterMatchers: 23186 * @vctxt: the WXS validation context 23187 * @elemDecl: the element declaration 23188 * 23189 * Creates helper objects to evaluate IDC selectors/fields 23190 * successively. 23191 * 23192 * Returns 0 if OK and -1 on internal errors. 23193 */ 23194 static int 23195 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23196 xmlSchemaElementPtr elemDecl) 23197 { 23198 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23199 xmlSchemaIDCPtr idc, refIdc; 23200 xmlSchemaIDCAugPtr aidc; 23201 23202 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23203 if (idc == NULL) 23204 return (0); 23205 23206 #ifdef DEBUG_IDC 23207 { 23208 xmlChar *str = NULL; 23209 xmlGenericError(xmlGenericErrorContext, 23210 "IDC: REGISTER on %s, depth %d\n", 23211 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23212 vctxt->inode->localName), vctxt->depth); 23213 FREE_AND_NULL(str) 23214 } 23215 #endif 23216 if (vctxt->inode->idcMatchers != NULL) { 23217 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23218 "The chain of IDC matchers is expected to be empty"); 23219 return (-1); 23220 } 23221 do { 23222 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23223 /* 23224 * Since IDCs bubbles are expensive we need to know the 23225 * depth at which the bubbles should stop; this will be 23226 * the depth of the top-most keyref IDC. If no keyref 23227 * references a key/unique IDC, the keyrefDepth will 23228 * be -1, indicating that no bubbles are needed. 23229 */ 23230 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23231 if (refIdc != NULL) { 23232 /* 23233 * Remember that we have keyrefs on this node. 23234 */ 23235 vctxt->inode->hasKeyrefs = 1; 23236 /* 23237 * Lookup the referenced augmented IDC info. 23238 */ 23239 aidc = vctxt->aidcs; 23240 while (aidc != NULL) { 23241 if (aidc->def == refIdc) 23242 break; 23243 aidc = aidc->next; 23244 } 23245 if (aidc == NULL) { 23246 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23247 "Could not find an augmented IDC item for an IDC " 23248 "definition"); 23249 return (-1); 23250 } 23251 if ((aidc->keyrefDepth == -1) || 23252 (vctxt->depth < aidc->keyrefDepth)) 23253 aidc->keyrefDepth = vctxt->depth; 23254 } 23255 } 23256 /* 23257 * Lookup the augmented IDC item for the IDC definition. 23258 */ 23259 aidc = vctxt->aidcs; 23260 while (aidc != NULL) { 23261 if (aidc->def == idc) 23262 break; 23263 aidc = aidc->next; 23264 } 23265 if (aidc == NULL) { 23266 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23267 "Could not find an augmented IDC item for an IDC definition"); 23268 return (-1); 23269 } 23270 /* 23271 * Create an IDC matcher for every IDC definition. 23272 */ 23273 if (vctxt->idcMatcherCache != NULL) { 23274 /* 23275 * Reuse a cached matcher. 23276 */ 23277 matcher = vctxt->idcMatcherCache; 23278 vctxt->idcMatcherCache = matcher->nextCached; 23279 matcher->nextCached = NULL; 23280 } else { 23281 matcher = (xmlSchemaIDCMatcherPtr) 23282 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23283 if (matcher == NULL) { 23284 xmlSchemaVErrMemory(vctxt, 23285 "allocating an IDC matcher", NULL); 23286 return (-1); 23287 } 23288 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23289 } 23290 if (last == NULL) 23291 vctxt->inode->idcMatchers = matcher; 23292 else 23293 last->next = matcher; 23294 last = matcher; 23295 23296 matcher->type = IDC_MATCHER; 23297 matcher->depth = vctxt->depth; 23298 matcher->aidc = aidc; 23299 matcher->idcType = aidc->def->type; 23300 #ifdef DEBUG_IDC 23301 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23302 #endif 23303 /* 23304 * Init the automaton state object. 23305 */ 23306 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23307 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23308 return (-1); 23309 23310 idc = idc->next; 23311 } while (idc != NULL); 23312 return (0); 23313 } 23314 23315 static int 23316 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23317 xmlSchemaNodeInfoPtr ielem) 23318 { 23319 xmlSchemaPSVIIDCBindingPtr bind; 23320 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23321 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23322 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23323 23324 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23325 /* vctxt->createIDCNodeTables */ 23326 while (matcher != NULL) { 23327 /* 23328 * Skip keyref IDCs and empty IDC target-lists. 23329 */ 23330 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23331 WXS_ILIST_IS_EMPTY(matcher->targets)) 23332 { 23333 matcher = matcher->next; 23334 continue; 23335 } 23336 /* 23337 * If we _want_ the IDC node-table to be created in any case 23338 * then do so. Otherwise create them only if keyrefs need them. 23339 */ 23340 if ((! vctxt->createIDCNodeTables) && 23341 ((matcher->aidc->keyrefDepth == -1) || 23342 (matcher->aidc->keyrefDepth > vctxt->depth))) 23343 { 23344 matcher = matcher->next; 23345 continue; 23346 } 23347 /* 23348 * Get/create the IDC binding on this element for the IDC definition. 23349 */ 23350 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23351 if (bind == NULL) 23352 goto internal_error; 23353 23354 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23355 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23356 nbDupls = bind->dupls->nbItems; 23357 } else { 23358 dupls = NULL; 23359 nbDupls = 0; 23360 } 23361 if (bind->nodeTable != NULL) { 23362 nbNodeTable = bind->nbNodes; 23363 } else { 23364 nbNodeTable = 0; 23365 } 23366 23367 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23368 /* 23369 * Transfer all IDC target-nodes to the IDC node-table. 23370 */ 23371 bind->nodeTable = 23372 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23373 bind->sizeNodes = matcher->targets->sizeItems; 23374 bind->nbNodes = matcher->targets->nbItems; 23375 23376 matcher->targets->items = NULL; 23377 matcher->targets->sizeItems = 0; 23378 matcher->targets->nbItems = 0; 23379 } else { 23380 /* 23381 * Compare the key-sequences and add to the IDC node-table. 23382 */ 23383 nbTargets = matcher->targets->nbItems; 23384 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23385 nbFields = matcher->aidc->def->nbFields; 23386 i = 0; 23387 do { 23388 keys = targets[i]->keys; 23389 if (nbDupls) { 23390 /* 23391 * Search in already found duplicates first. 23392 */ 23393 j = 0; 23394 do { 23395 if (nbFields == 1) { 23396 res = xmlSchemaAreValuesEqual(keys[0]->val, 23397 dupls[j]->keys[0]->val); 23398 if (res == -1) 23399 goto internal_error; 23400 if (res == 1) { 23401 /* 23402 * Equal key-sequence. 23403 */ 23404 goto next_target; 23405 } 23406 } else { 23407 res = 0; 23408 ntkeys = dupls[j]->keys; 23409 for (k = 0; k < nbFields; k++) { 23410 res = xmlSchemaAreValuesEqual(keys[k]->val, 23411 ntkeys[k]->val); 23412 if (res == -1) 23413 goto internal_error; 23414 if (res == 0) { 23415 /* 23416 * One of the keys differs. 23417 */ 23418 break; 23419 } 23420 } 23421 if (res == 1) { 23422 /* 23423 * Equal key-sequence found. 23424 */ 23425 goto next_target; 23426 } 23427 } 23428 j++; 23429 } while (j < nbDupls); 23430 } 23431 if (nbNodeTable) { 23432 j = 0; 23433 do { 23434 if (nbFields == 1) { 23435 res = xmlSchemaAreValuesEqual(keys[0]->val, 23436 bind->nodeTable[j]->keys[0]->val); 23437 if (res == -1) 23438 goto internal_error; 23439 if (res == 0) { 23440 /* 23441 * The key-sequence differs. 23442 */ 23443 goto next_node_table_entry; 23444 } 23445 } else { 23446 res = 0; 23447 ntkeys = bind->nodeTable[j]->keys; 23448 for (k = 0; k < nbFields; k++) { 23449 res = xmlSchemaAreValuesEqual(keys[k]->val, 23450 ntkeys[k]->val); 23451 if (res == -1) 23452 goto internal_error; 23453 if (res == 0) { 23454 /* 23455 * One of the keys differs. 23456 */ 23457 goto next_node_table_entry; 23458 } 23459 } 23460 } 23461 /* 23462 * Add the duplicate to the list of duplicates. 23463 */ 23464 if (bind->dupls == NULL) { 23465 bind->dupls = xmlSchemaItemListCreate(); 23466 if (bind->dupls == NULL) 23467 goto internal_error; 23468 } 23469 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23470 goto internal_error; 23471 /* 23472 * Remove the duplicate entry from the IDC node-table. 23473 */ 23474 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23475 bind->nbNodes--; 23476 23477 goto next_target; 23478 23479 next_node_table_entry: 23480 j++; 23481 } while (j < nbNodeTable); 23482 } 23483 /* 23484 * If everything is fine, then add the IDC target-node to 23485 * the IDC node-table. 23486 */ 23487 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23488 goto internal_error; 23489 23490 next_target: 23491 i++; 23492 } while (i < nbTargets); 23493 } 23494 matcher = matcher->next; 23495 } 23496 return(0); 23497 23498 internal_error: 23499 return(-1); 23500 } 23501 23502 /** 23503 * xmlSchemaBubbleIDCNodeTables: 23504 * @depth: the current tree depth 23505 * 23506 * Merges IDC bindings of an element at @depth into the corresponding IDC 23507 * bindings of its parent element. If a duplicate note-table entry is found, 23508 * both, the parent node-table entry and child entry are discarded from the 23509 * node-table of the parent. 23510 * 23511 * Returns 0 if OK and -1 on internal errors. 23512 */ 23513 static int 23514 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23515 { 23516 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23517 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23518 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23519 xmlSchemaIDCAugPtr aidc; 23520 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23521 23522 bind = vctxt->inode->idcTable; 23523 if (bind == NULL) { 23524 /* Fine, no table, no bubbles. */ 23525 return (0); 23526 } 23527 23528 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23529 /* 23530 * Walk all bindings; create new or add to existing bindings. 23531 * Remove duplicate key-sequences. 23532 */ 23533 while (bind != NULL) { 23534 23535 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23536 goto next_binding; 23537 /* 23538 * Check if the key/unique IDC table needs to be bubbled. 23539 */ 23540 if (! vctxt->createIDCNodeTables) { 23541 aidc = vctxt->aidcs; 23542 do { 23543 if (aidc->def == bind->definition) { 23544 if ((aidc->keyrefDepth == -1) || 23545 (aidc->keyrefDepth >= vctxt->depth)) { 23546 goto next_binding; 23547 } 23548 break; 23549 } 23550 aidc = aidc->next; 23551 } while (aidc != NULL); 23552 } 23553 23554 if (parTable != NULL) 23555 parBind = *parTable; 23556 /* 23557 * Search a matching parent binding for the 23558 * IDC definition. 23559 */ 23560 while (parBind != NULL) { 23561 if (parBind->definition == bind->definition) 23562 break; 23563 parBind = parBind->next; 23564 } 23565 23566 if (parBind != NULL) { 23567 /* 23568 * Compare every node-table entry of the child node, 23569 * i.e. the key-sequence within, ... 23570 */ 23571 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23572 23573 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23574 oldDupls = parBind->dupls->nbItems; 23575 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23576 } else { 23577 dupls = NULL; 23578 oldDupls = 0; 23579 } 23580 23581 parNodes = parBind->nodeTable; 23582 nbFields = bind->definition->nbFields; 23583 23584 for (i = 0; i < bind->nbNodes; i++) { 23585 node = bind->nodeTable[i]; 23586 if (node == NULL) 23587 continue; 23588 /* 23589 * ...with every key-sequence of the parent node, already 23590 * evaluated to be a duplicate key-sequence. 23591 */ 23592 if (oldDupls) { 23593 j = 0; 23594 while (j < oldDupls) { 23595 if (nbFields == 1) { 23596 ret = xmlSchemaAreValuesEqual( 23597 node->keys[0]->val, 23598 dupls[j]->keys[0]->val); 23599 if (ret == -1) 23600 goto internal_error; 23601 if (ret == 0) { 23602 j++; 23603 continue; 23604 } 23605 } else { 23606 parNode = dupls[j]; 23607 for (k = 0; k < nbFields; k++) { 23608 ret = xmlSchemaAreValuesEqual( 23609 node->keys[k]->val, 23610 parNode->keys[k]->val); 23611 if (ret == -1) 23612 goto internal_error; 23613 if (ret == 0) 23614 break; 23615 } 23616 } 23617 if (ret == 1) 23618 /* Duplicate found. */ 23619 break; 23620 j++; 23621 } 23622 if (j != oldDupls) { 23623 /* Duplicate found. Skip this entry. */ 23624 continue; 23625 } 23626 } 23627 /* 23628 * ... and with every key-sequence of the parent node. 23629 */ 23630 if (oldNum) { 23631 j = 0; 23632 while (j < oldNum) { 23633 parNode = parNodes[j]; 23634 if (nbFields == 1) { 23635 ret = xmlSchemaAreValuesEqual( 23636 node->keys[0]->val, 23637 parNode->keys[0]->val); 23638 if (ret == -1) 23639 goto internal_error; 23640 if (ret == 0) { 23641 j++; 23642 continue; 23643 } 23644 } else { 23645 for (k = 0; k < nbFields; k++) { 23646 ret = xmlSchemaAreValuesEqual( 23647 node->keys[k]->val, 23648 parNode->keys[k]->val); 23649 if (ret == -1) 23650 goto internal_error; 23651 if (ret == 0) 23652 break; 23653 } 23654 } 23655 if (ret == 1) 23656 /* Duplicate found. */ 23657 break; 23658 j++; 23659 } 23660 if (j != oldNum) { 23661 /* 23662 * Handle duplicates. Move the duplicate in 23663 * the parent's node-table to the list of 23664 * duplicates. 23665 */ 23666 oldNum--; 23667 parBind->nbNodes--; 23668 /* 23669 * Move last old item to pos of duplicate. 23670 */ 23671 parNodes[j] = parNodes[oldNum]; 23672 23673 if (parBind->nbNodes != oldNum) { 23674 /* 23675 * If new items exist, move last new item to 23676 * last of old items. 23677 */ 23678 parNodes[oldNum] = 23679 parNodes[parBind->nbNodes]; 23680 } 23681 if (parBind->dupls == NULL) { 23682 parBind->dupls = xmlSchemaItemListCreate(); 23683 if (parBind->dupls == NULL) 23684 goto internal_error; 23685 } 23686 xmlSchemaItemListAdd(parBind->dupls, parNode); 23687 } else { 23688 /* 23689 * Add the node-table entry (node and key-sequence) of 23690 * the child node to the node table of the parent node. 23691 */ 23692 if (parBind->nodeTable == NULL) { 23693 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23694 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23695 if (parBind->nodeTable == NULL) { 23696 xmlSchemaVErrMemory(NULL, 23697 "allocating IDC list of node-table items", NULL); 23698 goto internal_error; 23699 } 23700 parBind->sizeNodes = 1; 23701 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23702 parBind->sizeNodes *= 2; 23703 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23704 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23705 sizeof(xmlSchemaPSVIIDCNodePtr)); 23706 if (parBind->nodeTable == NULL) { 23707 xmlSchemaVErrMemory(NULL, 23708 "re-allocating IDC list of node-table items", NULL); 23709 goto internal_error; 23710 } 23711 } 23712 parNodes = parBind->nodeTable; 23713 /* 23714 * Append the new node-table entry to the 'new node-table 23715 * entries' section. 23716 */ 23717 parNodes[parBind->nbNodes++] = node; 23718 } 23719 23720 } 23721 23722 } 23723 } else { 23724 /* 23725 * No binding for the IDC was found: create a new one and 23726 * copy all node-tables. 23727 */ 23728 parBind = xmlSchemaIDCNewBinding(bind->definition); 23729 if (parBind == NULL) 23730 goto internal_error; 23731 23732 /* 23733 * TODO: Hmm, how to optimize the initial number of 23734 * allocated entries? 23735 */ 23736 if (bind->nbNodes != 0) { 23737 /* 23738 * Add all IDC node-table entries. 23739 */ 23740 if (! vctxt->psviExposeIDCNodeTables) { 23741 /* 23742 * Just move the entries. 23743 * NOTE: this is quite save here, since 23744 * all the keyref lookups have already been 23745 * performed. 23746 */ 23747 parBind->nodeTable = bind->nodeTable; 23748 bind->nodeTable = NULL; 23749 parBind->sizeNodes = bind->sizeNodes; 23750 bind->sizeNodes = 0; 23751 parBind->nbNodes = bind->nbNodes; 23752 bind->nbNodes = 0; 23753 } else { 23754 /* 23755 * Copy the entries. 23756 */ 23757 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23758 xmlMalloc(bind->nbNodes * 23759 sizeof(xmlSchemaPSVIIDCNodePtr)); 23760 if (parBind->nodeTable == NULL) { 23761 xmlSchemaVErrMemory(NULL, 23762 "allocating an array of IDC node-table " 23763 "items", NULL); 23764 xmlSchemaIDCFreeBinding(parBind); 23765 goto internal_error; 23766 } 23767 parBind->sizeNodes = bind->nbNodes; 23768 parBind->nbNodes = bind->nbNodes; 23769 memcpy(parBind->nodeTable, bind->nodeTable, 23770 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23771 } 23772 } 23773 if (bind->dupls) { 23774 /* 23775 * Move the duplicates. 23776 */ 23777 if (parBind->dupls != NULL) 23778 xmlSchemaItemListFree(parBind->dupls); 23779 parBind->dupls = bind->dupls; 23780 bind->dupls = NULL; 23781 } 23782 if (parTable != NULL) { 23783 if (*parTable == NULL) 23784 *parTable = parBind; 23785 else { 23786 parBind->next = *parTable; 23787 *parTable = parBind; 23788 } 23789 } 23790 } 23791 23792 next_binding: 23793 bind = bind->next; 23794 } 23795 return (0); 23796 23797 internal_error: 23798 return(-1); 23799 } 23800 23801 /** 23802 * xmlSchemaCheckCVCIDCKeyRef: 23803 * @vctxt: the WXS validation context 23804 * @elemDecl: the element declaration 23805 * 23806 * Check the cvc-idc-keyref constraints. 23807 */ 23808 static int 23809 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23810 { 23811 xmlSchemaIDCMatcherPtr matcher; 23812 xmlSchemaPSVIIDCBindingPtr bind; 23813 23814 matcher = vctxt->inode->idcMatchers; 23815 /* 23816 * Find a keyref. 23817 */ 23818 while (matcher != NULL) { 23819 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23820 matcher->targets && 23821 matcher->targets->nbItems) 23822 { 23823 int i, j, k, res, nbFields, hasDupls; 23824 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23825 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23826 23827 nbFields = matcher->aidc->def->nbFields; 23828 23829 /* 23830 * Find the IDC node-table for the referenced IDC key/unique. 23831 */ 23832 bind = vctxt->inode->idcTable; 23833 while (bind != NULL) { 23834 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23835 bind->definition) 23836 break; 23837 bind = bind->next; 23838 } 23839 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23840 /* 23841 * Search for a matching key-sequences. 23842 */ 23843 for (i = 0; i < matcher->targets->nbItems; i++) { 23844 res = 0; 23845 refNode = matcher->targets->items[i]; 23846 if (bind != NULL) { 23847 refKeys = refNode->keys; 23848 for (j = 0; j < bind->nbNodes; j++) { 23849 keys = bind->nodeTable[j]->keys; 23850 for (k = 0; k < nbFields; k++) { 23851 res = xmlSchemaAreValuesEqual(keys[k]->val, 23852 refKeys[k]->val); 23853 if (res == 0) 23854 break; 23855 else if (res == -1) { 23856 return (-1); 23857 } 23858 } 23859 if (res == 1) { 23860 /* 23861 * Match found. 23862 */ 23863 break; 23864 } 23865 } 23866 if ((res == 0) && hasDupls) { 23867 /* 23868 * Search in duplicates 23869 */ 23870 for (j = 0; j < bind->dupls->nbItems; j++) { 23871 keys = ((xmlSchemaPSVIIDCNodePtr) 23872 bind->dupls->items[j])->keys; 23873 for (k = 0; k < nbFields; k++) { 23874 res = xmlSchemaAreValuesEqual(keys[k]->val, 23875 refKeys[k]->val); 23876 if (res == 0) 23877 break; 23878 else if (res == -1) { 23879 return (-1); 23880 } 23881 } 23882 if (res == 1) { 23883 /* 23884 * Match in duplicates found. 23885 */ 23886 xmlChar *str = NULL, *strB = NULL; 23887 xmlSchemaKeyrefErr(vctxt, 23888 XML_SCHEMAV_CVC_IDC, refNode, 23889 (xmlSchemaTypePtr) matcher->aidc->def, 23890 "More than one match found for " 23891 "key-sequence %s of keyref '%s'", 23892 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23893 refNode->keys, nbFields), 23894 xmlSchemaGetComponentQName(&strB, 23895 matcher->aidc->def)); 23896 FREE_AND_NULL(str); 23897 FREE_AND_NULL(strB); 23898 break; 23899 } 23900 } 23901 } 23902 } 23903 23904 if (res == 0) { 23905 xmlChar *str = NULL, *strB = NULL; 23906 xmlSchemaKeyrefErr(vctxt, 23907 XML_SCHEMAV_CVC_IDC, refNode, 23908 (xmlSchemaTypePtr) matcher->aidc->def, 23909 "No match found for key-sequence %s of keyref '%s'", 23910 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23911 refNode->keys, nbFields), 23912 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23913 FREE_AND_NULL(str); 23914 FREE_AND_NULL(strB); 23915 } 23916 } 23917 } 23918 matcher = matcher->next; 23919 } 23920 /* TODO: Return an error if any error encountered. */ 23921 return (0); 23922 } 23923 23924 /************************************************************************ 23925 * * 23926 * XML Reader validation code * 23927 * * 23928 ************************************************************************/ 23929 23930 static xmlSchemaAttrInfoPtr 23931 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23932 { 23933 xmlSchemaAttrInfoPtr iattr; 23934 /* 23935 * Grow/create list of attribute infos. 23936 */ 23937 if (vctxt->attrInfos == NULL) { 23938 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23939 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23940 vctxt->sizeAttrInfos = 1; 23941 if (vctxt->attrInfos == NULL) { 23942 xmlSchemaVErrMemory(vctxt, 23943 "allocating attribute info list", NULL); 23944 return (NULL); 23945 } 23946 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23947 vctxt->sizeAttrInfos++; 23948 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23949 xmlRealloc(vctxt->attrInfos, 23950 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23951 if (vctxt->attrInfos == NULL) { 23952 xmlSchemaVErrMemory(vctxt, 23953 "re-allocating attribute info list", NULL); 23954 return (NULL); 23955 } 23956 } else { 23957 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23958 if (iattr->localName != NULL) { 23959 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23960 "attr info not cleared"); 23961 return (NULL); 23962 } 23963 iattr->nodeType = XML_ATTRIBUTE_NODE; 23964 return (iattr); 23965 } 23966 /* 23967 * Create an attribute info. 23968 */ 23969 iattr = (xmlSchemaAttrInfoPtr) 23970 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23971 if (iattr == NULL) { 23972 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23973 return (NULL); 23974 } 23975 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23976 iattr->nodeType = XML_ATTRIBUTE_NODE; 23977 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23978 23979 return (iattr); 23980 } 23981 23982 static int 23983 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23984 xmlNodePtr attrNode, 23985 int nodeLine, 23986 const xmlChar *localName, 23987 const xmlChar *nsName, 23988 int ownedNames, 23989 xmlChar *value, 23990 int ownedValue) 23991 { 23992 xmlSchemaAttrInfoPtr attr; 23993 23994 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23995 if (attr == NULL) { 23996 VERROR_INT("xmlSchemaPushAttribute", 23997 "calling xmlSchemaGetFreshAttrInfo()"); 23998 return (-1); 23999 } 24000 attr->node = attrNode; 24001 attr->nodeLine = nodeLine; 24002 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 24003 attr->localName = localName; 24004 attr->nsName = nsName; 24005 if (ownedNames) 24006 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 24007 /* 24008 * Evaluate if it's an XSI attribute. 24009 */ 24010 if (nsName != NULL) { 24011 if (xmlStrEqual(localName, BAD_CAST "nil")) { 24012 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24013 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 24014 } 24015 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 24016 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24017 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 24018 } 24019 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 24020 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24021 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 24022 } 24023 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 24024 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 24025 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 24026 } 24027 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 24028 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 24029 } 24030 } 24031 attr->value = value; 24032 if (ownedValue) 24033 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 24034 if (attr->metaType != 0) 24035 attr->state = XML_SCHEMAS_ATTR_META; 24036 return (0); 24037 } 24038 24039 /** 24040 * xmlSchemaClearElemInfo: 24041 * @vctxt: the WXS validation context 24042 * @ielem: the element information item 24043 */ 24044 static void 24045 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 24046 xmlSchemaNodeInfoPtr ielem) 24047 { 24048 ielem->hasKeyrefs = 0; 24049 ielem->appliedXPath = 0; 24050 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 24051 FREE_AND_NULL(ielem->localName); 24052 FREE_AND_NULL(ielem->nsName); 24053 } else { 24054 ielem->localName = NULL; 24055 ielem->nsName = NULL; 24056 } 24057 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24058 FREE_AND_NULL(ielem->value); 24059 } else { 24060 ielem->value = NULL; 24061 } 24062 if (ielem->val != NULL) { 24063 /* 24064 * PSVI TODO: Be careful not to free it when the value is 24065 * exposed via PSVI. 24066 */ 24067 xmlSchemaFreeValue(ielem->val); 24068 ielem->val = NULL; 24069 } 24070 if (ielem->idcMatchers != NULL) { 24071 /* 24072 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24073 * Does it work? 24074 */ 24075 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24076 #if 0 24077 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24078 #endif 24079 ielem->idcMatchers = NULL; 24080 } 24081 if (ielem->idcTable != NULL) { 24082 /* 24083 * OPTIMIZE TODO: Use a pool of IDC tables??. 24084 */ 24085 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24086 ielem->idcTable = NULL; 24087 } 24088 if (ielem->regexCtxt != NULL) { 24089 xmlRegFreeExecCtxt(ielem->regexCtxt); 24090 ielem->regexCtxt = NULL; 24091 } 24092 if (ielem->nsBindings != NULL) { 24093 xmlFree((xmlChar **)ielem->nsBindings); 24094 ielem->nsBindings = NULL; 24095 ielem->nbNsBindings = 0; 24096 ielem->sizeNsBindings = 0; 24097 } 24098 } 24099 24100 /** 24101 * xmlSchemaGetFreshElemInfo: 24102 * @vctxt: the schema validation context 24103 * 24104 * Creates/reuses and initializes the element info item for 24105 * the current tree depth. 24106 * 24107 * Returns the element info item or NULL on API or internal errors. 24108 */ 24109 static xmlSchemaNodeInfoPtr 24110 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24111 { 24112 xmlSchemaNodeInfoPtr info = NULL; 24113 24114 if (vctxt->depth > vctxt->sizeElemInfos) { 24115 VERROR_INT("xmlSchemaGetFreshElemInfo", 24116 "inconsistent depth encountered"); 24117 return (NULL); 24118 } 24119 if (vctxt->elemInfos == NULL) { 24120 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24121 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24122 if (vctxt->elemInfos == NULL) { 24123 xmlSchemaVErrMemory(vctxt, 24124 "allocating the element info array", NULL); 24125 return (NULL); 24126 } 24127 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24128 vctxt->sizeElemInfos = 10; 24129 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24130 int i = vctxt->sizeElemInfos; 24131 24132 vctxt->sizeElemInfos *= 2; 24133 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24134 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24135 sizeof(xmlSchemaNodeInfoPtr)); 24136 if (vctxt->elemInfos == NULL) { 24137 xmlSchemaVErrMemory(vctxt, 24138 "re-allocating the element info array", NULL); 24139 return (NULL); 24140 } 24141 /* 24142 * We need the new memory to be NULLed. 24143 * TODO: Use memset instead? 24144 */ 24145 for (; i < vctxt->sizeElemInfos; i++) 24146 vctxt->elemInfos[i] = NULL; 24147 } else 24148 info = vctxt->elemInfos[vctxt->depth]; 24149 24150 if (info == NULL) { 24151 info = (xmlSchemaNodeInfoPtr) 24152 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24153 if (info == NULL) { 24154 xmlSchemaVErrMemory(vctxt, 24155 "allocating an element info", NULL); 24156 return (NULL); 24157 } 24158 vctxt->elemInfos[vctxt->depth] = info; 24159 } else { 24160 if (info->localName != NULL) { 24161 VERROR_INT("xmlSchemaGetFreshElemInfo", 24162 "elem info has not been cleared"); 24163 return (NULL); 24164 } 24165 } 24166 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24167 info->nodeType = XML_ELEMENT_NODE; 24168 info->depth = vctxt->depth; 24169 24170 return (info); 24171 } 24172 24173 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24174 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24175 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24176 24177 static int 24178 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24179 xmlNodePtr node, 24180 xmlSchemaTypePtr type, 24181 xmlSchemaValType valType, 24182 const xmlChar * value, 24183 xmlSchemaValPtr val, 24184 unsigned long length, 24185 int fireErrors) 24186 { 24187 int ret, error = 0; 24188 24189 xmlSchemaTypePtr tmpType; 24190 xmlSchemaFacetLinkPtr facetLink; 24191 xmlSchemaFacetPtr facet; 24192 unsigned long len = 0; 24193 xmlSchemaWhitespaceValueType ws; 24194 24195 /* 24196 * In Libxml2, derived built-in types have currently no explicit facets. 24197 */ 24198 if (type->type == XML_SCHEMA_TYPE_BASIC) 24199 return (0); 24200 24201 /* 24202 * NOTE: Do not jump away, if the facetSet of the given type is 24203 * empty: until now, "pattern" and "enumeration" facets of the 24204 * *base types* need to be checked as well. 24205 */ 24206 if (type->facetSet == NULL) 24207 goto pattern_and_enum; 24208 24209 if (! WXS_IS_ATOMIC(type)) { 24210 if (WXS_IS_LIST(type)) 24211 goto WXS_IS_LIST; 24212 else 24213 goto pattern_and_enum; 24214 } 24215 24216 /* 24217 * Whitespace handling is only of importance for string-based 24218 * types. 24219 */ 24220 tmpType = xmlSchemaGetPrimitiveType(type); 24221 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24222 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24223 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24224 } else 24225 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24226 24227 /* 24228 * If the value was not computed (for string or 24229 * anySimpleType based types), then use the provided 24230 * type. 24231 */ 24232 if (val != NULL) 24233 valType = xmlSchemaGetValType(val); 24234 24235 ret = 0; 24236 for (facetLink = type->facetSet; facetLink != NULL; 24237 facetLink = facetLink->next) { 24238 /* 24239 * Skip the pattern "whiteSpace": it is used to 24240 * format the character content beforehand. 24241 */ 24242 switch (facetLink->facet->type) { 24243 case XML_SCHEMA_FACET_WHITESPACE: 24244 case XML_SCHEMA_FACET_PATTERN: 24245 case XML_SCHEMA_FACET_ENUMERATION: 24246 continue; 24247 case XML_SCHEMA_FACET_LENGTH: 24248 case XML_SCHEMA_FACET_MINLENGTH: 24249 case XML_SCHEMA_FACET_MAXLENGTH: 24250 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24251 valType, value, val, &len, ws); 24252 break; 24253 default: 24254 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24255 valType, value, val, ws); 24256 break; 24257 } 24258 if (ret < 0) { 24259 AERROR_INT("xmlSchemaValidateFacets", 24260 "validating against a atomic type facet"); 24261 return (-1); 24262 } else if (ret > 0) { 24263 if (fireErrors) 24264 xmlSchemaFacetErr(actxt, ret, node, 24265 value, len, type, facetLink->facet, NULL, NULL, NULL); 24266 else 24267 return (ret); 24268 if (error == 0) 24269 error = ret; 24270 } 24271 ret = 0; 24272 } 24273 24274 WXS_IS_LIST: 24275 if (! WXS_IS_LIST(type)) 24276 goto pattern_and_enum; 24277 /* 24278 * "length", "minLength" and "maxLength" of list types. 24279 */ 24280 ret = 0; 24281 for (facetLink = type->facetSet; facetLink != NULL; 24282 facetLink = facetLink->next) { 24283 24284 switch (facetLink->facet->type) { 24285 case XML_SCHEMA_FACET_LENGTH: 24286 case XML_SCHEMA_FACET_MINLENGTH: 24287 case XML_SCHEMA_FACET_MAXLENGTH: 24288 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24289 value, length, NULL); 24290 break; 24291 default: 24292 continue; 24293 } 24294 if (ret < 0) { 24295 AERROR_INT("xmlSchemaValidateFacets", 24296 "validating against a list type facet"); 24297 return (-1); 24298 } else if (ret > 0) { 24299 if (fireErrors) 24300 xmlSchemaFacetErr(actxt, ret, node, 24301 value, length, type, facetLink->facet, NULL, NULL, NULL); 24302 else 24303 return (ret); 24304 if (error == 0) 24305 error = ret; 24306 } 24307 ret = 0; 24308 } 24309 24310 pattern_and_enum: 24311 if (error >= 0) { 24312 int found = 0; 24313 /* 24314 * Process enumerations. Facet values are in the value space 24315 * of the defining type's base type. This seems to be a bug in the 24316 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24317 * Only the first set of enumerations in the ancestor-or-self axis 24318 * is used for validation. 24319 */ 24320 ret = 0; 24321 tmpType = type; 24322 do { 24323 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24324 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24325 continue; 24326 found = 1; 24327 ret = xmlSchemaAreValuesEqual(facet->val, val); 24328 if (ret == 1) 24329 break; 24330 else if (ret < 0) { 24331 AERROR_INT("xmlSchemaValidateFacets", 24332 "validating against an enumeration facet"); 24333 return (-1); 24334 } 24335 } 24336 if (ret != 0) 24337 break; 24338 /* 24339 * Break on the first set of enumerations. Any additional 24340 * enumerations which might be existent on the ancestors 24341 * of the current type are restricted by this set; thus 24342 * *must* *not* be taken into account. 24343 */ 24344 if (found) 24345 break; 24346 tmpType = tmpType->baseType; 24347 } while ((tmpType != NULL) && 24348 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24349 if (found && (ret == 0)) { 24350 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24351 if (fireErrors) { 24352 xmlSchemaFacetErr(actxt, ret, node, 24353 value, 0, type, NULL, NULL, NULL, NULL); 24354 } else 24355 return (ret); 24356 if (error == 0) 24357 error = ret; 24358 } 24359 } 24360 24361 if (error >= 0) { 24362 int found; 24363 /* 24364 * Process patters. Pattern facets are ORed at type level 24365 * and ANDed if derived. Walk the base type axis. 24366 */ 24367 tmpType = type; 24368 facet = NULL; 24369 do { 24370 found = 0; 24371 for (facetLink = tmpType->facetSet; facetLink != NULL; 24372 facetLink = facetLink->next) { 24373 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24374 continue; 24375 found = 1; 24376 /* 24377 * NOTE that for patterns, @value needs to be the 24378 * normalized value. 24379 */ 24380 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24381 if (ret == 1) 24382 break; 24383 else if (ret < 0) { 24384 AERROR_INT("xmlSchemaValidateFacets", 24385 "validating against a pattern facet"); 24386 return (-1); 24387 } else { 24388 /* 24389 * Save the last non-validating facet. 24390 */ 24391 facet = facetLink->facet; 24392 } 24393 } 24394 if (found && (ret != 1)) { 24395 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24396 if (fireErrors) { 24397 xmlSchemaFacetErr(actxt, ret, node, 24398 value, 0, type, facet, NULL, NULL, NULL); 24399 } else 24400 return (ret); 24401 if (error == 0) 24402 error = ret; 24403 break; 24404 } 24405 tmpType = tmpType->baseType; 24406 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24407 } 24408 24409 return (error); 24410 } 24411 24412 static xmlChar * 24413 xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24414 const xmlChar *value) 24415 { 24416 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24417 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24418 return (xmlSchemaCollapseString(value)); 24419 case XML_SCHEMA_WHITESPACE_REPLACE: 24420 return (xmlSchemaWhiteSpaceReplace(value)); 24421 default: 24422 return (NULL); 24423 } 24424 } 24425 24426 static int 24427 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24428 const xmlChar *value, 24429 xmlSchemaValPtr *val, 24430 int valNeeded) 24431 { 24432 int ret; 24433 const xmlChar *nsName; 24434 xmlChar *local, *prefix = NULL; 24435 24436 ret = xmlValidateQName(value, 1); 24437 if (ret != 0) { 24438 if (ret == -1) { 24439 VERROR_INT("xmlSchemaValidateQName", 24440 "calling xmlValidateQName()"); 24441 return (-1); 24442 } 24443 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24444 } 24445 /* 24446 * NOTE: xmlSplitQName2 will always return a duplicated 24447 * strings. 24448 */ 24449 local = xmlSplitQName2(value, &prefix); 24450 if (local == NULL) 24451 local = xmlStrdup(value); 24452 /* 24453 * OPTIMIZE TODO: Use flags for: 24454 * - is there any namespace binding? 24455 * - is there a default namespace? 24456 */ 24457 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24458 24459 if (prefix != NULL) { 24460 xmlFree(prefix); 24461 /* 24462 * A namespace must be found if the prefix is 24463 * NOT NULL. 24464 */ 24465 if (nsName == NULL) { 24466 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24467 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24468 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24469 "The QName value '%s' has no " 24470 "corresponding namespace declaration in " 24471 "scope", value, NULL); 24472 if (local != NULL) 24473 xmlFree(local); 24474 return (ret); 24475 } 24476 } 24477 if (valNeeded && val) { 24478 if (nsName != NULL) 24479 *val = xmlSchemaNewQNameValue( 24480 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24481 else 24482 *val = xmlSchemaNewQNameValue(NULL, 24483 BAD_CAST local); 24484 } else 24485 xmlFree(local); 24486 return (0); 24487 } 24488 24489 /* 24490 * cvc-simple-type 24491 */ 24492 static int 24493 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24494 xmlNodePtr node, 24495 xmlSchemaTypePtr type, 24496 const xmlChar *value, 24497 xmlSchemaValPtr *retVal, 24498 int fireErrors, 24499 int normalize, 24500 int isNormalized) 24501 { 24502 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24503 xmlSchemaValPtr val = NULL; 24504 /* xmlSchemaWhitespaceValueType ws; */ 24505 xmlChar *normValue = NULL; 24506 24507 #define NORMALIZE(atype) \ 24508 if ((! isNormalized) && \ 24509 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24510 normValue = xmlSchemaNormalizeValue(atype, value); \ 24511 if (normValue != NULL) \ 24512 value = normValue; \ 24513 isNormalized = 1; \ 24514 } 24515 24516 if ((retVal != NULL) && (*retVal != NULL)) { 24517 xmlSchemaFreeValue(*retVal); 24518 *retVal = NULL; 24519 } 24520 /* 24521 * 3.14.4 Simple Type Definition Validation Rules 24522 * Validation Rule: String Valid 24523 */ 24524 /* 24525 * 1 It is schema-valid with respect to that definition as defined 24526 * by Datatype Valid in [XML Schemas: Datatypes]. 24527 */ 24528 /* 24529 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24530 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then 24531 * the string must be a `declared entity name`. 24532 */ 24533 /* 24534 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24535 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), 24536 * then every whitespace-delimited substring of the string must be a `declared 24537 * entity name`. 24538 */ 24539 /* 24540 * 2.3 otherwise no further condition applies. 24541 */ 24542 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24543 valNeeded = 1; 24544 if (value == NULL) 24545 value = BAD_CAST ""; 24546 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24547 xmlSchemaTypePtr biType; /* The built-in type. */ 24548 /* 24549 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match` 24550 * a literal in the `lexical space` of {base type definition}" 24551 */ 24552 /* 24553 * Whitespace-normalize. 24554 */ 24555 NORMALIZE(type); 24556 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24557 /* 24558 * Get the built-in type. 24559 */ 24560 biType = type->baseType; 24561 while ((biType != NULL) && 24562 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24563 biType = biType->baseType; 24564 24565 if (biType == NULL) { 24566 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24567 "could not get the built-in type"); 24568 goto internal_error; 24569 } 24570 } else 24571 biType = type; 24572 /* 24573 * NOTATIONs need to be processed here, since they need 24574 * to lookup in the hashtable of NOTATION declarations of the schema. 24575 */ 24576 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24577 switch (biType->builtInType) { 24578 case XML_SCHEMAS_NOTATION: 24579 ret = xmlSchemaValidateNotation( 24580 (xmlSchemaValidCtxtPtr) actxt, 24581 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24582 NULL, value, &val, valNeeded); 24583 break; 24584 case XML_SCHEMAS_QNAME: 24585 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24586 value, &val, valNeeded); 24587 break; 24588 default: 24589 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24590 if (valNeeded) 24591 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24592 value, &val, node); 24593 else 24594 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24595 value, NULL, node); 24596 break; 24597 } 24598 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24599 switch (biType->builtInType) { 24600 case XML_SCHEMAS_NOTATION: 24601 ret = xmlSchemaValidateNotation(NULL, 24602 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24603 value, &val, valNeeded); 24604 break; 24605 default: 24606 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24607 if (valNeeded) 24608 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24609 value, &val, node); 24610 else 24611 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24612 value, NULL, node); 24613 break; 24614 } 24615 } else { 24616 /* 24617 * Validation via a public API is not implemented yet. 24618 */ 24619 TODO 24620 goto internal_error; 24621 } 24622 if (ret != 0) { 24623 if (ret < 0) { 24624 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24625 "validating against a built-in type"); 24626 goto internal_error; 24627 } 24628 if (WXS_IS_LIST(type)) 24629 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24630 else 24631 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24632 } 24633 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24634 /* 24635 * Check facets. 24636 */ 24637 ret = xmlSchemaValidateFacets(actxt, node, type, 24638 (xmlSchemaValType) biType->builtInType, value, val, 24639 0, fireErrors); 24640 if (ret != 0) { 24641 if (ret < 0) { 24642 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24643 "validating facets of atomic simple type"); 24644 goto internal_error; 24645 } 24646 if (WXS_IS_LIST(type)) 24647 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24648 else 24649 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24650 } 24651 } 24652 else if (fireErrors && (ret > 0)) 24653 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24654 } else if (WXS_IS_LIST(type)) { 24655 24656 xmlSchemaTypePtr itemType; 24657 const xmlChar *cur, *end; 24658 xmlChar *tmpValue = NULL; 24659 unsigned long len = 0; 24660 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24661 /* 1.2.2 if {variety} is `list` then the string must be a sequence 24662 * of white space separated tokens, each of which `match`es a literal 24663 * in the `lexical space` of {item type definition} 24664 */ 24665 /* 24666 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24667 * the list type has an enum or pattern facet. 24668 */ 24669 NORMALIZE(type); 24670 /* 24671 * VAL TODO: Optimize validation of empty values. 24672 * VAL TODO: We do not have computed values for lists. 24673 */ 24674 itemType = WXS_LIST_ITEMTYPE(type); 24675 cur = value; 24676 do { 24677 while (IS_BLANK_CH(*cur)) 24678 cur++; 24679 end = cur; 24680 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24681 end++; 24682 if (end == cur) 24683 break; 24684 tmpValue = xmlStrndup(cur, end - cur); 24685 len++; 24686 24687 if (valNeeded) 24688 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24689 tmpValue, &curVal, fireErrors, 0, 1); 24690 else 24691 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24692 tmpValue, NULL, fireErrors, 0, 1); 24693 FREE_AND_NULL(tmpValue); 24694 if (curVal != NULL) { 24695 /* 24696 * Add to list of computed values. 24697 */ 24698 if (val == NULL) 24699 val = curVal; 24700 else 24701 xmlSchemaValueAppend(prevVal, curVal); 24702 prevVal = curVal; 24703 curVal = NULL; 24704 } 24705 if (ret != 0) { 24706 if (ret < 0) { 24707 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24708 "validating an item of list simple type"); 24709 goto internal_error; 24710 } 24711 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24712 break; 24713 } 24714 cur = end; 24715 } while (*cur != 0); 24716 FREE_AND_NULL(tmpValue); 24717 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24718 /* 24719 * Apply facets (pattern, enumeration). 24720 */ 24721 ret = xmlSchemaValidateFacets(actxt, node, type, 24722 XML_SCHEMAS_UNKNOWN, value, val, 24723 len, fireErrors); 24724 if (ret != 0) { 24725 if (ret < 0) { 24726 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24727 "validating facets of list simple type"); 24728 goto internal_error; 24729 } 24730 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24731 } 24732 } 24733 if (fireErrors && (ret > 0)) { 24734 /* 24735 * Report the normalized value. 24736 */ 24737 normalize = 1; 24738 NORMALIZE(type); 24739 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24740 } 24741 } else if (WXS_IS_UNION(type)) { 24742 xmlSchemaTypeLinkPtr memberLink; 24743 /* 24744 * TODO: For all datatypes `derived` by `union` whiteSpace does 24745 * not apply directly; however, the normalization behavior of `union` 24746 * types is controlled by the value of whiteSpace on that one of the 24747 * `memberTypes` against which the `union` is successfully validated. 24748 * 24749 * This means that the value is normalized by the first validating 24750 * member type, then the facets of the union type are applied. This 24751 * needs changing of the value! 24752 */ 24753 24754 /* 24755 * 1.2.3 if {variety} is `union` then the string must `match` a 24756 * literal in the `lexical space` of at least one member of 24757 * {member type definitions} 24758 */ 24759 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24760 if (memberLink == NULL) { 24761 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24762 "union simple type has no member types"); 24763 goto internal_error; 24764 } 24765 /* 24766 * Always normalize union type values, since we currently 24767 * cannot store the whitespace information with the value 24768 * itself; otherwise a later value-comparison would be 24769 * not possible. 24770 */ 24771 while (memberLink != NULL) { 24772 if (valNeeded) 24773 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24774 memberLink->type, value, &val, 0, 1, 0); 24775 else 24776 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24777 memberLink->type, value, NULL, 0, 1, 0); 24778 if (ret <= 0) 24779 break; 24780 memberLink = memberLink->next; 24781 } 24782 if (ret != 0) { 24783 if (ret < 0) { 24784 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24785 "validating members of union simple type"); 24786 goto internal_error; 24787 } 24788 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24789 } 24790 /* 24791 * Apply facets (pattern, enumeration). 24792 */ 24793 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24794 /* 24795 * The normalization behavior of `union` types is controlled by 24796 * the value of whiteSpace on that one of the `memberTypes` 24797 * against which the `union` is successfully validated. 24798 */ 24799 NORMALIZE(memberLink->type); 24800 ret = xmlSchemaValidateFacets(actxt, node, type, 24801 XML_SCHEMAS_UNKNOWN, value, val, 24802 0, fireErrors); 24803 if (ret != 0) { 24804 if (ret < 0) { 24805 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24806 "validating facets of union simple type"); 24807 goto internal_error; 24808 } 24809 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24810 } 24811 } 24812 if (fireErrors && (ret > 0)) 24813 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24814 } 24815 24816 if (normValue != NULL) 24817 xmlFree(normValue); 24818 if (ret == 0) { 24819 if (retVal != NULL) 24820 *retVal = val; 24821 else if (val != NULL) 24822 xmlSchemaFreeValue(val); 24823 } else if (val != NULL) 24824 xmlSchemaFreeValue(val); 24825 return (ret); 24826 internal_error: 24827 if (normValue != NULL) 24828 xmlFree(normValue); 24829 if (val != NULL) 24830 xmlSchemaFreeValue(val); 24831 return (-1); 24832 } 24833 24834 static int 24835 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24836 const xmlChar *value, 24837 const xmlChar **nsName, 24838 const xmlChar **localName) 24839 { 24840 int ret = 0; 24841 24842 if ((nsName == NULL) || (localName == NULL)) 24843 return (-1); 24844 *nsName = NULL; 24845 *localName = NULL; 24846 24847 ret = xmlValidateQName(value, 1); 24848 if (ret == -1) 24849 return (-1); 24850 if (ret > 0) { 24851 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24852 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24853 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24854 return (1); 24855 } 24856 { 24857 xmlChar *local = NULL; 24858 xmlChar *prefix; 24859 24860 /* 24861 * NOTE: xmlSplitQName2 will return a duplicated 24862 * string. 24863 */ 24864 local = xmlSplitQName2(value, &prefix); 24865 if (local == NULL) 24866 *localName = xmlDictLookup(vctxt->dict, value, -1); 24867 else { 24868 *localName = xmlDictLookup(vctxt->dict, local, -1); 24869 xmlFree(local); 24870 } 24871 24872 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24873 24874 if (prefix != NULL) { 24875 xmlFree(prefix); 24876 /* 24877 * A namespace must be found if the prefix is NOT NULL. 24878 */ 24879 if (*nsName == NULL) { 24880 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24881 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24882 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24883 "The QName value '%s' has no " 24884 "corresponding namespace declaration in scope", 24885 value, NULL); 24886 return (2); 24887 } 24888 } 24889 } 24890 return (0); 24891 } 24892 24893 static int 24894 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24895 xmlSchemaAttrInfoPtr iattr, 24896 xmlSchemaTypePtr *localType, 24897 xmlSchemaElementPtr elemDecl) 24898 { 24899 int ret = 0; 24900 /* 24901 * cvc-elt (3.3.4) : (4) 24902 * AND 24903 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24904 * (1.2.1.2.1) - (1.2.1.2.4) 24905 * Handle 'xsi:type'. 24906 */ 24907 if (localType == NULL) 24908 return (-1); 24909 *localType = NULL; 24910 if (iattr == NULL) 24911 return (0); 24912 else { 24913 const xmlChar *nsName = NULL, *local = NULL; 24914 /* 24915 * TODO: We should report a *warning* that the type was overridden 24916 * by the instance. 24917 */ 24918 ACTIVATE_ATTRIBUTE(iattr); 24919 /* 24920 * (cvc-elt) (3.3.4) : (4.1) 24921 * (cvc-assess-elt) (1.2.1.2.2) 24922 */ 24923 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24924 &nsName, &local); 24925 if (ret != 0) { 24926 if (ret < 0) { 24927 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24928 "calling xmlSchemaQNameExpand() to validate the " 24929 "attribute 'xsi:type'"); 24930 goto internal_error; 24931 } 24932 goto exit; 24933 } 24934 /* 24935 * (cvc-elt) (3.3.4) : (4.2) 24936 * (cvc-assess-elt) (1.2.1.2.3) 24937 */ 24938 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24939 if (*localType == NULL) { 24940 xmlChar *str = NULL; 24941 24942 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24943 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24944 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24945 "The QName value '%s' of the xsi:type attribute does not " 24946 "resolve to a type definition", 24947 xmlSchemaFormatQName(&str, nsName, local), NULL); 24948 FREE_AND_NULL(str); 24949 ret = vctxt->err; 24950 goto exit; 24951 } 24952 if (elemDecl != NULL) { 24953 int set = 0; 24954 24955 /* 24956 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24957 * "The `local type definition` must be validly 24958 * derived from the {type definition} given the union of 24959 * the {disallowed substitutions} and the {type definition}'s 24960 * {prohibited substitutions}, as defined in 24961 * Type Derivation OK (Complex) ($3.4.6) 24962 * (if it is a complex type definition), 24963 * or given {disallowed substitutions} as defined in Type 24964 * Derivation OK (Simple) ($3.14.6) (if it is a simple type 24965 * definition)." 24966 * 24967 * {disallowed substitutions}: the "block" on the element decl. 24968 * {prohibited substitutions}: the "block" on the type def. 24969 */ 24970 /* 24971 * OPTIMIZE TODO: We could map types already evaluated 24972 * to be validly derived from other types to avoid checking 24973 * this over and over for the same types. 24974 */ 24975 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24976 (elemDecl->subtypes->flags & 24977 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24978 set |= SUBSET_EXTENSION; 24979 24980 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24981 (elemDecl->subtypes->flags & 24982 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24983 set |= SUBSET_RESTRICTION; 24984 24985 /* 24986 * REMOVED and CHANGED since this produced a parser context 24987 * which adds to the string dict of the schema. So this would 24988 * change the schema and we don't want this. We don't need 24989 * the parser context anymore. 24990 * 24991 * if ((vctxt->pctxt == NULL) && 24992 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24993 * return (-1); 24994 */ 24995 24996 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24997 elemDecl->subtypes, set) != 0) { 24998 xmlChar *str = NULL; 24999 25000 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25001 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 25002 "The type definition '%s', specified by xsi:type, is " 25003 "blocked or not validly derived from the type definition " 25004 "of the element declaration", 25005 xmlSchemaFormatQName(&str, 25006 (*localType)->targetNamespace, 25007 (*localType)->name), 25008 NULL); 25009 FREE_AND_NULL(str); 25010 ret = vctxt->err; 25011 *localType = NULL; 25012 } 25013 } 25014 } 25015 exit: 25016 ACTIVATE_ELEM; 25017 return (ret); 25018 internal_error: 25019 ACTIVATE_ELEM; 25020 return (-1); 25021 } 25022 25023 static int 25024 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 25025 { 25026 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 25027 xmlSchemaTypePtr actualType; 25028 25029 /* 25030 * cvc-elt (3.3.4) : 1 25031 */ 25032 if (elemDecl == NULL) { 25033 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 25034 "No matching declaration available"); 25035 return (vctxt->err); 25036 } 25037 actualType = WXS_ELEM_TYPEDEF(elemDecl); 25038 /* 25039 * cvc-elt (3.3.4) : 2 25040 */ 25041 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 25042 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 25043 "The element declaration is abstract"); 25044 return (vctxt->err); 25045 } 25046 if (actualType == NULL) { 25047 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25048 "The type definition is absent"); 25049 return (XML_SCHEMAV_CVC_TYPE_1); 25050 } 25051 if (vctxt->nbAttrInfos != 0) { 25052 int ret; 25053 xmlSchemaAttrInfoPtr iattr; 25054 /* 25055 * cvc-elt (3.3.4) : 3 25056 * Handle 'xsi:nil'. 25057 */ 25058 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25059 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25060 if (iattr) { 25061 ACTIVATE_ATTRIBUTE(iattr); 25062 /* 25063 * Validate the value. 25064 */ 25065 ret = xmlSchemaVCheckCVCSimpleType( 25066 ACTXT_CAST vctxt, NULL, 25067 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25068 iattr->value, &(iattr->val), 1, 0, 0); 25069 ACTIVATE_ELEM; 25070 if (ret < 0) { 25071 VERROR_INT("xmlSchemaValidateElemDecl", 25072 "calling xmlSchemaVCheckCVCSimpleType() to " 25073 "validate the attribute 'xsi:nil'"); 25074 return (-1); 25075 } 25076 if (ret == 0) { 25077 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25078 /* 25079 * cvc-elt (3.3.4) : 3.1 25080 */ 25081 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25082 "The element is not 'nillable'"); 25083 /* Does not return an error on purpose. */ 25084 } else { 25085 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25086 /* 25087 * cvc-elt (3.3.4) : 3.2.2 25088 */ 25089 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25090 (elemDecl->value != NULL)) { 25091 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25092 "The element cannot be 'nilled' because " 25093 "there is a fixed value constraint defined " 25094 "for it"); 25095 /* Does not return an error on purpose. */ 25096 } else 25097 vctxt->inode->flags |= 25098 XML_SCHEMA_ELEM_INFO_NILLED; 25099 } 25100 } 25101 } 25102 } 25103 /* 25104 * cvc-elt (3.3.4) : 4 25105 * Handle 'xsi:type'. 25106 */ 25107 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25108 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25109 if (iattr) { 25110 xmlSchemaTypePtr localType = NULL; 25111 25112 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25113 elemDecl); 25114 if (ret != 0) { 25115 if (ret == -1) { 25116 VERROR_INT("xmlSchemaValidateElemDecl", 25117 "calling xmlSchemaProcessXSIType() to " 25118 "process the attribute 'xsi:type'"); 25119 return (-1); 25120 } 25121 /* Does not return an error on purpose. */ 25122 } 25123 if (localType != NULL) { 25124 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25125 actualType = localType; 25126 } 25127 } 25128 } 25129 /* 25130 * IDC: Register identity-constraint XPath matchers. 25131 */ 25132 if ((elemDecl->idcs != NULL) && 25133 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25134 return (-1); 25135 /* 25136 * No actual type definition. 25137 */ 25138 if (actualType == NULL) { 25139 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25140 "The type definition is absent"); 25141 return (XML_SCHEMAV_CVC_TYPE_1); 25142 } 25143 /* 25144 * Remember the actual type definition. 25145 */ 25146 vctxt->inode->typeDef = actualType; 25147 25148 return (0); 25149 } 25150 25151 static int 25152 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25153 { 25154 xmlSchemaAttrInfoPtr iattr; 25155 int ret = 0, i; 25156 25157 /* 25158 * SPEC cvc-type (3.1.1) 25159 * "The attributes of must be empty, excepting those whose namespace 25160 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25161 * whose local name is one of type, nil, schemaLocation or 25162 * noNamespaceSchemaLocation." 25163 */ 25164 if (vctxt->nbAttrInfos == 0) 25165 return (0); 25166 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25167 iattr = vctxt->attrInfos[i]; 25168 if (! iattr->metaType) { 25169 ACTIVATE_ATTRIBUTE(iattr) 25170 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25171 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25172 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25173 } 25174 } 25175 ACTIVATE_ELEM 25176 return (ret); 25177 } 25178 25179 /* 25180 * Cleanup currently used attribute infos. 25181 */ 25182 static void 25183 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25184 { 25185 int i; 25186 xmlSchemaAttrInfoPtr attr; 25187 25188 if (vctxt->nbAttrInfos == 0) 25189 return; 25190 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25191 attr = vctxt->attrInfos[i]; 25192 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25193 if (attr->localName != NULL) 25194 xmlFree((xmlChar *) attr->localName); 25195 if (attr->nsName != NULL) 25196 xmlFree((xmlChar *) attr->nsName); 25197 } 25198 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25199 if (attr->value != NULL) 25200 xmlFree((xmlChar *) attr->value); 25201 } 25202 if (attr->val != NULL) { 25203 xmlSchemaFreeValue(attr->val); 25204 attr->val = NULL; 25205 } 25206 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25207 } 25208 vctxt->nbAttrInfos = 0; 25209 } 25210 25211 /* 25212 * 3.4.4 Complex Type Definition Validation Rules 25213 * Element Locally Valid (Complex Type) (cvc-complex-type) 25214 * 3.2.4 Attribute Declaration Validation Rules 25215 * Validation Rule: Attribute Locally Valid (cvc-attribute) 25216 * Attribute Locally Valid (Use) (cvc-au) 25217 * 25218 * Only "assessed" attribute information items will be visible to 25219 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25220 */ 25221 static int 25222 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25223 { 25224 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25225 xmlSchemaItemListPtr attrUseList; 25226 xmlSchemaAttributeUsePtr attrUse = NULL; 25227 xmlSchemaAttributePtr attrDecl = NULL; 25228 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25229 int i, j, found, nbAttrs, nbUses; 25230 int xpathRes = 0, res, wildIDs = 0, fixed; 25231 xmlNodePtr defAttrOwnerElem = NULL; 25232 25233 /* 25234 * SPEC (cvc-attribute) 25235 * (1) "The declaration must not be `absent` (see Missing 25236 * Sub-components ($5.3) for how this can fail to be 25237 * the case)." 25238 * (2) "Its {type definition} must not be absent." 25239 * 25240 * NOTE (1) + (2): This is not handled here, since we currently do not 25241 * allow validation against schemas which have missing sub-components. 25242 * 25243 * SPEC (cvc-complex-type) 25244 * (3) "For each attribute information item in the element information 25245 * item's [attributes] excepting those whose [namespace name] is 25246 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25247 * [local name] is one of type, nil, schemaLocation or 25248 * noNamespaceSchemaLocation, the appropriate case among the following 25249 * must be true: 25250 * 25251 */ 25252 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25253 /* 25254 * @nbAttrs is the number of attributes present in the instance. 25255 */ 25256 nbAttrs = vctxt->nbAttrInfos; 25257 if (attrUseList != NULL) 25258 nbUses = attrUseList->nbItems; 25259 else 25260 nbUses = 0; 25261 for (i = 0; i < nbUses; i++) { 25262 found = 0; 25263 attrUse = attrUseList->items[i]; 25264 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25265 for (j = 0; j < nbAttrs; j++) { 25266 iattr = vctxt->attrInfos[j]; 25267 /* 25268 * SPEC (cvc-complex-type) (3) 25269 * Skip meta attributes. 25270 */ 25271 if (iattr->metaType) 25272 continue; 25273 if (iattr->localName[0] != attrDecl->name[0]) 25274 continue; 25275 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25276 continue; 25277 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25278 continue; 25279 found = 1; 25280 /* 25281 * SPEC (cvc-complex-type) 25282 * (3.1) "If there is among the {attribute uses} an attribute 25283 * use with an {attribute declaration} whose {name} matches 25284 * the attribute information item's [local name] and whose 25285 * {target namespace} is identical to the attribute information 25286 * item's [namespace name] (where an `absent` {target namespace} 25287 * is taken to be identical to a [namespace name] with no value), 25288 * then the attribute information must be `valid` with respect 25289 * to that attribute use as per Attribute Locally Valid (Use) 25290 * ($3.5.4). In this case the {attribute declaration} of that 25291 * attribute use is the `context-determined declaration` for the 25292 * attribute information item with respect to Schema-Validity 25293 * Assessment (Attribute) ($3.2.4) and 25294 * Assessment Outcome (Attribute) ($3.2.5). 25295 */ 25296 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25297 iattr->use = attrUse; 25298 /* 25299 * Context-determined declaration. 25300 */ 25301 iattr->decl = attrDecl; 25302 iattr->typeDef = attrDecl->subtypes; 25303 break; 25304 } 25305 25306 if (found) 25307 continue; 25308 25309 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25310 /* 25311 * Handle non-existent, required attributes. 25312 * 25313 * SPEC (cvc-complex-type) 25314 * (4) "The {attribute declaration} of each attribute use in 25315 * the {attribute uses} whose {required} is true matches one 25316 * of the attribute information items in the element information 25317 * item's [attributes] as per clause 3.1 above." 25318 */ 25319 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25320 if (tmpiattr == NULL) { 25321 VERROR_INT( 25322 "xmlSchemaVAttributesComplex", 25323 "calling xmlSchemaGetFreshAttrInfo()"); 25324 return (-1); 25325 } 25326 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25327 tmpiattr->use = attrUse; 25328 tmpiattr->decl = attrDecl; 25329 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25330 ((attrUse->defValue != NULL) || 25331 (attrDecl->defValue != NULL))) { 25332 /* 25333 * Handle non-existent, optional, default/fixed attributes. 25334 */ 25335 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25336 if (tmpiattr == NULL) { 25337 VERROR_INT( 25338 "xmlSchemaVAttributesComplex", 25339 "calling xmlSchemaGetFreshAttrInfo()"); 25340 return (-1); 25341 } 25342 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25343 tmpiattr->use = attrUse; 25344 tmpiattr->decl = attrDecl; 25345 tmpiattr->typeDef = attrDecl->subtypes; 25346 tmpiattr->localName = attrDecl->name; 25347 tmpiattr->nsName = attrDecl->targetNamespace; 25348 } 25349 } 25350 25351 if (vctxt->nbAttrInfos == 0) 25352 return (0); 25353 /* 25354 * Validate against the wildcard. 25355 */ 25356 if (type->attributeWildcard != NULL) { 25357 /* 25358 * SPEC (cvc-complex-type) 25359 * (3.2.1) "There must be an {attribute wildcard}." 25360 */ 25361 for (i = 0; i < nbAttrs; i++) { 25362 iattr = vctxt->attrInfos[i]; 25363 /* 25364 * SPEC (cvc-complex-type) (3) 25365 * Skip meta attributes. 25366 */ 25367 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25368 continue; 25369 /* 25370 * SPEC (cvc-complex-type) 25371 * (3.2.2) "The attribute information item must be `valid` with 25372 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)." 25373 * 25374 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25375 * "... its [namespace name] must be `valid` with respect to 25376 * the wildcard constraint, as defined in Wildcard allows 25377 * Namespace Name ($3.10.4)." 25378 */ 25379 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25380 iattr->nsName) == 0) { 25381 /* 25382 * Handle processContents. 25383 * 25384 * SPEC (cvc-wildcard): 25385 * processContents | context-determined declaration: 25386 * "strict" "mustFind" 25387 * "lax" "none" 25388 * "skip" "skip" 25389 */ 25390 if (type->attributeWildcard->processContents == 25391 XML_SCHEMAS_ANY_SKIP) { 25392 /* 25393 * context-determined declaration = "skip" 25394 * 25395 * SPEC PSVI Assessment Outcome (Attribute) 25396 * [validity] = "notKnown" 25397 * [validation attempted] = "none" 25398 */ 25399 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25400 continue; 25401 } 25402 /* 25403 * Find an attribute declaration. 25404 */ 25405 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25406 iattr->localName, iattr->nsName); 25407 if (iattr->decl != NULL) { 25408 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25409 /* 25410 * SPEC (cvc-complex-type) 25411 * (5) "Let [Definition:] the wild IDs be the set of 25412 * all attribute information item to which clause 3.2 25413 * applied and whose `validation` resulted in a 25414 * `context-determined declaration` of mustFind or no 25415 * `context-determined declaration` at all, and whose 25416 * [local name] and [namespace name] resolve (as 25417 * defined by QName resolution (Instance) ($3.15.4)) to 25418 * an attribute declaration whose {type definition} is 25419 * or is derived from ID. Then all of the following 25420 * must be true:" 25421 */ 25422 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25423 if (xmlSchemaIsDerivedFromBuiltInType( 25424 iattr->typeDef, XML_SCHEMAS_ID)) { 25425 /* 25426 * SPEC (5.1) "There must be no more than one 25427 * item in `wild IDs`." 25428 */ 25429 if (wildIDs != 0) { 25430 /* VAL TODO */ 25431 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25432 TODO 25433 continue; 25434 } 25435 wildIDs++; 25436 /* 25437 * SPEC (cvc-complex-type) 25438 * (5.2) "If `wild IDs` is non-empty, there must not 25439 * be any attribute uses among the {attribute uses} 25440 * whose {attribute declaration}'s {type definition} 25441 * is or is derived from ID." 25442 */ 25443 if (attrUseList != NULL) { 25444 for (j = 0; j < attrUseList->nbItems; j++) { 25445 if (xmlSchemaIsDerivedFromBuiltInType( 25446 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25447 XML_SCHEMAS_ID)) { 25448 /* URGENT VAL TODO: implement */ 25449 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25450 TODO 25451 break; 25452 } 25453 } 25454 } 25455 } 25456 } else if (type->attributeWildcard->processContents == 25457 XML_SCHEMAS_ANY_LAX) { 25458 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25459 /* 25460 * SPEC PSVI Assessment Outcome (Attribute) 25461 * [validity] = "notKnown" 25462 * [validation attempted] = "none" 25463 */ 25464 } else { 25465 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25466 } 25467 } 25468 } 25469 } 25470 25471 if (vctxt->nbAttrInfos == 0) 25472 return (0); 25473 25474 /* 25475 * Get the owner element; needed for creation of default attributes. 25476 * This fixes bug #341337, reported by David Grohmann. 25477 */ 25478 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25479 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25480 if (ielem && ielem->node && ielem->node->doc) 25481 defAttrOwnerElem = ielem->node; 25482 } 25483 /* 25484 * Validate values, create default attributes, evaluate IDCs. 25485 */ 25486 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25487 iattr = vctxt->attrInfos[i]; 25488 /* 25489 * VAL TODO: Note that we won't try to resolve IDCs to 25490 * "lax" and "skip" validated attributes. Check what to 25491 * do in this case. 25492 */ 25493 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25494 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25495 continue; 25496 /* 25497 * VAL TODO: What to do if the type definition is missing? 25498 */ 25499 if (iattr->typeDef == NULL) { 25500 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25501 continue; 25502 } 25503 25504 ACTIVATE_ATTRIBUTE(iattr); 25505 fixed = 0; 25506 xpathRes = 0; 25507 25508 if (vctxt->xpathStates != NULL) { 25509 /* 25510 * Evaluate IDCs. 25511 */ 25512 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25513 XML_ATTRIBUTE_NODE); 25514 if (xpathRes == -1) { 25515 VERROR_INT("xmlSchemaVAttributesComplex", 25516 "calling xmlSchemaXPathEvaluate()"); 25517 goto internal_error; 25518 } 25519 } 25520 25521 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25522 /* 25523 * Default/fixed attributes. 25524 * We need the value only if we need to resolve IDCs or 25525 * will create default attributes. 25526 */ 25527 if ((xpathRes) || (defAttrOwnerElem)) { 25528 if (iattr->use->defValue != NULL) { 25529 iattr->value = (xmlChar *) iattr->use->defValue; 25530 iattr->val = iattr->use->defVal; 25531 } else { 25532 iattr->value = (xmlChar *) iattr->decl->defValue; 25533 iattr->val = iattr->decl->defVal; 25534 } 25535 /* 25536 * IDCs will consume the precomputed default value, 25537 * so we need to clone it. 25538 */ 25539 if (iattr->val == NULL) { 25540 VERROR_INT("xmlSchemaVAttributesComplex", 25541 "default/fixed value on an attribute use was " 25542 "not precomputed"); 25543 goto internal_error; 25544 } 25545 iattr->val = xmlSchemaCopyValue(iattr->val); 25546 if (iattr->val == NULL) { 25547 VERROR_INT("xmlSchemaVAttributesComplex", 25548 "calling xmlSchemaCopyValue()"); 25549 goto internal_error; 25550 } 25551 } 25552 /* 25553 * PSVI: Add the default attribute to the current element. 25554 * VAL TODO: Should we use the *normalized* value? This currently 25555 * uses the *initial* value. 25556 */ 25557 25558 if (defAttrOwnerElem) { 25559 xmlChar *normValue; 25560 const xmlChar *value; 25561 25562 value = iattr->value; 25563 /* 25564 * Normalize the value. 25565 */ 25566 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25567 iattr->value); 25568 if (normValue != NULL) 25569 value = BAD_CAST normValue; 25570 25571 if (iattr->nsName == NULL) { 25572 if (xmlNewProp(defAttrOwnerElem, 25573 iattr->localName, value) == NULL) { 25574 VERROR_INT("xmlSchemaVAttributesComplex", 25575 "calling xmlNewProp()"); 25576 if (normValue != NULL) 25577 xmlFree(normValue); 25578 goto internal_error; 25579 } 25580 } else { 25581 xmlNsPtr ns; 25582 25583 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25584 defAttrOwnerElem, iattr->nsName); 25585 if (ns == NULL) { 25586 xmlChar prefix[12]; 25587 int counter = 0; 25588 25589 /* 25590 * Create a namespace declaration on the validation 25591 * root node if no namespace declaration is in scope. 25592 */ 25593 do { 25594 snprintf((char *) prefix, 12, "p%d", counter++); 25595 ns = xmlSearchNs(defAttrOwnerElem->doc, 25596 defAttrOwnerElem, BAD_CAST prefix); 25597 if (counter > 1000) { 25598 VERROR_INT( 25599 "xmlSchemaVAttributesComplex", 25600 "could not compute a ns prefix for a " 25601 "default/fixed attribute"); 25602 if (normValue != NULL) 25603 xmlFree(normValue); 25604 goto internal_error; 25605 } 25606 } while (ns != NULL); 25607 ns = xmlNewNs(vctxt->validationRoot, 25608 iattr->nsName, BAD_CAST prefix); 25609 } 25610 /* 25611 * TODO: 25612 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25613 * If we have QNames: do we need to ensure there's a 25614 * prefix defined for the QName? 25615 */ 25616 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25617 } 25618 if (normValue != NULL) 25619 xmlFree(normValue); 25620 } 25621 /* 25622 * Go directly to IDC evaluation. 25623 */ 25624 goto eval_idcs; 25625 } 25626 /* 25627 * Validate the value. 25628 */ 25629 if (vctxt->value != NULL) { 25630 /* 25631 * Free last computed value; just for safety reasons. 25632 */ 25633 xmlSchemaFreeValue(vctxt->value); 25634 vctxt->value = NULL; 25635 } 25636 /* 25637 * Note that the attribute *use* can be unavailable, if 25638 * the attribute was a wild attribute. 25639 */ 25640 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25641 ((iattr->use != NULL) && 25642 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25643 fixed = 1; 25644 else 25645 fixed = 0; 25646 /* 25647 * SPEC (cvc-attribute) 25648 * (3) "The item's `normalized value` must be locally `valid` 25649 * with respect to that {type definition} as per 25650 * String Valid ($3.14.4)." 25651 * 25652 * VAL TODO: Do we already have the 25653 * "normalized attribute value" here? 25654 */ 25655 if (xpathRes || fixed) { 25656 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25657 /* 25658 * Request a computed value. 25659 */ 25660 res = xmlSchemaVCheckCVCSimpleType( 25661 ACTXT_CAST vctxt, 25662 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25663 1, 1, 0); 25664 } else { 25665 res = xmlSchemaVCheckCVCSimpleType( 25666 ACTXT_CAST vctxt, 25667 iattr->node, iattr->typeDef, iattr->value, NULL, 25668 1, 0, 0); 25669 } 25670 25671 if (res != 0) { 25672 if (res == -1) { 25673 VERROR_INT("xmlSchemaVAttributesComplex", 25674 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25675 goto internal_error; 25676 } 25677 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25678 /* 25679 * SPEC PSVI Assessment Outcome (Attribute) 25680 * [validity] = "invalid" 25681 */ 25682 goto eval_idcs; 25683 } 25684 25685 if (fixed) { 25686 /* 25687 * SPEC Attribute Locally Valid (Use) (cvc-au) 25688 * "For an attribute information item to be `valid` 25689 * with respect to an attribute use its *normalized* 25690 * value must match the *canonical* lexical 25691 * representation of the attribute use's {value 25692 * constraint}value, if it is present and fixed." 25693 * 25694 * VAL TODO: The requirement for the *canonical* value 25695 * will be removed in XML Schema 1.1. 25696 */ 25697 /* 25698 * SPEC Attribute Locally Valid (cvc-attribute) 25699 * (4) "The item's *actual* value must match the *value* of 25700 * the {value constraint}, if it is present and fixed." 25701 */ 25702 if (iattr->val == NULL) { 25703 /* VAL TODO: A value was not precomputed. */ 25704 TODO 25705 goto eval_idcs; 25706 } 25707 if ((iattr->use != NULL) && 25708 (iattr->use->defValue != NULL)) { 25709 if (iattr->use->defVal == NULL) { 25710 /* VAL TODO: A default value was not precomputed. */ 25711 TODO 25712 goto eval_idcs; 25713 } 25714 iattr->vcValue = iattr->use->defValue; 25715 /* 25716 if (xmlSchemaCompareValuesWhtsp(attr->val, 25717 (xmlSchemaWhitespaceValueType) ws, 25718 attr->use->defVal, 25719 (xmlSchemaWhitespaceValueType) ws) != 0) { 25720 */ 25721 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25722 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25723 } else { 25724 if (iattr->decl->defVal == NULL) { 25725 /* VAL TODO: A default value was not precomputed. */ 25726 TODO 25727 goto eval_idcs; 25728 } 25729 iattr->vcValue = iattr->decl->defValue; 25730 /* 25731 if (xmlSchemaCompareValuesWhtsp(attr->val, 25732 (xmlSchemaWhitespaceValueType) ws, 25733 attrDecl->defVal, 25734 (xmlSchemaWhitespaceValueType) ws) != 0) { 25735 */ 25736 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25737 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25738 } 25739 /* 25740 * [validity] = "valid" 25741 */ 25742 } 25743 eval_idcs: 25744 /* 25745 * Evaluate IDCs. 25746 */ 25747 if (xpathRes) { 25748 if (xmlSchemaXPathProcessHistory(vctxt, 25749 vctxt->depth +1) == -1) { 25750 VERROR_INT("xmlSchemaVAttributesComplex", 25751 "calling xmlSchemaXPathEvaluate()"); 25752 goto internal_error; 25753 } 25754 } else if (vctxt->xpathStates != NULL) 25755 xmlSchemaXPathPop(vctxt); 25756 } 25757 25758 /* 25759 * Report errors. 25760 */ 25761 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25762 iattr = vctxt->attrInfos[i]; 25763 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25764 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25765 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25766 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25767 continue; 25768 ACTIVATE_ATTRIBUTE(iattr); 25769 switch (iattr->state) { 25770 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25771 xmlChar *str = NULL; 25772 ACTIVATE_ELEM; 25773 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25774 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25775 "The attribute '%s' is required but missing", 25776 xmlSchemaFormatQName(&str, 25777 iattr->decl->targetNamespace, 25778 iattr->decl->name), 25779 NULL); 25780 FREE_AND_NULL(str) 25781 break; 25782 } 25783 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25784 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25785 "The type definition is absent"); 25786 break; 25787 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25788 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25789 XML_SCHEMAV_CVC_AU, NULL, NULL, 25790 "The value '%s' does not match the fixed " 25791 "value constraint '%s'", 25792 iattr->value, iattr->vcValue); 25793 break; 25794 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25795 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25796 "No matching global attribute declaration available, but " 25797 "demanded by the strict wildcard"); 25798 break; 25799 case XML_SCHEMAS_ATTR_UNKNOWN: 25800 if (iattr->metaType) 25801 break; 25802 /* 25803 * MAYBE VAL TODO: One might report different error messages 25804 * for the following errors. 25805 */ 25806 if (type->attributeWildcard == NULL) { 25807 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25808 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25809 } else { 25810 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25811 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25812 } 25813 break; 25814 default: 25815 break; 25816 } 25817 } 25818 25819 ACTIVATE_ELEM; 25820 return (0); 25821 internal_error: 25822 ACTIVATE_ELEM; 25823 return (-1); 25824 } 25825 25826 static int 25827 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25828 int *skip) 25829 { 25830 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25831 /* 25832 * The namespace of the element was already identified to be 25833 * matching the wildcard. 25834 */ 25835 if ((skip == NULL) || (wild == NULL) || 25836 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25837 VERROR_INT("xmlSchemaValidateElemWildcard", 25838 "bad arguments"); 25839 return (-1); 25840 } 25841 *skip = 0; 25842 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25843 /* 25844 * URGENT VAL TODO: Either we need to position the stream to the 25845 * next sibling, or walk the whole subtree. 25846 */ 25847 *skip = 1; 25848 return (0); 25849 } 25850 { 25851 xmlSchemaElementPtr decl = NULL; 25852 25853 decl = xmlSchemaGetElem(vctxt->schema, 25854 vctxt->inode->localName, vctxt->inode->nsName); 25855 if (decl != NULL) { 25856 vctxt->inode->decl = decl; 25857 return (0); 25858 } 25859 } 25860 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25861 /* VAL TODO: Change to proper error code. */ 25862 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25863 "No matching global element declaration available, but " 25864 "demanded by the strict wildcard"); 25865 return (vctxt->err); 25866 } 25867 if (vctxt->nbAttrInfos != 0) { 25868 xmlSchemaAttrInfoPtr iattr; 25869 /* 25870 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25871 * (1.2.1.2.1) - (1.2.1.2.3 ) 25872 * 25873 * Use the xsi:type attribute for the type definition. 25874 */ 25875 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25876 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25877 if (iattr != NULL) { 25878 if (xmlSchemaProcessXSIType(vctxt, iattr, 25879 &(vctxt->inode->typeDef), NULL) == -1) { 25880 VERROR_INT("xmlSchemaValidateElemWildcard", 25881 "calling xmlSchemaProcessXSIType() to " 25882 "process the attribute 'xsi:nil'"); 25883 return (-1); 25884 } 25885 /* 25886 * Don't return an error on purpose. 25887 */ 25888 return (0); 25889 } 25890 } 25891 /* 25892 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25893 * 25894 * Fallback to "anyType". 25895 */ 25896 vctxt->inode->typeDef = 25897 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25898 return (0); 25899 } 25900 25901 /* 25902 * xmlSchemaCheckCOSValidDefault: 25903 * 25904 * This will be called if: not nilled, no content and a default/fixed 25905 * value is provided. 25906 */ 25907 25908 static int 25909 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25910 const xmlChar *value, 25911 xmlSchemaValPtr *val) 25912 { 25913 int ret = 0; 25914 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25915 25916 /* 25917 * cos-valid-default: 25918 * Schema Component Constraint: Element Default Valid (Immediate) 25919 * For a string to be a valid default with respect to a type 25920 * definition the appropriate case among the following must be true: 25921 */ 25922 if WXS_IS_COMPLEX(inode->typeDef) { 25923 /* 25924 * Complex type. 25925 * 25926 * SPEC (2.1) "its {content type} must be a simple type definition 25927 * or mixed." 25928 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25929 * type}'s particle must be `emptiable` as defined by 25930 * Particle Emptiable ($3.9.6)." 25931 */ 25932 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25933 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25934 (! WXS_EMPTIABLE(inode->typeDef)))) { 25935 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25936 /* NOTE that this covers (2.2.2) as well. */ 25937 VERROR(ret, NULL, 25938 "For a string to be a valid default, the type definition " 25939 "must be a simple type or a complex type with simple content " 25940 "or mixed content and a particle emptiable"); 25941 return(ret); 25942 } 25943 } 25944 /* 25945 * 1 If the type definition is a simple type definition, then the string 25946 * must be `valid` with respect to that definition as defined by String 25947 * Valid ($3.14.4). 25948 * 25949 * AND 25950 * 25951 * 2.2.1 If the {content type} is a simple type definition, then the 25952 * string must be `valid` with respect to that simple type definition 25953 * as defined by String Valid ($3.14.4). 25954 */ 25955 if (WXS_IS_SIMPLE(inode->typeDef)) { 25956 25957 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25958 NULL, inode->typeDef, value, val, 1, 1, 0); 25959 25960 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25961 25962 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25963 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25964 } 25965 if (ret < 0) { 25966 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25967 "calling xmlSchemaVCheckCVCSimpleType()"); 25968 } 25969 return (ret); 25970 } 25971 25972 static void 25973 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED, 25974 const xmlChar * name ATTRIBUTE_UNUSED, 25975 void *transdata, void *inputdata) 25976 { 25977 xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata; 25978 xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata; 25979 inode->decl = item; 25980 #ifdef DEBUG_CONTENT 25981 { 25982 xmlChar *str = NULL; 25983 25984 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25985 xmlGenericError(xmlGenericErrorContext, 25986 "AUTOMATON callback for '%s' [declaration]\n", 25987 xmlSchemaFormatQName(&str, 25988 inode->localName, inode->nsName)); 25989 } else { 25990 xmlGenericError(xmlGenericErrorContext, 25991 "AUTOMATON callback for '%s' [wildcard]\n", 25992 xmlSchemaFormatQName(&str, 25993 inode->localName, inode->nsName)); 25994 25995 } 25996 FREE_AND_NULL(str) 25997 } 25998 #endif 25999 } 26000 26001 static int 26002 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 26003 { 26004 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 26005 if (vctxt->inode == NULL) { 26006 VERROR_INT("xmlSchemaValidatorPushElem", 26007 "calling xmlSchemaGetFreshElemInfo()"); 26008 return (-1); 26009 } 26010 vctxt->nbAttrInfos = 0; 26011 return (0); 26012 } 26013 26014 static int 26015 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 26016 xmlSchemaNodeInfoPtr inode, 26017 xmlSchemaTypePtr type, 26018 const xmlChar *value) 26019 { 26020 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 26021 return (xmlSchemaVCheckCVCSimpleType( 26022 ACTXT_CAST vctxt, NULL, 26023 type, value, &(inode->val), 1, 1, 0)); 26024 else 26025 return (xmlSchemaVCheckCVCSimpleType( 26026 ACTXT_CAST vctxt, NULL, 26027 type, value, NULL, 1, 0, 0)); 26028 } 26029 26030 26031 26032 /* 26033 * Process END of element. 26034 */ 26035 static int 26036 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 26037 { 26038 int ret = 0; 26039 xmlSchemaNodeInfoPtr inode = vctxt->inode; 26040 26041 if (vctxt->nbAttrInfos != 0) 26042 xmlSchemaClearAttrInfos(vctxt); 26043 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 26044 /* 26045 * This element was not expected; 26046 * we will not validate child elements of broken parents. 26047 * Skip validation of all content of the parent. 26048 */ 26049 vctxt->skipDepth = vctxt->depth -1; 26050 goto end_elem; 26051 } 26052 if ((inode->typeDef == NULL) || 26053 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 26054 /* 26055 * 1. the type definition might be missing if the element was 26056 * error prone 26057 * 2. it might be abstract. 26058 */ 26059 goto end_elem; 26060 } 26061 /* 26062 * Check the content model. 26063 */ 26064 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26065 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26066 26067 /* 26068 * Workaround for "anyType". 26069 */ 26070 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26071 goto character_content; 26072 26073 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26074 xmlChar *values[10]; 26075 int terminal, nbval = 10, nbneg; 26076 26077 if (inode->regexCtxt == NULL) { 26078 /* 26079 * Create the regex context. 26080 */ 26081 inode->regexCtxt = 26082 xmlRegNewExecCtxt(inode->typeDef->contModel, 26083 xmlSchemaVContentModelCallback, vctxt); 26084 if (inode->regexCtxt == NULL) { 26085 VERROR_INT("xmlSchemaValidatorPopElem", 26086 "failed to create a regex context"); 26087 goto internal_error; 26088 } 26089 #ifdef DEBUG_AUTOMATA 26090 xmlGenericError(xmlGenericErrorContext, 26091 "AUTOMATON create on '%s'\n", inode->localName); 26092 #endif 26093 } 26094 26095 /* 26096 * Do not check further content if the node has been nilled 26097 */ 26098 if (INODE_NILLED(inode)) { 26099 ret = 0; 26100 #ifdef DEBUG_AUTOMATA 26101 xmlGenericError(xmlGenericErrorContext, 26102 "AUTOMATON succeeded on nilled '%s'\n", 26103 inode->localName); 26104 #endif 26105 goto skip_nilled; 26106 } 26107 26108 /* 26109 * Get hold of the still expected content, since a further 26110 * call to xmlRegExecPushString() will lose this information. 26111 */ 26112 xmlRegExecNextValues(inode->regexCtxt, 26113 &nbval, &nbneg, &values[0], &terminal); 26114 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26115 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26116 /* 26117 * Still missing something. 26118 */ 26119 ret = 1; 26120 inode->flags |= 26121 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26122 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26123 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26124 "Missing child element(s)", 26125 nbval, nbneg, values); 26126 #ifdef DEBUG_AUTOMATA 26127 xmlGenericError(xmlGenericErrorContext, 26128 "AUTOMATON missing ERROR on '%s'\n", 26129 inode->localName); 26130 #endif 26131 } else { 26132 /* 26133 * Content model is satisfied. 26134 */ 26135 ret = 0; 26136 #ifdef DEBUG_AUTOMATA 26137 xmlGenericError(xmlGenericErrorContext, 26138 "AUTOMATON succeeded on '%s'\n", 26139 inode->localName); 26140 #endif 26141 } 26142 26143 } 26144 } 26145 26146 skip_nilled: 26147 26148 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26149 goto end_elem; 26150 26151 character_content: 26152 26153 if (vctxt->value != NULL) { 26154 xmlSchemaFreeValue(vctxt->value); 26155 vctxt->value = NULL; 26156 } 26157 /* 26158 * Check character content. 26159 */ 26160 if (inode->decl == NULL) { 26161 /* 26162 * Speedup if no declaration exists. 26163 */ 26164 if (WXS_IS_SIMPLE(inode->typeDef)) { 26165 ret = xmlSchemaVCheckINodeDataType(vctxt, 26166 inode, inode->typeDef, inode->value); 26167 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26168 ret = xmlSchemaVCheckINodeDataType(vctxt, 26169 inode, inode->typeDef->contentTypeDef, 26170 inode->value); 26171 } 26172 if (ret < 0) { 26173 VERROR_INT("xmlSchemaValidatorPopElem", 26174 "calling xmlSchemaVCheckCVCSimpleType()"); 26175 goto internal_error; 26176 } 26177 goto end_elem; 26178 } 26179 /* 26180 * cvc-elt (3.3.4) : 5 26181 * The appropriate case among the following must be true: 26182 */ 26183 /* 26184 * cvc-elt (3.3.4) : 5.1 26185 * If the declaration has a {value constraint}, 26186 * the item has neither element nor character [children] and 26187 * clause 3.2 has not applied, then all of the following must be true: 26188 */ 26189 if ((inode->decl->value != NULL) && 26190 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26191 (! INODE_NILLED(inode))) { 26192 /* 26193 * cvc-elt (3.3.4) : 5.1.1 26194 * If the `actual type definition` is a `local type definition` 26195 * then the canonical lexical representation of the {value constraint} 26196 * value must be a valid default for the `actual type definition` as 26197 * defined in Element Default Valid (Immediate) ($3.3.6). 26198 */ 26199 /* 26200 * NOTE: 'local' above means types acquired by xsi:type. 26201 * NOTE: Although the *canonical* value is stated, it is not 26202 * relevant if canonical or not. Additionally XML Schema 1.1 26203 * will removed this requirement as well. 26204 */ 26205 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26206 26207 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26208 inode->decl->value, &(inode->val)); 26209 if (ret != 0) { 26210 if (ret < 0) { 26211 VERROR_INT("xmlSchemaValidatorPopElem", 26212 "calling xmlSchemaCheckCOSValidDefault()"); 26213 goto internal_error; 26214 } 26215 goto end_elem; 26216 } 26217 /* 26218 * Stop here, to avoid redundant validation of the value 26219 * (see following). 26220 */ 26221 goto default_psvi; 26222 } 26223 /* 26224 * cvc-elt (3.3.4) : 5.1.2 26225 * The element information item with the canonical lexical 26226 * representation of the {value constraint} value used as its 26227 * `normalized value` must be `valid` with respect to the 26228 * `actual type definition` as defined by Element Locally Valid (Type) 26229 * ($3.3.4). 26230 */ 26231 if (WXS_IS_SIMPLE(inode->typeDef)) { 26232 ret = xmlSchemaVCheckINodeDataType(vctxt, 26233 inode, inode->typeDef, inode->decl->value); 26234 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26235 ret = xmlSchemaVCheckINodeDataType(vctxt, 26236 inode, inode->typeDef->contentTypeDef, 26237 inode->decl->value); 26238 } 26239 if (ret != 0) { 26240 if (ret < 0) { 26241 VERROR_INT("xmlSchemaValidatorPopElem", 26242 "calling xmlSchemaVCheckCVCSimpleType()"); 26243 goto internal_error; 26244 } 26245 goto end_elem; 26246 } 26247 26248 default_psvi: 26249 /* 26250 * PSVI: Create a text node on the instance element. 26251 */ 26252 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26253 (inode->node != NULL)) { 26254 xmlNodePtr textChild; 26255 xmlChar *normValue; 26256 /* 26257 * VAL TODO: Normalize the value. 26258 */ 26259 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26260 inode->decl->value); 26261 if (normValue != NULL) { 26262 textChild = xmlNewText(BAD_CAST normValue); 26263 xmlFree(normValue); 26264 } else 26265 textChild = xmlNewText(inode->decl->value); 26266 if (textChild == NULL) { 26267 VERROR_INT("xmlSchemaValidatorPopElem", 26268 "calling xmlNewText()"); 26269 goto internal_error; 26270 } else 26271 xmlAddChild(inode->node, textChild); 26272 } 26273 26274 } else if (! INODE_NILLED(inode)) { 26275 /* 26276 * 5.2.1 The element information item must be `valid` with respect 26277 * to the `actual type definition` as defined by Element Locally 26278 * Valid (Type) ($3.3.4). 26279 */ 26280 if (WXS_IS_SIMPLE(inode->typeDef)) { 26281 /* 26282 * SPEC (cvc-type) (3.1) 26283 * "If the type definition is a simple type definition, ..." 26284 * (3.1.3) "If clause 3.2 of Element Locally Valid 26285 * (Element) ($3.3.4) did not apply, then the `normalized value` 26286 * must be `valid` with respect to the type definition as defined 26287 * by String Valid ($3.14.4). 26288 */ 26289 ret = xmlSchemaVCheckINodeDataType(vctxt, 26290 inode, inode->typeDef, inode->value); 26291 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26292 /* 26293 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26294 * definition, then the element information item must be 26295 * `valid` with respect to the type definition as per 26296 * Element Locally Valid (Complex Type) ($3.4.4);" 26297 * 26298 * SPEC (cvc-complex-type) (2.2) 26299 * "If the {content type} is a simple type definition, ... 26300 * the `normalized value` of the element information item is 26301 * `valid` with respect to that simple type definition as 26302 * defined by String Valid ($3.14.4)." 26303 */ 26304 ret = xmlSchemaVCheckINodeDataType(vctxt, 26305 inode, inode->typeDef->contentTypeDef, inode->value); 26306 } 26307 if (ret != 0) { 26308 if (ret < 0) { 26309 VERROR_INT("xmlSchemaValidatorPopElem", 26310 "calling xmlSchemaVCheckCVCSimpleType()"); 26311 goto internal_error; 26312 } 26313 goto end_elem; 26314 } 26315 /* 26316 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26317 * not applied, all of the following must be true: 26318 */ 26319 if ((inode->decl->value != NULL) && 26320 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26321 26322 /* 26323 * TODO: We will need a computed value, when comparison is 26324 * done on computed values. 26325 */ 26326 /* 26327 * 5.2.2.1 The element information item must have no element 26328 * information item [children]. 26329 */ 26330 if (inode->flags & 26331 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26332 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26333 VERROR(ret, NULL, 26334 "The content must not contain element nodes since " 26335 "there is a fixed value constraint"); 26336 goto end_elem; 26337 } else { 26338 /* 26339 * 5.2.2.2 The appropriate case among the following must 26340 * be true: 26341 */ 26342 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26343 /* 26344 * 5.2.2.2.1 If the {content type} of the `actual type 26345 * definition` is mixed, then the *initial value* of the 26346 * item must match the canonical lexical representation 26347 * of the {value constraint} value. 26348 * 26349 * ... the *initial value* of an element information 26350 * item is the string composed of, in order, the 26351 * [character code] of each character information item in 26352 * the [children] of that element information item. 26353 */ 26354 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26355 /* 26356 * VAL TODO: Report invalid & expected values as well. 26357 * VAL TODO: Implement the canonical stuff. 26358 */ 26359 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26360 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26361 ret, NULL, NULL, 26362 "The initial value '%s' does not match the fixed " 26363 "value constraint '%s'", 26364 inode->value, inode->decl->value); 26365 goto end_elem; 26366 } 26367 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26368 /* 26369 * 5.2.2.2.2 If the {content type} of the `actual type 26370 * definition` is a simple type definition, then the 26371 * *actual value* of the item must match the canonical 26372 * lexical representation of the {value constraint} value. 26373 */ 26374 /* 26375 * VAL TODO: *actual value* is the normalized value, impl. 26376 * this. 26377 * VAL TODO: Report invalid & expected values as well. 26378 * VAL TODO: Implement a comparison with the computed values. 26379 */ 26380 if (! xmlStrEqual(inode->value, 26381 inode->decl->value)) { 26382 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26383 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26384 ret, NULL, NULL, 26385 "The actual value '%s' does not match the fixed " 26386 "value constraint '%s'", 26387 inode->value, 26388 inode->decl->value); 26389 goto end_elem; 26390 } 26391 } 26392 } 26393 } 26394 } 26395 26396 end_elem: 26397 if (vctxt->depth < 0) { 26398 /* TODO: raise error? */ 26399 return (0); 26400 } 26401 if (vctxt->depth == vctxt->skipDepth) 26402 vctxt->skipDepth = -1; 26403 /* 26404 * Evaluate the history of XPath state objects. 26405 */ 26406 if (inode->appliedXPath && 26407 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26408 goto internal_error; 26409 /* 26410 * MAYBE TODO: 26411 * SPEC (6) "The element information item must be `valid` with 26412 * respect to each of the {identity-constraint definitions} as per 26413 * Identity-constraint Satisfied ($3.11.4)." 26414 */ 26415 /* 26416 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26417 * need to be built in any case. 26418 * We will currently build IDC node-tables and bubble them only if 26419 * keyrefs do exist. 26420 */ 26421 26422 /* 26423 * Add the current IDC target-nodes to the IDC node-tables. 26424 */ 26425 if ((inode->idcMatchers != NULL) && 26426 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26427 { 26428 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26429 goto internal_error; 26430 } 26431 /* 26432 * Validate IDC keyrefs. 26433 */ 26434 if (vctxt->inode->hasKeyrefs) 26435 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26436 goto internal_error; 26437 /* 26438 * Merge/free the IDC table. 26439 */ 26440 if (inode->idcTable != NULL) { 26441 #ifdef DEBUG_IDC_NODE_TABLE 26442 xmlSchemaDebugDumpIDCTable(stdout, 26443 inode->nsName, 26444 inode->localName, 26445 inode->idcTable); 26446 #endif 26447 if ((vctxt->depth > 0) && 26448 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26449 { 26450 /* 26451 * Merge the IDC node table with the table of the parent node. 26452 */ 26453 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26454 goto internal_error; 26455 } 26456 } 26457 /* 26458 * Clear the current ielem. 26459 * VAL TODO: Don't free the PSVI IDC tables if they are 26460 * requested for the PSVI. 26461 */ 26462 xmlSchemaClearElemInfo(vctxt, inode); 26463 /* 26464 * Skip further processing if we are on the validation root. 26465 */ 26466 if (vctxt->depth == 0) { 26467 vctxt->depth--; 26468 vctxt->inode = NULL; 26469 return (0); 26470 } 26471 /* 26472 * Reset the keyrefDepth if needed. 26473 */ 26474 if (vctxt->aidcs != NULL) { 26475 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26476 do { 26477 if (aidc->keyrefDepth == vctxt->depth) { 26478 /* 26479 * A 'keyrefDepth' of a key/unique IDC matches the current 26480 * depth, this means that we are leaving the scope of the 26481 * top-most keyref IDC which refers to this IDC. 26482 */ 26483 aidc->keyrefDepth = -1; 26484 } 26485 aidc = aidc->next; 26486 } while (aidc != NULL); 26487 } 26488 vctxt->depth--; 26489 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26490 /* 26491 * VAL TODO: 7 If the element information item is the `validation root`, it must be 26492 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4). 26493 */ 26494 return (ret); 26495 26496 internal_error: 26497 vctxt->err = -1; 26498 return (-1); 26499 } 26500 26501 /* 26502 * 3.4.4 Complex Type Definition Validation Rules 26503 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26504 */ 26505 static int 26506 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26507 { 26508 xmlSchemaNodeInfoPtr pielem; 26509 xmlSchemaTypePtr ptype; 26510 int ret = 0; 26511 26512 if (vctxt->depth <= 0) { 26513 VERROR_INT("xmlSchemaValidateChildElem", 26514 "not intended for the validation root"); 26515 return (-1); 26516 } 26517 pielem = vctxt->elemInfos[vctxt->depth -1]; 26518 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26519 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26520 /* 26521 * Handle 'nilled' elements. 26522 */ 26523 if (INODE_NILLED(pielem)) { 26524 /* 26525 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26526 */ 26527 ACTIVATE_PARENT_ELEM; 26528 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26529 VERROR(ret, NULL, 26530 "Neither character nor element content is allowed, " 26531 "because the element was 'nilled'"); 26532 ACTIVATE_ELEM; 26533 goto unexpected_elem; 26534 } 26535 26536 ptype = pielem->typeDef; 26537 26538 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26539 /* 26540 * Workaround for "anyType": we have currently no content model 26541 * assigned for "anyType", so handle it explicitly. 26542 * "anyType" has an unbounded, lax "any" wildcard. 26543 */ 26544 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26545 vctxt->inode->localName, 26546 vctxt->inode->nsName); 26547 26548 if (vctxt->inode->decl == NULL) { 26549 xmlSchemaAttrInfoPtr iattr; 26550 /* 26551 * Process "xsi:type". 26552 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26553 */ 26554 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26555 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26556 if (iattr != NULL) { 26557 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26558 &(vctxt->inode->typeDef), NULL); 26559 if (ret != 0) { 26560 if (ret == -1) { 26561 VERROR_INT("xmlSchemaValidateChildElem", 26562 "calling xmlSchemaProcessXSIType() to " 26563 "process the attribute 'xsi:nil'"); 26564 return (-1); 26565 } 26566 return (ret); 26567 } 26568 } else { 26569 /* 26570 * Fallback to "anyType". 26571 * 26572 * SPEC (cvc-assess-elt) 26573 * "If the item cannot be `strictly assessed`, [...] 26574 * an element information item's schema validity may be laxly 26575 * assessed if its `context-determined declaration` is not 26576 * skip by `validating` with respect to the `ur-type 26577 * definition` as per Element Locally Valid (Type) ($3.3.4)." 26578 */ 26579 vctxt->inode->typeDef = 26580 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26581 } 26582 } 26583 return (0); 26584 } 26585 26586 switch (ptype->contentType) { 26587 case XML_SCHEMA_CONTENT_EMPTY: 26588 /* 26589 * SPEC (2.1) "If the {content type} is empty, then the 26590 * element information item has no character or element 26591 * information item [children]." 26592 */ 26593 ACTIVATE_PARENT_ELEM 26594 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26595 VERROR(ret, NULL, 26596 "Element content is not allowed, " 26597 "because the content type is empty"); 26598 ACTIVATE_ELEM 26599 goto unexpected_elem; 26600 break; 26601 26602 case XML_SCHEMA_CONTENT_MIXED: 26603 case XML_SCHEMA_CONTENT_ELEMENTS: { 26604 xmlRegExecCtxtPtr regexCtxt; 26605 xmlChar *values[10]; 26606 int terminal, nbval = 10, nbneg; 26607 26608 /* VAL TODO: Optimized "anyType" validation.*/ 26609 26610 if (ptype->contModel == NULL) { 26611 VERROR_INT("xmlSchemaValidateChildElem", 26612 "type has elem content but no content model"); 26613 return (-1); 26614 } 26615 /* 26616 * Safety belt for evaluation if the cont. model was already 26617 * examined to be invalid. 26618 */ 26619 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26620 VERROR_INT("xmlSchemaValidateChildElem", 26621 "validating elem, but elem content is already invalid"); 26622 return (-1); 26623 } 26624 26625 regexCtxt = pielem->regexCtxt; 26626 if (regexCtxt == NULL) { 26627 /* 26628 * Create the regex context. 26629 */ 26630 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26631 xmlSchemaVContentModelCallback, vctxt); 26632 if (regexCtxt == NULL) { 26633 VERROR_INT("xmlSchemaValidateChildElem", 26634 "failed to create a regex context"); 26635 return (-1); 26636 } 26637 pielem->regexCtxt = regexCtxt; 26638 #ifdef DEBUG_AUTOMATA 26639 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26640 pielem->localName); 26641 #endif 26642 } 26643 26644 /* 26645 * SPEC (2.4) "If the {content type} is element-only or mixed, 26646 * then the sequence of the element information item's 26647 * element information item [children], if any, taken in 26648 * order, is `valid` with respect to the {content type}'s 26649 * particle, as defined in Element Sequence Locally Valid 26650 * (Particle) ($3.9.4)." 26651 */ 26652 ret = xmlRegExecPushString2(regexCtxt, 26653 vctxt->inode->localName, 26654 vctxt->inode->nsName, 26655 vctxt->inode); 26656 #ifdef DEBUG_AUTOMATA 26657 if (ret < 0) 26658 xmlGenericError(xmlGenericErrorContext, 26659 "AUTOMATON push ERROR for '%s' on '%s'\n", 26660 vctxt->inode->localName, pielem->localName); 26661 else 26662 xmlGenericError(xmlGenericErrorContext, 26663 "AUTOMATON push OK for '%s' on '%s'\n", 26664 vctxt->inode->localName, pielem->localName); 26665 #endif 26666 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26667 VERROR_INT("xmlSchemaValidateChildElem", 26668 "calling xmlRegExecPushString2()"); 26669 return (-1); 26670 } 26671 if (ret < 0) { 26672 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26673 &values[0], &terminal); 26674 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26675 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26676 "This element is not expected", 26677 nbval, nbneg, values); 26678 ret = vctxt->err; 26679 goto unexpected_elem; 26680 } else 26681 ret = 0; 26682 } 26683 break; 26684 case XML_SCHEMA_CONTENT_SIMPLE: 26685 case XML_SCHEMA_CONTENT_BASIC: 26686 ACTIVATE_PARENT_ELEM 26687 if (WXS_IS_COMPLEX(ptype)) { 26688 /* 26689 * SPEC (cvc-complex-type) (2.2) 26690 * "If the {content type} is a simple type definition, then 26691 * the element information item has no element information 26692 * item [children], ..." 26693 */ 26694 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26695 VERROR(ret, NULL, "Element content is not allowed, " 26696 "because the content type is a simple type definition"); 26697 } else { 26698 /* 26699 * SPEC (cvc-type) (3.1.2) "The element information item must 26700 * have no element information item [children]." 26701 */ 26702 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26703 VERROR(ret, NULL, "Element content is not allowed, " 26704 "because the type definition is simple"); 26705 } 26706 ACTIVATE_ELEM 26707 ret = vctxt->err; 26708 goto unexpected_elem; 26709 break; 26710 26711 default: 26712 break; 26713 } 26714 return (ret); 26715 unexpected_elem: 26716 /* 26717 * Pop this element and set the skipDepth to skip 26718 * all further content of the parent element. 26719 */ 26720 vctxt->skipDepth = vctxt->depth; 26721 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26722 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26723 return (ret); 26724 } 26725 26726 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26727 #define XML_SCHEMA_PUSH_TEXT_CREATED 2 26728 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26729 26730 static int 26731 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26732 int nodeType, const xmlChar *value, int len, 26733 int mode, int *consumed) 26734 { 26735 /* 26736 * Unfortunately we have to duplicate the text sometimes. 26737 * OPTIMIZE: Maybe we could skip it, if: 26738 * 1. content type is simple 26739 * 2. whitespace is "collapse" 26740 * 3. it consists of whitespace only 26741 * 26742 * Process character content. 26743 */ 26744 if (consumed != NULL) 26745 *consumed = 0; 26746 if (INODE_NILLED(vctxt->inode)) { 26747 /* 26748 * SPEC cvc-elt (3.3.4 - 3.2.1) 26749 * "The element information item must have no character or 26750 * element information item [children]." 26751 */ 26752 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26753 "Neither character nor element content is allowed " 26754 "because the element is 'nilled'"); 26755 return (vctxt->err); 26756 } 26757 /* 26758 * SPEC (2.1) "If the {content type} is empty, then the 26759 * element information item has no character or element 26760 * information item [children]." 26761 */ 26762 if (vctxt->inode->typeDef->contentType == 26763 XML_SCHEMA_CONTENT_EMPTY) { 26764 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26765 "Character content is not allowed, " 26766 "because the content type is empty"); 26767 return (vctxt->err); 26768 } 26769 26770 if (vctxt->inode->typeDef->contentType == 26771 XML_SCHEMA_CONTENT_ELEMENTS) { 26772 if ((nodeType != XML_TEXT_NODE) || 26773 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26774 /* 26775 * SPEC cvc-complex-type (2.3) 26776 * "If the {content type} is element-only, then the 26777 * element information item has no character information 26778 * item [children] other than those whose [character 26779 * code] is defined as a white space in [XML 1.0 (Second 26780 * Edition)]." 26781 */ 26782 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26783 "Character content other than whitespace is not allowed " 26784 "because the content type is 'element-only'"); 26785 return (vctxt->err); 26786 } 26787 return (0); 26788 } 26789 26790 if ((value == NULL) || (value[0] == 0)) 26791 return (0); 26792 /* 26793 * Save the value. 26794 * NOTE that even if the content type is *mixed*, we need the 26795 * *initial value* for default/fixed value constraints. 26796 */ 26797 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26798 ((vctxt->inode->decl == NULL) || 26799 (vctxt->inode->decl->value == NULL))) 26800 return (0); 26801 26802 if (vctxt->inode->value == NULL) { 26803 /* 26804 * Set the value. 26805 */ 26806 switch (mode) { 26807 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26808 /* 26809 * When working on a tree. 26810 */ 26811 vctxt->inode->value = value; 26812 break; 26813 case XML_SCHEMA_PUSH_TEXT_CREATED: 26814 /* 26815 * When working with the reader. 26816 * The value will be freed by the element info. 26817 */ 26818 vctxt->inode->value = value; 26819 if (consumed != NULL) 26820 *consumed = 1; 26821 vctxt->inode->flags |= 26822 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26823 break; 26824 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26825 /* 26826 * When working with SAX. 26827 * The value will be freed by the element info. 26828 */ 26829 if (len != -1) 26830 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26831 else 26832 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26833 vctxt->inode->flags |= 26834 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26835 break; 26836 default: 26837 break; 26838 } 26839 } else { 26840 if (len < 0) 26841 len = xmlStrlen(value); 26842 /* 26843 * Concat the value. 26844 */ 26845 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26846 vctxt->inode->value = BAD_CAST xmlStrncat( 26847 (xmlChar *) vctxt->inode->value, value, len); 26848 } else { 26849 vctxt->inode->value = 26850 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26851 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26852 } 26853 } 26854 26855 return (0); 26856 } 26857 26858 static int 26859 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26860 { 26861 int ret = 0; 26862 26863 if ((vctxt->skipDepth != -1) && 26864 (vctxt->depth >= vctxt->skipDepth)) { 26865 VERROR_INT("xmlSchemaValidateElem", 26866 "in skip-state"); 26867 goto internal_error; 26868 } 26869 if (vctxt->xsiAssemble) { 26870 /* 26871 * We will stop validation if there was an error during 26872 * dynamic schema construction. 26873 * Note that we simply set @skipDepth to 0, this could 26874 * mean that a streaming document via SAX would be 26875 * still read to the end but it won't be validated any more. 26876 * TODO: If we are sure how to stop the validation at once 26877 * for all input scenarios, then this should be changed to 26878 * instantly stop the validation. 26879 */ 26880 ret = xmlSchemaAssembleByXSI(vctxt); 26881 if (ret != 0) { 26882 if (ret == -1) 26883 goto internal_error; 26884 vctxt->skipDepth = 0; 26885 return(ret); 26886 } 26887 /* 26888 * Augment the IDC definitions for the main schema and all imported ones 26889 * NOTE: main schema is the first in the imported list 26890 */ 26891 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, 26892 vctxt); 26893 } 26894 if (vctxt->depth > 0) { 26895 /* 26896 * Validate this element against the content model 26897 * of the parent. 26898 */ 26899 ret = xmlSchemaValidateChildElem(vctxt); 26900 if (ret != 0) { 26901 if (ret < 0) { 26902 VERROR_INT("xmlSchemaValidateElem", 26903 "calling xmlSchemaStreamValidateChildElement()"); 26904 goto internal_error; 26905 } 26906 goto exit; 26907 } 26908 if (vctxt->depth == vctxt->skipDepth) 26909 goto exit; 26910 if ((vctxt->inode->decl == NULL) && 26911 (vctxt->inode->typeDef == NULL)) { 26912 VERROR_INT("xmlSchemaValidateElem", 26913 "the child element was valid but neither the " 26914 "declaration nor the type was set"); 26915 goto internal_error; 26916 } 26917 } else { 26918 /* 26919 * Get the declaration of the validation root. 26920 */ 26921 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26922 vctxt->inode->localName, 26923 vctxt->inode->nsName); 26924 if (vctxt->inode->decl == NULL) { 26925 ret = XML_SCHEMAV_CVC_ELT_1; 26926 VERROR(ret, NULL, 26927 "No matching global declaration available " 26928 "for the validation root"); 26929 goto exit; 26930 } 26931 } 26932 26933 if (vctxt->inode->decl == NULL) 26934 goto type_validation; 26935 26936 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26937 int skip; 26938 /* 26939 * Wildcards. 26940 */ 26941 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26942 if (ret != 0) { 26943 if (ret < 0) { 26944 VERROR_INT("xmlSchemaValidateElem", 26945 "calling xmlSchemaValidateElemWildcard()"); 26946 goto internal_error; 26947 } 26948 goto exit; 26949 } 26950 if (skip) { 26951 vctxt->skipDepth = vctxt->depth; 26952 goto exit; 26953 } 26954 /* 26955 * The declaration might be set by the wildcard validation, 26956 * when the processContents is "lax" or "strict". 26957 */ 26958 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26959 /* 26960 * Clear the "decl" field to not confuse further processing. 26961 */ 26962 vctxt->inode->decl = NULL; 26963 goto type_validation; 26964 } 26965 } 26966 /* 26967 * Validate against the declaration. 26968 */ 26969 ret = xmlSchemaValidateElemDecl(vctxt); 26970 if (ret != 0) { 26971 if (ret < 0) { 26972 VERROR_INT("xmlSchemaValidateElem", 26973 "calling xmlSchemaValidateElemDecl()"); 26974 goto internal_error; 26975 } 26976 goto exit; 26977 } 26978 /* 26979 * Validate against the type definition. 26980 */ 26981 type_validation: 26982 26983 if (vctxt->inode->typeDef == NULL) { 26984 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26985 ret = XML_SCHEMAV_CVC_TYPE_1; 26986 VERROR(ret, NULL, 26987 "The type definition is absent"); 26988 goto exit; 26989 } 26990 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26991 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26992 ret = XML_SCHEMAV_CVC_TYPE_2; 26993 VERROR(ret, NULL, 26994 "The type definition is abstract"); 26995 goto exit; 26996 } 26997 /* 26998 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26999 * during validation against the declaration. This must be done 27000 * _before_ attribute validation. 27001 */ 27002 if (vctxt->xpathStates != NULL) { 27003 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 27004 vctxt->inode->appliedXPath = 1; 27005 if (ret == -1) { 27006 VERROR_INT("xmlSchemaValidateElem", 27007 "calling xmlSchemaXPathEvaluate()"); 27008 goto internal_error; 27009 } 27010 } 27011 /* 27012 * Validate attributes. 27013 */ 27014 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 27015 if ((vctxt->nbAttrInfos != 0) || 27016 (vctxt->inode->typeDef->attrUses != NULL)) { 27017 27018 ret = xmlSchemaVAttributesComplex(vctxt); 27019 } 27020 } else if (vctxt->nbAttrInfos != 0) { 27021 27022 ret = xmlSchemaVAttributesSimple(vctxt); 27023 } 27024 /* 27025 * Clear registered attributes. 27026 */ 27027 if (vctxt->nbAttrInfos != 0) 27028 xmlSchemaClearAttrInfos(vctxt); 27029 if (ret == -1) { 27030 VERROR_INT("xmlSchemaValidateElem", 27031 "calling attributes validation"); 27032 goto internal_error; 27033 } 27034 /* 27035 * Don't return an error if attributes are invalid on purpose. 27036 */ 27037 ret = 0; 27038 27039 exit: 27040 if (ret != 0) 27041 vctxt->skipDepth = vctxt->depth; 27042 return (ret); 27043 internal_error: 27044 return (-1); 27045 } 27046 27047 #ifdef XML_SCHEMA_READER_ENABLED 27048 static int 27049 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 27050 { 27051 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 27052 int depth, nodeType, ret = 0, consumed; 27053 xmlSchemaNodeInfoPtr ielem; 27054 27055 vctxt->depth = -1; 27056 ret = xmlTextReaderRead(vctxt->reader); 27057 /* 27058 * Move to the document element. 27059 */ 27060 while (ret == 1) { 27061 nodeType = xmlTextReaderNodeType(vctxt->reader); 27062 if (nodeType == XML_ELEMENT_NODE) 27063 goto root_found; 27064 ret = xmlTextReaderRead(vctxt->reader); 27065 } 27066 goto exit; 27067 27068 root_found: 27069 27070 do { 27071 depth = xmlTextReaderDepth(vctxt->reader); 27072 nodeType = xmlTextReaderNodeType(vctxt->reader); 27073 27074 if (nodeType == XML_ELEMENT_NODE) { 27075 27076 vctxt->depth++; 27077 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27078 VERROR_INT("xmlSchemaVReaderWalk", 27079 "calling xmlSchemaValidatorPushElem()"); 27080 goto internal_error; 27081 } 27082 ielem = vctxt->inode; 27083 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27084 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27085 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27086 /* 27087 * Is the element empty? 27088 */ 27089 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27090 if (ret == -1) { 27091 VERROR_INT("xmlSchemaVReaderWalk", 27092 "calling xmlTextReaderIsEmptyElement()"); 27093 goto internal_error; 27094 } 27095 if (ret) { 27096 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27097 } 27098 /* 27099 * Register attributes. 27100 */ 27101 vctxt->nbAttrInfos = 0; 27102 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27103 if (ret == -1) { 27104 VERROR_INT("xmlSchemaVReaderWalk", 27105 "calling xmlTextReaderMoveToFirstAttribute()"); 27106 goto internal_error; 27107 } 27108 if (ret == 1) { 27109 do { 27110 /* 27111 * VAL TODO: How do we know that the reader works on a 27112 * node tree, to be able to pass a node here? 27113 */ 27114 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27115 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27116 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27117 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27118 27119 VERROR_INT("xmlSchemaVReaderWalk", 27120 "calling xmlSchemaValidatorPushAttribute()"); 27121 goto internal_error; 27122 } 27123 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27124 if (ret == -1) { 27125 VERROR_INT("xmlSchemaVReaderWalk", 27126 "calling xmlTextReaderMoveToFirstAttribute()"); 27127 goto internal_error; 27128 } 27129 } while (ret == 1); 27130 /* 27131 * Back to element position. 27132 */ 27133 ret = xmlTextReaderMoveToElement(vctxt->reader); 27134 if (ret == -1) { 27135 VERROR_INT("xmlSchemaVReaderWalk", 27136 "calling xmlTextReaderMoveToElement()"); 27137 goto internal_error; 27138 } 27139 } 27140 /* 27141 * Validate the element. 27142 */ 27143 ret= xmlSchemaValidateElem(vctxt); 27144 if (ret != 0) { 27145 if (ret == -1) { 27146 VERROR_INT("xmlSchemaVReaderWalk", 27147 "calling xmlSchemaValidateElem()"); 27148 goto internal_error; 27149 } 27150 goto exit; 27151 } 27152 if (vctxt->depth == vctxt->skipDepth) { 27153 int curDepth; 27154 /* 27155 * Skip all content. 27156 */ 27157 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27158 ret = xmlTextReaderRead(vctxt->reader); 27159 curDepth = xmlTextReaderDepth(vctxt->reader); 27160 while ((ret == 1) && (curDepth != depth)) { 27161 ret = xmlTextReaderRead(vctxt->reader); 27162 curDepth = xmlTextReaderDepth(vctxt->reader); 27163 } 27164 if (ret < 0) { 27165 /* 27166 * VAL TODO: A reader error occurred; what to do here? 27167 */ 27168 ret = 1; 27169 goto exit; 27170 } 27171 } 27172 goto leave_elem; 27173 } 27174 /* 27175 * READER VAL TODO: Is an END_ELEM really never called 27176 * if the elem is empty? 27177 */ 27178 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27179 goto leave_elem; 27180 } else if (nodeType == END_ELEM) { 27181 /* 27182 * Process END of element. 27183 */ 27184 leave_elem: 27185 ret = xmlSchemaValidatorPopElem(vctxt); 27186 if (ret != 0) { 27187 if (ret < 0) { 27188 VERROR_INT("xmlSchemaVReaderWalk", 27189 "calling xmlSchemaValidatorPopElem()"); 27190 goto internal_error; 27191 } 27192 goto exit; 27193 } 27194 if (vctxt->depth >= 0) 27195 ielem = vctxt->inode; 27196 else 27197 ielem = NULL; 27198 } else if ((nodeType == XML_TEXT_NODE) || 27199 (nodeType == XML_CDATA_SECTION_NODE) || 27200 (nodeType == WHTSP) || 27201 (nodeType == SIGN_WHTSP)) { 27202 /* 27203 * Process character content. 27204 */ 27205 xmlChar *value; 27206 27207 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27208 nodeType = XML_TEXT_NODE; 27209 27210 value = xmlTextReaderValue(vctxt->reader); 27211 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27212 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27213 if (! consumed) 27214 xmlFree(value); 27215 if (ret == -1) { 27216 VERROR_INT("xmlSchemaVReaderWalk", 27217 "calling xmlSchemaVPushText()"); 27218 goto internal_error; 27219 } 27220 } else if ((nodeType == XML_ENTITY_NODE) || 27221 (nodeType == XML_ENTITY_REF_NODE)) { 27222 /* 27223 * VAL TODO: What to do with entities? 27224 */ 27225 TODO 27226 } 27227 /* 27228 * Read next node. 27229 */ 27230 ret = xmlTextReaderRead(vctxt->reader); 27231 } while (ret == 1); 27232 27233 exit: 27234 return (ret); 27235 internal_error: 27236 return (-1); 27237 } 27238 #endif 27239 27240 /************************************************************************ 27241 * * 27242 * SAX validation handlers * 27243 * * 27244 ************************************************************************/ 27245 27246 /* 27247 * Process text content. 27248 */ 27249 static void 27250 xmlSchemaSAXHandleText(void *ctx, 27251 const xmlChar * ch, 27252 int len) 27253 { 27254 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27255 27256 if (vctxt->depth < 0) 27257 return; 27258 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27259 return; 27260 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27261 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27262 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27263 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27264 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27265 "calling xmlSchemaVPushText()"); 27266 vctxt->err = -1; 27267 xmlStopParser(vctxt->parserCtxt); 27268 } 27269 } 27270 27271 /* 27272 * Process CDATA content. 27273 */ 27274 static void 27275 xmlSchemaSAXHandleCDataSection(void *ctx, 27276 const xmlChar * ch, 27277 int len) 27278 { 27279 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27280 27281 if (vctxt->depth < 0) 27282 return; 27283 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27284 return; 27285 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27286 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27287 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27288 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27289 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27290 "calling xmlSchemaVPushText()"); 27291 vctxt->err = -1; 27292 xmlStopParser(vctxt->parserCtxt); 27293 } 27294 } 27295 27296 static void 27297 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27298 const xmlChar * name ATTRIBUTE_UNUSED) 27299 { 27300 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27301 27302 if (vctxt->depth < 0) 27303 return; 27304 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27305 return; 27306 /* SAX VAL TODO: What to do here? */ 27307 TODO 27308 } 27309 27310 static void 27311 xmlSchemaSAXHandleStartElementNs(void *ctx, 27312 const xmlChar * localname, 27313 const xmlChar * prefix ATTRIBUTE_UNUSED, 27314 const xmlChar * URI, 27315 int nb_namespaces, 27316 const xmlChar ** namespaces, 27317 int nb_attributes, 27318 int nb_defaulted ATTRIBUTE_UNUSED, 27319 const xmlChar ** attributes) 27320 { 27321 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27322 int ret; 27323 xmlSchemaNodeInfoPtr ielem; 27324 int i, j; 27325 27326 /* 27327 * SAX VAL TODO: What to do with nb_defaulted? 27328 */ 27329 /* 27330 * Skip elements if inside a "skip" wildcard or invalid. 27331 */ 27332 vctxt->depth++; 27333 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27334 return; 27335 /* 27336 * Push the element. 27337 */ 27338 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27339 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27340 "calling xmlSchemaValidatorPushElem()"); 27341 goto internal_error; 27342 } 27343 ielem = vctxt->inode; 27344 /* 27345 * TODO: Is this OK? 27346 */ 27347 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27348 ielem->localName = localname; 27349 ielem->nsName = URI; 27350 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27351 /* 27352 * Register namespaces on the elem info. 27353 */ 27354 if (nb_namespaces != 0) { 27355 /* 27356 * Although the parser builds its own namespace list, 27357 * we have no access to it, so we'll use an own one. 27358 */ 27359 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27360 /* 27361 * Store prefix and namespace name. 27362 */ 27363 if (ielem->nsBindings == NULL) { 27364 ielem->nsBindings = 27365 (const xmlChar **) xmlMalloc(10 * 27366 sizeof(const xmlChar *)); 27367 if (ielem->nsBindings == NULL) { 27368 xmlSchemaVErrMemory(vctxt, 27369 "allocating namespace bindings for SAX validation", 27370 NULL); 27371 goto internal_error; 27372 } 27373 ielem->nbNsBindings = 0; 27374 ielem->sizeNsBindings = 5; 27375 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27376 ielem->sizeNsBindings *= 2; 27377 ielem->nsBindings = 27378 (const xmlChar **) xmlRealloc( 27379 (void *) ielem->nsBindings, 27380 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27381 if (ielem->nsBindings == NULL) { 27382 xmlSchemaVErrMemory(vctxt, 27383 "re-allocating namespace bindings for SAX validation", 27384 NULL); 27385 goto internal_error; 27386 } 27387 } 27388 27389 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27390 if (namespaces[j+1][0] == 0) { 27391 /* 27392 * Handle xmlns="". 27393 */ 27394 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27395 } else 27396 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27397 namespaces[j+1]; 27398 ielem->nbNsBindings++; 27399 } 27400 } 27401 /* 27402 * Register attributes. 27403 * SAX VAL TODO: We are not adding namespace declaration 27404 * attributes yet. 27405 */ 27406 if (nb_attributes != 0) { 27407 int valueLen, k, l; 27408 xmlChar *value; 27409 27410 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27411 /* 27412 * Duplicate the value, changing any & to a literal ampersand. 27413 * 27414 * libxml2 differs from normal SAX here in that it escapes all ampersands 27415 * as & instead of delivering the raw converted string. Changing the 27416 * behavior at this point would break applications that use this API, so 27417 * we are forced to work around it. 27418 */ 27419 valueLen = attributes[j+4] - attributes[j+3]; 27420 value = xmlMallocAtomic(valueLen + 1); 27421 if (value == NULL) { 27422 xmlSchemaVErrMemory(vctxt, 27423 "allocating string for decoded attribute", 27424 NULL); 27425 goto internal_error; 27426 } 27427 for (k = 0, l = 0; k < valueLen; l++) { 27428 if (k < valueLen - 4 && 27429 attributes[j+3][k+0] == '&' && 27430 attributes[j+3][k+1] == '#' && 27431 attributes[j+3][k+2] == '3' && 27432 attributes[j+3][k+3] == '8' && 27433 attributes[j+3][k+4] == ';') { 27434 value[l] = '&'; 27435 k += 5; 27436 } else { 27437 value[l] = attributes[j+3][k]; 27438 k++; 27439 } 27440 } 27441 value[l] = '\0'; 27442 /* 27443 * TODO: Set the node line. 27444 */ 27445 ret = xmlSchemaValidatorPushAttribute(vctxt, 27446 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27447 value, 1); 27448 if (ret == -1) { 27449 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27450 "calling xmlSchemaValidatorPushAttribute()"); 27451 goto internal_error; 27452 } 27453 } 27454 } 27455 /* 27456 * Validate the element. 27457 */ 27458 ret = xmlSchemaValidateElem(vctxt); 27459 if (ret != 0) { 27460 if (ret == -1) { 27461 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27462 "calling xmlSchemaValidateElem()"); 27463 goto internal_error; 27464 } 27465 goto exit; 27466 } 27467 27468 exit: 27469 return; 27470 internal_error: 27471 vctxt->err = -1; 27472 xmlStopParser(vctxt->parserCtxt); 27473 return; 27474 } 27475 27476 static void 27477 xmlSchemaSAXHandleEndElementNs(void *ctx, 27478 const xmlChar * localname ATTRIBUTE_UNUSED, 27479 const xmlChar * prefix ATTRIBUTE_UNUSED, 27480 const xmlChar * URI ATTRIBUTE_UNUSED) 27481 { 27482 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27483 int res; 27484 27485 /* 27486 * Skip elements if inside a "skip" wildcard or if invalid. 27487 */ 27488 if (vctxt->skipDepth != -1) { 27489 if (vctxt->depth > vctxt->skipDepth) { 27490 vctxt->depth--; 27491 return; 27492 } else 27493 vctxt->skipDepth = -1; 27494 } 27495 /* 27496 * SAX VAL TODO: Just a temporary check. 27497 */ 27498 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27499 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27500 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27501 "elem pop mismatch"); 27502 } 27503 res = xmlSchemaValidatorPopElem(vctxt); 27504 if (res != 0) { 27505 if (res < 0) { 27506 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27507 "calling xmlSchemaValidatorPopElem()"); 27508 goto internal_error; 27509 } 27510 goto exit; 27511 } 27512 exit: 27513 return; 27514 internal_error: 27515 vctxt->err = -1; 27516 xmlStopParser(vctxt->parserCtxt); 27517 return; 27518 } 27519 27520 /************************************************************************ 27521 * * 27522 * Validation interfaces * 27523 * * 27524 ************************************************************************/ 27525 27526 /** 27527 * xmlSchemaNewValidCtxt: 27528 * @schema: a precompiled XML Schemas 27529 * 27530 * Create an XML Schemas validation context based on the given schema. 27531 * 27532 * Returns the validation context or NULL in case of error 27533 */ 27534 xmlSchemaValidCtxtPtr 27535 xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27536 { 27537 xmlSchemaValidCtxtPtr ret; 27538 27539 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27540 if (ret == NULL) { 27541 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27542 return (NULL); 27543 } 27544 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27545 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27546 ret->dict = xmlDictCreate(); 27547 ret->nodeQNames = xmlSchemaItemListCreate(); 27548 ret->schema = schema; 27549 return (ret); 27550 } 27551 27552 /** 27553 * xmlSchemaValidateSetFilename: 27554 * @vctxt: the schema validation context 27555 * @filename: the file name 27556 * 27557 * Workaround to provide file error reporting information when this is 27558 * not provided by current APIs 27559 */ 27560 void 27561 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) { 27562 if (vctxt == NULL) 27563 return; 27564 if (vctxt->filename != NULL) 27565 xmlFree(vctxt->filename); 27566 if (filename != NULL) 27567 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename); 27568 else 27569 vctxt->filename = NULL; 27570 } 27571 27572 /** 27573 * xmlSchemaClearValidCtxt: 27574 * @vctxt: the schema validation context 27575 * 27576 * Free the resources associated to the schema validation context; 27577 * leaves some fields alive intended for reuse of the context. 27578 */ 27579 static void 27580 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27581 { 27582 if (vctxt == NULL) 27583 return; 27584 27585 /* 27586 * TODO: Should we clear the flags? 27587 * Might be problematic if one reuses the context 27588 * and assumes that the options remain the same. 27589 */ 27590 vctxt->flags = 0; 27591 vctxt->validationRoot = NULL; 27592 vctxt->doc = NULL; 27593 #ifdef LIBXML_READER_ENABLED 27594 vctxt->reader = NULL; 27595 #endif 27596 vctxt->hasKeyrefs = 0; 27597 27598 if (vctxt->value != NULL) { 27599 xmlSchemaFreeValue(vctxt->value); 27600 vctxt->value = NULL; 27601 } 27602 /* 27603 * Augmented IDC information. 27604 */ 27605 if (vctxt->aidcs != NULL) { 27606 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27607 do { 27608 next = cur->next; 27609 xmlFree(cur); 27610 cur = next; 27611 } while (cur != NULL); 27612 vctxt->aidcs = NULL; 27613 } 27614 if (vctxt->idcMatcherCache != NULL) { 27615 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27616 27617 while (matcher) { 27618 tmp = matcher; 27619 matcher = matcher->nextCached; 27620 xmlSchemaIDCFreeMatcherList(tmp); 27621 } 27622 vctxt->idcMatcherCache = NULL; 27623 } 27624 27625 27626 if (vctxt->idcNodes != NULL) { 27627 int i; 27628 xmlSchemaPSVIIDCNodePtr item; 27629 27630 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27631 item = vctxt->idcNodes[i]; 27632 xmlFree(item->keys); 27633 xmlFree(item); 27634 } 27635 xmlFree(vctxt->idcNodes); 27636 vctxt->idcNodes = NULL; 27637 vctxt->nbIdcNodes = 0; 27638 vctxt->sizeIdcNodes = 0; 27639 } 27640 27641 if (vctxt->idcKeys != NULL) { 27642 int i; 27643 for (i = 0; i < vctxt->nbIdcKeys; i++) 27644 xmlSchemaIDCFreeKey(vctxt->idcKeys[i]); 27645 xmlFree(vctxt->idcKeys); 27646 vctxt->idcKeys = NULL; 27647 vctxt->nbIdcKeys = 0; 27648 vctxt->sizeIdcKeys = 0; 27649 } 27650 27651 /* 27652 * Note that we won't delete the XPath state pool here. 27653 */ 27654 if (vctxt->xpathStates != NULL) { 27655 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27656 vctxt->xpathStates = NULL; 27657 } 27658 /* 27659 * Attribute info. 27660 */ 27661 if (vctxt->nbAttrInfos != 0) { 27662 xmlSchemaClearAttrInfos(vctxt); 27663 } 27664 /* 27665 * Element info. 27666 */ 27667 if (vctxt->elemInfos != NULL) { 27668 int i; 27669 xmlSchemaNodeInfoPtr ei; 27670 27671 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27672 ei = vctxt->elemInfos[i]; 27673 if (ei == NULL) 27674 break; 27675 xmlSchemaClearElemInfo(vctxt, ei); 27676 } 27677 } 27678 xmlSchemaItemListClear(vctxt->nodeQNames); 27679 /* Recreate the dict. */ 27680 xmlDictFree(vctxt->dict); 27681 /* 27682 * TODO: Is is save to recreate it? Do we have a scenario 27683 * where the user provides the dict? 27684 */ 27685 vctxt->dict = xmlDictCreate(); 27686 27687 if (vctxt->filename != NULL) { 27688 xmlFree(vctxt->filename); 27689 vctxt->filename = NULL; 27690 } 27691 } 27692 27693 /** 27694 * xmlSchemaFreeValidCtxt: 27695 * @ctxt: the schema validation context 27696 * 27697 * Free the resources associated to the schema validation context 27698 */ 27699 void 27700 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27701 { 27702 if (ctxt == NULL) 27703 return; 27704 if (ctxt->value != NULL) 27705 xmlSchemaFreeValue(ctxt->value); 27706 if (ctxt->pctxt != NULL) 27707 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27708 if (ctxt->idcNodes != NULL) { 27709 int i; 27710 xmlSchemaPSVIIDCNodePtr item; 27711 27712 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27713 item = ctxt->idcNodes[i]; 27714 xmlFree(item->keys); 27715 xmlFree(item); 27716 } 27717 xmlFree(ctxt->idcNodes); 27718 } 27719 if (ctxt->idcKeys != NULL) { 27720 int i; 27721 for (i = 0; i < ctxt->nbIdcKeys; i++) 27722 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27723 xmlFree(ctxt->idcKeys); 27724 } 27725 27726 if (ctxt->xpathStates != NULL) { 27727 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27728 ctxt->xpathStates = NULL; 27729 } 27730 if (ctxt->xpathStatePool != NULL) { 27731 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27732 ctxt->xpathStatePool = NULL; 27733 } 27734 27735 /* 27736 * Augmented IDC information. 27737 */ 27738 if (ctxt->aidcs != NULL) { 27739 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27740 do { 27741 next = cur->next; 27742 xmlFree(cur); 27743 cur = next; 27744 } while (cur != NULL); 27745 } 27746 if (ctxt->attrInfos != NULL) { 27747 int i; 27748 xmlSchemaAttrInfoPtr attr; 27749 27750 /* Just a paranoid call to the cleanup. */ 27751 if (ctxt->nbAttrInfos != 0) 27752 xmlSchemaClearAttrInfos(ctxt); 27753 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27754 attr = ctxt->attrInfos[i]; 27755 xmlFree(attr); 27756 } 27757 xmlFree(ctxt->attrInfos); 27758 } 27759 if (ctxt->elemInfos != NULL) { 27760 int i; 27761 xmlSchemaNodeInfoPtr ei; 27762 27763 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27764 ei = ctxt->elemInfos[i]; 27765 if (ei == NULL) 27766 break; 27767 xmlSchemaClearElemInfo(ctxt, ei); 27768 xmlFree(ei); 27769 } 27770 xmlFree(ctxt->elemInfos); 27771 } 27772 if (ctxt->nodeQNames != NULL) 27773 xmlSchemaItemListFree(ctxt->nodeQNames); 27774 if (ctxt->dict != NULL) 27775 xmlDictFree(ctxt->dict); 27776 if (ctxt->filename != NULL) 27777 xmlFree(ctxt->filename); 27778 xmlFree(ctxt); 27779 } 27780 27781 /** 27782 * xmlSchemaIsValid: 27783 * @ctxt: the schema validation context 27784 * 27785 * Check if any error was detected during validation. 27786 * 27787 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case 27788 * of internal error. 27789 */ 27790 int 27791 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27792 { 27793 if (ctxt == NULL) 27794 return(-1); 27795 return(ctxt->err == 0); 27796 } 27797 27798 /** 27799 * xmlSchemaSetValidErrors: 27800 * @ctxt: a schema validation context 27801 * @err: the error function 27802 * @warn: the warning function 27803 * @ctx: the functions context 27804 * 27805 * Set the error and warning callback informations 27806 */ 27807 void 27808 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27809 xmlSchemaValidityErrorFunc err, 27810 xmlSchemaValidityWarningFunc warn, void *ctx) 27811 { 27812 if (ctxt == NULL) 27813 return; 27814 ctxt->error = err; 27815 ctxt->warning = warn; 27816 ctxt->errCtxt = ctx; 27817 if (ctxt->pctxt != NULL) 27818 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27819 } 27820 27821 /** 27822 * xmlSchemaSetValidStructuredErrors: 27823 * @ctxt: a schema validation context 27824 * @serror: the structured error function 27825 * @ctx: the functions context 27826 * 27827 * Set the structured error callback 27828 */ 27829 void 27830 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27831 xmlStructuredErrorFunc serror, void *ctx) 27832 { 27833 if (ctxt == NULL) 27834 return; 27835 ctxt->serror = serror; 27836 ctxt->error = NULL; 27837 ctxt->warning = NULL; 27838 ctxt->errCtxt = ctx; 27839 if (ctxt->pctxt != NULL) 27840 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27841 } 27842 27843 /** 27844 * xmlSchemaGetValidErrors: 27845 * @ctxt: a XML-Schema validation context 27846 * @err: the error function result 27847 * @warn: the warning function result 27848 * @ctx: the functions context result 27849 * 27850 * Get the error and warning callback informations 27851 * 27852 * Returns -1 in case of error and 0 otherwise 27853 */ 27854 int 27855 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27856 xmlSchemaValidityErrorFunc * err, 27857 xmlSchemaValidityWarningFunc * warn, void **ctx) 27858 { 27859 if (ctxt == NULL) 27860 return (-1); 27861 if (err != NULL) 27862 *err = ctxt->error; 27863 if (warn != NULL) 27864 *warn = ctxt->warning; 27865 if (ctx != NULL) 27866 *ctx = ctxt->errCtxt; 27867 return (0); 27868 } 27869 27870 27871 /** 27872 * xmlSchemaSetValidOptions: 27873 * @ctxt: a schema validation context 27874 * @options: a combination of xmlSchemaValidOption 27875 * 27876 * Sets the options to be used during the validation. 27877 * 27878 * Returns 0 in case of success, -1 in case of an 27879 * API error. 27880 */ 27881 int 27882 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27883 int options) 27884 27885 { 27886 int i; 27887 27888 if (ctxt == NULL) 27889 return (-1); 27890 /* 27891 * WARNING: Change the start value if adding to the 27892 * xmlSchemaValidOption. 27893 * TODO: Is there an other, more easy to maintain, 27894 * way? 27895 */ 27896 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27897 if (options & 1<<i) 27898 return (-1); 27899 } 27900 ctxt->options = options; 27901 return (0); 27902 } 27903 27904 /** 27905 * xmlSchemaValidCtxtGetOptions: 27906 * @ctxt: a schema validation context 27907 * 27908 * Get the validation context options. 27909 * 27910 * Returns the option combination or -1 on error. 27911 */ 27912 int 27913 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27914 27915 { 27916 if (ctxt == NULL) 27917 return (-1); 27918 else 27919 return (ctxt->options); 27920 } 27921 27922 static int 27923 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27924 { 27925 xmlAttrPtr attr; 27926 int ret = 0; 27927 xmlSchemaNodeInfoPtr ielem = NULL; 27928 xmlNodePtr node, valRoot; 27929 const xmlChar *nsName; 27930 27931 /* DOC VAL TODO: Move this to the start function. */ 27932 if (vctxt->validationRoot != NULL) 27933 valRoot = vctxt->validationRoot; 27934 else 27935 valRoot = xmlDocGetRootElement(vctxt->doc); 27936 if (valRoot == NULL) { 27937 /* VAL TODO: Error code? */ 27938 VERROR(1, NULL, "The document has no document element"); 27939 return (1); 27940 } 27941 vctxt->depth = -1; 27942 vctxt->validationRoot = valRoot; 27943 node = valRoot; 27944 while (node != NULL) { 27945 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27946 goto next_sibling; 27947 if (node->type == XML_ELEMENT_NODE) { 27948 27949 /* 27950 * Init the node-info. 27951 */ 27952 vctxt->depth++; 27953 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27954 goto internal_error; 27955 ielem = vctxt->inode; 27956 ielem->node = node; 27957 ielem->nodeLine = node->line; 27958 ielem->localName = node->name; 27959 if (node->ns != NULL) 27960 ielem->nsName = node->ns->href; 27961 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27962 /* 27963 * Register attributes. 27964 * DOC VAL TODO: We do not register namespace declaration 27965 * attributes yet. 27966 */ 27967 vctxt->nbAttrInfos = 0; 27968 if (node->properties != NULL) { 27969 attr = node->properties; 27970 do { 27971 if (attr->ns != NULL) 27972 nsName = attr->ns->href; 27973 else 27974 nsName = NULL; 27975 ret = xmlSchemaValidatorPushAttribute(vctxt, 27976 (xmlNodePtr) attr, 27977 /* 27978 * Note that we give it the line number of the 27979 * parent element. 27980 */ 27981 ielem->nodeLine, 27982 attr->name, nsName, 0, 27983 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27984 if (ret == -1) { 27985 VERROR_INT("xmlSchemaDocWalk", 27986 "calling xmlSchemaValidatorPushAttribute()"); 27987 goto internal_error; 27988 } 27989 attr = attr->next; 27990 } while (attr); 27991 } 27992 /* 27993 * Validate the element. 27994 */ 27995 ret = xmlSchemaValidateElem(vctxt); 27996 if (ret != 0) { 27997 if (ret == -1) { 27998 VERROR_INT("xmlSchemaDocWalk", 27999 "calling xmlSchemaValidateElem()"); 28000 goto internal_error; 28001 } 28002 /* 28003 * Don't stop validation; just skip the content 28004 * of this element. 28005 */ 28006 goto leave_node; 28007 } 28008 if ((vctxt->skipDepth != -1) && 28009 (vctxt->depth >= vctxt->skipDepth)) 28010 goto leave_node; 28011 } else if ((node->type == XML_TEXT_NODE) || 28012 (node->type == XML_CDATA_SECTION_NODE)) { 28013 /* 28014 * Process character content. 28015 */ 28016 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 28017 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 28018 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 28019 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 28020 if (ret < 0) { 28021 VERROR_INT("xmlSchemaVDocWalk", 28022 "calling xmlSchemaVPushText()"); 28023 goto internal_error; 28024 } 28025 /* 28026 * DOC VAL TODO: Should we skip further validation of the 28027 * element content here? 28028 */ 28029 } else if ((node->type == XML_ENTITY_NODE) || 28030 (node->type == XML_ENTITY_REF_NODE)) { 28031 /* 28032 * DOC VAL TODO: What to do with entities? 28033 */ 28034 VERROR_INT("xmlSchemaVDocWalk", 28035 "there is at least one entity reference in the node-tree " 28036 "currently being validated. Processing of entities with " 28037 "this XML Schema processor is not supported (yet). Please " 28038 "substitute entities before validation."); 28039 goto internal_error; 28040 } else { 28041 goto leave_node; 28042 /* 28043 * DOC VAL TODO: XInclude nodes, etc. 28044 */ 28045 } 28046 /* 28047 * Walk the doc. 28048 */ 28049 if (node->children != NULL) { 28050 node = node->children; 28051 continue; 28052 } 28053 leave_node: 28054 if (node->type == XML_ELEMENT_NODE) { 28055 /* 28056 * Leaving the scope of an element. 28057 */ 28058 if (node != vctxt->inode->node) { 28059 VERROR_INT("xmlSchemaVDocWalk", 28060 "element position mismatch"); 28061 goto internal_error; 28062 } 28063 ret = xmlSchemaValidatorPopElem(vctxt); 28064 if (ret != 0) { 28065 if (ret < 0) { 28066 VERROR_INT("xmlSchemaVDocWalk", 28067 "calling xmlSchemaValidatorPopElem()"); 28068 goto internal_error; 28069 } 28070 } 28071 if (node == valRoot) 28072 goto exit; 28073 } 28074 next_sibling: 28075 if (node->next != NULL) 28076 node = node->next; 28077 else { 28078 node = node->parent; 28079 goto leave_node; 28080 } 28081 } 28082 28083 exit: 28084 return (ret); 28085 internal_error: 28086 return (-1); 28087 } 28088 28089 static int 28090 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 28091 /* 28092 * Some initialization. 28093 */ 28094 vctxt->err = 0; 28095 vctxt->nberrors = 0; 28096 vctxt->depth = -1; 28097 vctxt->skipDepth = -1; 28098 vctxt->xsiAssemble = 0; 28099 vctxt->hasKeyrefs = 0; 28100 #ifdef ENABLE_IDC_NODE_TABLES_TEST 28101 vctxt->createIDCNodeTables = 1; 28102 #else 28103 vctxt->createIDCNodeTables = 0; 28104 #endif 28105 /* 28106 * Create a schema + parser if necessary. 28107 */ 28108 if (vctxt->schema == NULL) { 28109 xmlSchemaParserCtxtPtr pctxt; 28110 28111 vctxt->xsiAssemble = 1; 28112 /* 28113 * If not schema was given then we will create a schema 28114 * dynamically using XSI schema locations. 28115 * 28116 * Create the schema parser context. 28117 */ 28118 if ((vctxt->pctxt == NULL) && 28119 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 28120 return (-1); 28121 pctxt = vctxt->pctxt; 28122 pctxt->xsiAssemble = 1; 28123 /* 28124 * Create the schema. 28125 */ 28126 vctxt->schema = xmlSchemaNewSchema(pctxt); 28127 if (vctxt->schema == NULL) 28128 return (-1); 28129 /* 28130 * Create the schema construction context. 28131 */ 28132 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 28133 if (pctxt->constructor == NULL) 28134 return(-1); 28135 pctxt->constructor->mainSchema = vctxt->schema; 28136 /* 28137 * Take ownership of the constructor to be able to free it. 28138 */ 28139 pctxt->ownsConstructor = 1; 28140 } 28141 /* 28142 * Augment the IDC definitions for the main schema and all imported ones 28143 * NOTE: main schema if the first in the imported list 28144 */ 28145 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, 28146 vctxt); 28147 28148 return(0); 28149 } 28150 28151 static void 28152 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28153 if (vctxt->xsiAssemble) { 28154 if (vctxt->schema != NULL) { 28155 xmlSchemaFree(vctxt->schema); 28156 vctxt->schema = NULL; 28157 } 28158 } 28159 xmlSchemaClearValidCtxt(vctxt); 28160 } 28161 28162 static int 28163 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28164 { 28165 int ret = 0; 28166 28167 if (xmlSchemaPreRun(vctxt) < 0) 28168 return(-1); 28169 28170 if (vctxt->doc != NULL) { 28171 /* 28172 * Tree validation. 28173 */ 28174 ret = xmlSchemaVDocWalk(vctxt); 28175 #ifdef LIBXML_READER_ENABLED 28176 } else if (vctxt->reader != NULL) { 28177 /* 28178 * XML Reader validation. 28179 */ 28180 #ifdef XML_SCHEMA_READER_ENABLED 28181 ret = xmlSchemaVReaderWalk(vctxt); 28182 #endif 28183 #endif 28184 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28185 /* 28186 * SAX validation. 28187 */ 28188 ret = xmlParseDocument(vctxt->parserCtxt); 28189 } else { 28190 VERROR_INT("xmlSchemaVStart", 28191 "no instance to validate"); 28192 ret = -1; 28193 } 28194 28195 xmlSchemaPostRun(vctxt); 28196 if (ret == 0) 28197 ret = vctxt->err; 28198 return (ret); 28199 } 28200 28201 /** 28202 * xmlSchemaValidateOneElement: 28203 * @ctxt: a schema validation context 28204 * @elem: an element node 28205 * 28206 * Validate a branch of a tree, starting with the given @elem. 28207 * 28208 * Returns 0 if the element and its subtree is valid, a positive error 28209 * code number otherwise and -1 in case of an internal or API error. 28210 */ 28211 int 28212 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28213 { 28214 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28215 return (-1); 28216 28217 if (ctxt->schema == NULL) 28218 return (-1); 28219 28220 ctxt->doc = elem->doc; 28221 ctxt->node = elem; 28222 ctxt->validationRoot = elem; 28223 return(xmlSchemaVStart(ctxt)); 28224 } 28225 28226 /** 28227 * xmlSchemaValidateDoc: 28228 * @ctxt: a schema validation context 28229 * @doc: a parsed document tree 28230 * 28231 * Validate a document tree in memory. 28232 * 28233 * Returns 0 if the document is schemas valid, a positive error code 28234 * number otherwise and -1 in case of internal or API error. 28235 */ 28236 int 28237 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28238 { 28239 if ((ctxt == NULL) || (doc == NULL)) 28240 return (-1); 28241 28242 ctxt->doc = doc; 28243 ctxt->node = xmlDocGetRootElement(doc); 28244 if (ctxt->node == NULL) { 28245 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28246 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28247 (xmlNodePtr) doc, NULL, 28248 "The document has no document element", NULL, NULL); 28249 return (ctxt->err); 28250 } 28251 ctxt->validationRoot = ctxt->node; 28252 return (xmlSchemaVStart(ctxt)); 28253 } 28254 28255 28256 /************************************************************************ 28257 * * 28258 * Function and data for SAX streaming API * 28259 * * 28260 ************************************************************************/ 28261 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28262 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28263 28264 struct _xmlSchemaSplitSAXData { 28265 xmlSAXHandlerPtr user_sax; 28266 void *user_data; 28267 xmlSchemaValidCtxtPtr ctxt; 28268 xmlSAXHandlerPtr schemas_sax; 28269 }; 28270 28271 #define XML_SAX_PLUG_MAGIC 0xdc43ba21 28272 28273 struct _xmlSchemaSAXPlug { 28274 unsigned int magic; 28275 28276 /* the original callbacks informations */ 28277 xmlSAXHandlerPtr *user_sax_ptr; 28278 xmlSAXHandlerPtr user_sax; 28279 void **user_data_ptr; 28280 void *user_data; 28281 28282 /* the block plugged back and validation informations */ 28283 xmlSAXHandler schemas_sax; 28284 xmlSchemaValidCtxtPtr ctxt; 28285 }; 28286 28287 /* All those functions just bounces to the user provided SAX handlers */ 28288 static void 28289 internalSubsetSplit(void *ctx, const xmlChar *name, 28290 const xmlChar *ExternalID, const xmlChar *SystemID) 28291 { 28292 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28293 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28294 (ctxt->user_sax->internalSubset != NULL)) 28295 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28296 SystemID); 28297 } 28298 28299 static int 28300 isStandaloneSplit(void *ctx) 28301 { 28302 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28303 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28304 (ctxt->user_sax->isStandalone != NULL)) 28305 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28306 return(0); 28307 } 28308 28309 static int 28310 hasInternalSubsetSplit(void *ctx) 28311 { 28312 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28313 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28314 (ctxt->user_sax->hasInternalSubset != NULL)) 28315 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28316 return(0); 28317 } 28318 28319 static int 28320 hasExternalSubsetSplit(void *ctx) 28321 { 28322 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28323 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28324 (ctxt->user_sax->hasExternalSubset != NULL)) 28325 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28326 return(0); 28327 } 28328 28329 static void 28330 externalSubsetSplit(void *ctx, const xmlChar *name, 28331 const xmlChar *ExternalID, const xmlChar *SystemID) 28332 { 28333 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28334 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28335 (ctxt->user_sax->externalSubset != NULL)) 28336 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28337 SystemID); 28338 } 28339 28340 static xmlParserInputPtr 28341 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28342 { 28343 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28344 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28345 (ctxt->user_sax->resolveEntity != NULL)) 28346 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28347 systemId)); 28348 return(NULL); 28349 } 28350 28351 static xmlEntityPtr 28352 getEntitySplit(void *ctx, const xmlChar *name) 28353 { 28354 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28355 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28356 (ctxt->user_sax->getEntity != NULL)) 28357 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28358 return(NULL); 28359 } 28360 28361 static xmlEntityPtr 28362 getParameterEntitySplit(void *ctx, const xmlChar *name) 28363 { 28364 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28365 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28366 (ctxt->user_sax->getParameterEntity != NULL)) 28367 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28368 return(NULL); 28369 } 28370 28371 28372 static void 28373 entityDeclSplit(void *ctx, const xmlChar *name, int type, 28374 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28375 { 28376 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28377 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28378 (ctxt->user_sax->entityDecl != NULL)) 28379 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28380 systemId, content); 28381 } 28382 28383 static void 28384 attributeDeclSplit(void *ctx, const xmlChar * elem, 28385 const xmlChar * name, int type, int def, 28386 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28387 { 28388 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28389 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28390 (ctxt->user_sax->attributeDecl != NULL)) { 28391 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28392 def, defaultValue, tree); 28393 } else { 28394 xmlFreeEnumeration(tree); 28395 } 28396 } 28397 28398 static void 28399 elementDeclSplit(void *ctx, const xmlChar *name, int type, 28400 xmlElementContentPtr content) 28401 { 28402 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28403 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28404 (ctxt->user_sax->elementDecl != NULL)) 28405 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28406 } 28407 28408 static void 28409 notationDeclSplit(void *ctx, const xmlChar *name, 28410 const xmlChar *publicId, const xmlChar *systemId) 28411 { 28412 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28413 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28414 (ctxt->user_sax->notationDecl != NULL)) 28415 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28416 systemId); 28417 } 28418 28419 static void 28420 unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28421 const xmlChar *publicId, const xmlChar *systemId, 28422 const xmlChar *notationName) 28423 { 28424 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28425 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28426 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28427 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28428 systemId, notationName); 28429 } 28430 28431 static void 28432 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28433 { 28434 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28435 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28436 (ctxt->user_sax->setDocumentLocator != NULL)) 28437 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28438 } 28439 28440 static void 28441 startDocumentSplit(void *ctx) 28442 { 28443 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28444 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28445 (ctxt->user_sax->startDocument != NULL)) 28446 ctxt->user_sax->startDocument(ctxt->user_data); 28447 } 28448 28449 static void 28450 endDocumentSplit(void *ctx) 28451 { 28452 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28453 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28454 (ctxt->user_sax->endDocument != NULL)) 28455 ctxt->user_sax->endDocument(ctxt->user_data); 28456 } 28457 28458 static void 28459 processingInstructionSplit(void *ctx, const xmlChar *target, 28460 const xmlChar *data) 28461 { 28462 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28463 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28464 (ctxt->user_sax->processingInstruction != NULL)) 28465 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28466 } 28467 28468 static void 28469 commentSplit(void *ctx, const xmlChar *value) 28470 { 28471 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28472 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28473 (ctxt->user_sax->comment != NULL)) 28474 ctxt->user_sax->comment(ctxt->user_data, value); 28475 } 28476 28477 /* 28478 * Varargs error callbacks to the user application, harder ... 28479 */ 28480 28481 static void XMLCDECL 28482 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28483 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28484 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28485 (ctxt->user_sax->warning != NULL)) { 28486 TODO 28487 } 28488 } 28489 static void XMLCDECL 28490 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28491 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28492 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28493 (ctxt->user_sax->error != NULL)) { 28494 TODO 28495 } 28496 } 28497 static void XMLCDECL 28498 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28499 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28500 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28501 (ctxt->user_sax->fatalError != NULL)) { 28502 TODO 28503 } 28504 } 28505 28506 /* 28507 * Those are function where both the user handler and the schemas handler 28508 * need to be called. 28509 */ 28510 static void 28511 charactersSplit(void *ctx, const xmlChar *ch, int len) 28512 { 28513 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28514 if (ctxt == NULL) 28515 return; 28516 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28517 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28518 if (ctxt->ctxt != NULL) 28519 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28520 } 28521 28522 static void 28523 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28524 { 28525 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28526 if (ctxt == NULL) 28527 return; 28528 if ((ctxt->user_sax != NULL) && 28529 (ctxt->user_sax->ignorableWhitespace != NULL)) 28530 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28531 if (ctxt->ctxt != NULL) 28532 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28533 } 28534 28535 static void 28536 cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28537 { 28538 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28539 if (ctxt == NULL) 28540 return; 28541 if ((ctxt->user_sax != NULL) && 28542 (ctxt->user_sax->cdataBlock != NULL)) 28543 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28544 if (ctxt->ctxt != NULL) 28545 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28546 } 28547 28548 static void 28549 referenceSplit(void *ctx, const xmlChar *name) 28550 { 28551 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28552 if (ctxt == NULL) 28553 return; 28554 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28555 (ctxt->user_sax->reference != NULL)) 28556 ctxt->user_sax->reference(ctxt->user_data, name); 28557 if (ctxt->ctxt != NULL) 28558 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28559 } 28560 28561 static void 28562 startElementNsSplit(void *ctx, const xmlChar * localname, 28563 const xmlChar * prefix, const xmlChar * URI, 28564 int nb_namespaces, const xmlChar ** namespaces, 28565 int nb_attributes, int nb_defaulted, 28566 const xmlChar ** attributes) { 28567 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28568 if (ctxt == NULL) 28569 return; 28570 if ((ctxt->user_sax != NULL) && 28571 (ctxt->user_sax->startElementNs != NULL)) 28572 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28573 URI, nb_namespaces, namespaces, 28574 nb_attributes, nb_defaulted, 28575 attributes); 28576 if (ctxt->ctxt != NULL) 28577 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28578 URI, nb_namespaces, namespaces, 28579 nb_attributes, nb_defaulted, 28580 attributes); 28581 } 28582 28583 static void 28584 endElementNsSplit(void *ctx, const xmlChar * localname, 28585 const xmlChar * prefix, const xmlChar * URI) { 28586 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28587 if (ctxt == NULL) 28588 return; 28589 if ((ctxt->user_sax != NULL) && 28590 (ctxt->user_sax->endElementNs != NULL)) 28591 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28592 if (ctxt->ctxt != NULL) 28593 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28594 } 28595 28596 /** 28597 * xmlSchemaSAXPlug: 28598 * @ctxt: a schema validation context 28599 * @sax: a pointer to the original xmlSAXHandlerPtr 28600 * @user_data: a pointer to the original SAX user data pointer 28601 * 28602 * Plug a SAX based validation layer in a SAX parsing event flow. 28603 * The original @saxptr and @dataptr data are replaced by new pointers 28604 * but the calls to the original will be maintained. 28605 * 28606 * Returns a pointer to a data structure needed to unplug the validation layer 28607 * or NULL in case of errors. 28608 */ 28609 xmlSchemaSAXPlugPtr 28610 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28611 xmlSAXHandlerPtr *sax, void **user_data) 28612 { 28613 xmlSchemaSAXPlugPtr ret; 28614 xmlSAXHandlerPtr old_sax; 28615 28616 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28617 return(NULL); 28618 28619 /* 28620 * We only allow to plug into SAX2 event streams 28621 */ 28622 old_sax = *sax; 28623 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28624 return(NULL); 28625 if ((old_sax != NULL) && 28626 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28627 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28628 return(NULL); 28629 28630 /* 28631 * everything seems right allocate the local data needed for that layer 28632 */ 28633 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28634 if (ret == NULL) { 28635 return(NULL); 28636 } 28637 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28638 ret->magic = XML_SAX_PLUG_MAGIC; 28639 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28640 ret->ctxt = ctxt; 28641 ret->user_sax_ptr = sax; 28642 ret->user_sax = old_sax; 28643 if (old_sax == NULL) { 28644 /* 28645 * go direct, no need for the split block and functions. 28646 */ 28647 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28648 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28649 /* 28650 * Note that we use the same text-function for both, to prevent 28651 * the parser from testing for ignorable whitespace. 28652 */ 28653 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28654 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28655 28656 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28657 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28658 28659 ret->user_data = ctxt; 28660 *user_data = ctxt; 28661 } else { 28662 /* 28663 * for each callback unused by Schemas initialize it to the Split 28664 * routine only if non NULL in the user block, this can speed up 28665 * things at the SAX level. 28666 */ 28667 if (old_sax->internalSubset != NULL) 28668 ret->schemas_sax.internalSubset = internalSubsetSplit; 28669 if (old_sax->isStandalone != NULL) 28670 ret->schemas_sax.isStandalone = isStandaloneSplit; 28671 if (old_sax->hasInternalSubset != NULL) 28672 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28673 if (old_sax->hasExternalSubset != NULL) 28674 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28675 if (old_sax->resolveEntity != NULL) 28676 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28677 if (old_sax->getEntity != NULL) 28678 ret->schemas_sax.getEntity = getEntitySplit; 28679 if (old_sax->entityDecl != NULL) 28680 ret->schemas_sax.entityDecl = entityDeclSplit; 28681 if (old_sax->notationDecl != NULL) 28682 ret->schemas_sax.notationDecl = notationDeclSplit; 28683 if (old_sax->attributeDecl != NULL) 28684 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28685 if (old_sax->elementDecl != NULL) 28686 ret->schemas_sax.elementDecl = elementDeclSplit; 28687 if (old_sax->unparsedEntityDecl != NULL) 28688 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28689 if (old_sax->setDocumentLocator != NULL) 28690 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28691 if (old_sax->startDocument != NULL) 28692 ret->schemas_sax.startDocument = startDocumentSplit; 28693 if (old_sax->endDocument != NULL) 28694 ret->schemas_sax.endDocument = endDocumentSplit; 28695 if (old_sax->processingInstruction != NULL) 28696 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28697 if (old_sax->comment != NULL) 28698 ret->schemas_sax.comment = commentSplit; 28699 if (old_sax->warning != NULL) 28700 ret->schemas_sax.warning = warningSplit; 28701 if (old_sax->error != NULL) 28702 ret->schemas_sax.error = errorSplit; 28703 if (old_sax->fatalError != NULL) 28704 ret->schemas_sax.fatalError = fatalErrorSplit; 28705 if (old_sax->getParameterEntity != NULL) 28706 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28707 if (old_sax->externalSubset != NULL) 28708 ret->schemas_sax.externalSubset = externalSubsetSplit; 28709 28710 /* 28711 * the 6 schemas callback have to go to the splitter functions 28712 * Note that we use the same text-function for ignorableWhitespace 28713 * if possible, to prevent the parser from testing for ignorable 28714 * whitespace. 28715 */ 28716 ret->schemas_sax.characters = charactersSplit; 28717 if ((old_sax->ignorableWhitespace != NULL) && 28718 (old_sax->ignorableWhitespace != old_sax->characters)) 28719 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28720 else 28721 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28722 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28723 ret->schemas_sax.reference = referenceSplit; 28724 ret->schemas_sax.startElementNs = startElementNsSplit; 28725 ret->schemas_sax.endElementNs = endElementNsSplit; 28726 28727 ret->user_data_ptr = user_data; 28728 ret->user_data = *user_data; 28729 *user_data = ret; 28730 } 28731 28732 /* 28733 * plug the pointers back. 28734 */ 28735 *sax = &(ret->schemas_sax); 28736 ctxt->sax = *sax; 28737 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28738 xmlSchemaPreRun(ctxt); 28739 return(ret); 28740 } 28741 28742 /** 28743 * xmlSchemaSAXUnplug: 28744 * @plug: a data structure returned by xmlSchemaSAXPlug 28745 * 28746 * Unplug a SAX based validation layer in a SAX parsing event flow. 28747 * The original pointers used in the call are restored. 28748 * 28749 * Returns 0 in case of success and -1 in case of failure. 28750 */ 28751 int 28752 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28753 { 28754 xmlSAXHandlerPtr *sax; 28755 void **user_data; 28756 28757 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28758 return(-1); 28759 plug->magic = 0; 28760 28761 xmlSchemaPostRun(plug->ctxt); 28762 /* restore the data */ 28763 sax = plug->user_sax_ptr; 28764 *sax = plug->user_sax; 28765 if (plug->user_sax != NULL) { 28766 user_data = plug->user_data_ptr; 28767 *user_data = plug->user_data; 28768 } 28769 28770 /* free and return */ 28771 xmlFree(plug); 28772 return(0); 28773 } 28774 28775 /** 28776 * xmlSchemaValidateSetLocator: 28777 * @vctxt: a schema validation context 28778 * @f: the locator function pointer 28779 * @ctxt: the locator context 28780 * 28781 * Allows to set a locator function to the validation context, 28782 * which will be used to provide file and line information since 28783 * those are not provided as part of the SAX validation flow 28784 * Setting @f to NULL disable the locator. 28785 */ 28786 28787 void 28788 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt, 28789 xmlSchemaValidityLocatorFunc f, 28790 void *ctxt) 28791 { 28792 if (vctxt == NULL) return; 28793 vctxt->locFunc = f; 28794 vctxt->locCtxt = ctxt; 28795 } 28796 28797 /** 28798 * xmlSchemaValidateStreamLocator: 28799 * @ctx: the xmlTextReaderPtr used 28800 * @file: returned file information 28801 * @line: returned line information 28802 * 28803 * Internal locator function for the readers 28804 * 28805 * Returns 0 in case the Schema validation could be (de)activated and 28806 * -1 in case of error. 28807 */ 28808 static int 28809 xmlSchemaValidateStreamLocator(void *ctx, const char **file, 28810 unsigned long *line) { 28811 xmlParserCtxtPtr ctxt; 28812 28813 if ((ctx == NULL) || ((file == NULL) && (line == NULL))) 28814 return(-1); 28815 28816 if (file != NULL) 28817 *file = NULL; 28818 if (line != NULL) 28819 *line = 0; 28820 28821 ctxt = (xmlParserCtxtPtr) ctx; 28822 if (ctxt->input != NULL) { 28823 if (file != NULL) 28824 *file = ctxt->input->filename; 28825 if (line != NULL) 28826 *line = ctxt->input->line; 28827 return(0); 28828 } 28829 return(-1); 28830 } 28831 28832 /** 28833 * xmlSchemaValidateStream: 28834 * @ctxt: a schema validation context 28835 * @input: the input to use for reading the data 28836 * @enc: an optional encoding information 28837 * @sax: a SAX handler for the resulting events 28838 * @user_data: the context to provide to the SAX handler. 28839 * 28840 * Validate an input based on a flow of SAX event from the parser 28841 * and forward the events to the @sax handler with the provided @user_data 28842 * the user provided @sax handler must be a SAX2 one. 28843 * 28844 * Returns 0 if the document is schemas valid, a positive error code 28845 * number otherwise and -1 in case of internal or API error. 28846 */ 28847 int 28848 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28849 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28850 xmlSAXHandlerPtr sax, void *user_data) 28851 { 28852 xmlSchemaSAXPlugPtr plug = NULL; 28853 xmlSAXHandlerPtr old_sax = NULL; 28854 xmlParserCtxtPtr pctxt = NULL; 28855 xmlParserInputPtr inputStream = NULL; 28856 int ret; 28857 28858 if ((ctxt == NULL) || (input == NULL)) 28859 return (-1); 28860 28861 /* 28862 * prepare the parser 28863 */ 28864 pctxt = xmlNewParserCtxt(); 28865 if (pctxt == NULL) 28866 return (-1); 28867 old_sax = pctxt->sax; 28868 pctxt->sax = sax; 28869 pctxt->userData = user_data; 28870 #if 0 28871 if (options) 28872 xmlCtxtUseOptions(pctxt, options); 28873 #endif 28874 pctxt->linenumbers = 1; 28875 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt); 28876 28877 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28878 if (inputStream == NULL) { 28879 ret = -1; 28880 goto done; 28881 } 28882 inputPush(pctxt, inputStream); 28883 ctxt->parserCtxt = pctxt; 28884 ctxt->input = input; 28885 28886 /* 28887 * Plug the validation and launch the parsing 28888 */ 28889 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28890 if (plug == NULL) { 28891 ret = -1; 28892 goto done; 28893 } 28894 ctxt->input = input; 28895 ctxt->enc = enc; 28896 ctxt->sax = pctxt->sax; 28897 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28898 ret = xmlSchemaVStart(ctxt); 28899 28900 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28901 ret = ctxt->parserCtxt->errNo; 28902 if (ret == 0) 28903 ret = 1; 28904 } 28905 28906 done: 28907 ctxt->parserCtxt = NULL; 28908 ctxt->sax = NULL; 28909 ctxt->input = NULL; 28910 if (plug != NULL) { 28911 xmlSchemaSAXUnplug(plug); 28912 } 28913 /* cleanup */ 28914 if (pctxt != NULL) { 28915 pctxt->sax = old_sax; 28916 xmlFreeParserCtxt(pctxt); 28917 } 28918 return (ret); 28919 } 28920 28921 /** 28922 * xmlSchemaValidateFile: 28923 * @ctxt: a schema validation context 28924 * @filename: the URI of the instance 28925 * @options: a future set of options, currently unused 28926 * 28927 * Do a schemas validation of the given resource, it will use the 28928 * SAX streamable validation internally. 28929 * 28930 * Returns 0 if the document is valid, a positive error code 28931 * number otherwise and -1 in case of an internal or API error. 28932 */ 28933 int 28934 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28935 const char * filename, 28936 int options ATTRIBUTE_UNUSED) 28937 { 28938 int ret; 28939 xmlParserInputBufferPtr input; 28940 28941 if ((ctxt == NULL) || (filename == NULL)) 28942 return (-1); 28943 28944 input = xmlParserInputBufferCreateFilename(filename, 28945 XML_CHAR_ENCODING_NONE); 28946 if (input == NULL) 28947 return (-1); 28948 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28949 NULL, NULL); 28950 return (ret); 28951 } 28952 28953 /** 28954 * xmlSchemaValidCtxtGetParserCtxt: 28955 * @ctxt: a schema validation context 28956 * 28957 * allow access to the parser context of the schema validation context 28958 * 28959 * Returns the parser context of the schema validation context or NULL 28960 * in case of error. 28961 */ 28962 xmlParserCtxtPtr 28963 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28964 { 28965 if (ctxt == NULL) 28966 return(NULL); 28967 return (ctxt->parserCtxt); 28968 } 28969 28970 #define bottom_xmlschemas 28971 #include "elfgcchack.h" 28972 #endif /* LIBXML_SCHEMAS_ENABLED */ 28973